This is an archive of the discontinued LLVM Phabricator instance.

[IR] allow fast-math-flags on select of FP values
ClosedPublic

Authored by spatel on May 14 2019, 1:51 PM.

Details

Summary

This is a minimal start to correcting a problem most directly discussed in PR38086:
https://bugs.llvm.org/show_bug.cgi?id=38086

We have been hacking around a limitation for FP select patterns by using the fast-math-flags on the condition of the select rather than the select itself.
This patch just allows FMF to appear with the 'select' opcode. No changes are needed to "FPMathOperator" because it already includes select-of-FP because that definition is based on the return value type.

Once we have this ability, we can start correcting and adding IR transforms to use the FMF on a 'select' instruction. The instcombine and vectorizer test diffs only show that the IRBuilder change is behaving as expected by applying an FMF guard value to 'select'.

For reference:
rL241901 - allowed FMF with fcmp
rL255555 - allowed FMF with FP calls

Diff Detail

Repository
rL LLVM

Event Timeline

spatel created this revision.May 14 2019, 1:51 PM
nlw0 added a subscriber: nlw0.May 14 2019, 3:05 PM

Just to make sure that I understand the general direction here: We want to make all fast-math flags apply only to inputs, not outputs, and so we're going to end up adding fast-math flags on all instructions that might take floating-point inputs?

Just to make sure that I understand the general direction here: We want to make all fast-math flags apply only to inputs, not outputs, and so we're going to end up adding fast-math flags on all instructions that might take floating-point inputs?

I think we want to have FMF apply to the value itself. That should allow removing FMF from fcmp by adjusting our analysis/pattern matching to detect the FMF on fcmp's operands. That would simplify the definition of FPMathOperator too - if it's an FP value (produces an FP value), it's an FPMO. To make that complete, I think we'd eventually allow adding FMF as an attribute to FP function arguments.

Some motivating examples:

define float @PR39535(float %x) {
  %cmp = fcmp nsz oeq float %x, 0.0           ; 'nsz' behavior is implicit in any fcmp, so this is strange
  %cond = select i1 %cmp, float %x, float 0.0 ; if this has 'nsz', we can simplify to '0.0' because both arms of the select are the same
  ret float %cond
}

define i1 @orderedLessZeroUIToFP_nnan(i32 %x) {
  %a = uitofp i32 %x to float                 ; if this has 'nnan', the result is a number and >=0.0 (the fcmp must be true)
  %uge = fcmp nnan oge float %a, 0.000000e+00
  ret i1 %uge
}
hfinkel accepted this revision.May 21 2019, 10:03 AM

To make that complete, I think we'd eventually allow adding FMF as an attribute to FP function arguments.

Okay. So the flag will always be a property of the value, and so we'll add them to loads and function arguments, etc. This makes sense to me, and seems like it creates an unambiguous picture. We need to be a bit careful how we define this -- I think that we want a disallowed value in one of these arguments, etc. to be poison and not UB. We'll need to be more aggressive about propagating the flags when we inline the functions when they have the flags on their return values (because we don't otherwise have a way to get the information when the values are later used as inputs).

LGTM.

This revision is now accepted and ready to land.May 21 2019, 10:03 AM
This revision was automatically updated to reflect the committed changes.
foad added a subscriber: foad.Oct 21 2019, 4:48 AM
foad added inline comments.
llvm/trunk/lib/AsmParser/LLParser.cpp
5704

Why is the FMF handling done inline here, instead of in the body of ParseSelect ?

spatel marked an inline comment as done.Oct 22 2019, 5:56 AM
spatel added inline comments.
llvm/trunk/lib/AsmParser/LLParser.cpp
5704

Copied from the similar block for fcmp just above here. No objection if you want to change it.