This is an archive of the discontinued LLVM Phabricator instance.

Reassoc FMF should not optimize FMA(a, 0, b) to (b)
ClosedPublic

Authored by svenvh on Jul 21 2022, 2:19 AM.

Details

Summary

Optimizing (a * 0 + b) to (b) requires assuming that a is finite and not
NaN. DAGCombiner will do this optimization when the reassoc fast math
flag is set, which is not correct. Change DAGCombiner to only consider
UnsafeMath for this optimization.

Co-authored-by: Andrea Faulds <andrea.faulds@arm.com>

Diff Detail

Event Timeline

svenvh created this revision.Jul 21 2022, 2:19 AM
svenvh requested review of this revision.Jul 21 2022, 2:19 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 21 2022, 2:19 AM
spatel added inline comments.Jul 24 2022, 2:04 PM
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
15029–15030

We are slowly trying to get away from using the global settings by replacing those checks with fast-math-flags. Can we do that here?

This should match the conditions that we use to simplify X * 0.0. That's done via DAG.simplifyFPBinop():

// X * 0.0 --> 0.0
if (Opcode == ISD::FMUL && Flags.hasNoNaNs() && Flags.hasNoSignedZeros())
  if (YC->getValueAPF().isZero())
    return getConstantFP(0.0, SDLoc(Y), Y.getValueType());
svenvh added inline comments.Jul 25 2022, 3:45 AM
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
15029–15030

Sure, but is it okay to do the modernization in a separate followup commit? This change just intends to fix the immediate bug (i.e. restore the status quo to before 8e570c3390d20, which is where this bug was introduced).

I guess the followup patch will be like this then?

@@ -15026,7 +15026,7 @@ SDValue DAGCombiner::visitFMA(SDNode *N) {
        CostN1 == TargetLowering::NegatibleCost::Cheaper))
     return DAG.getNode(ISD::FMA, DL, VT, NegN0, NegN1, N2);
 
-  if (Options.UnsafeFPMath) {
+  if (N->getFlags().hasNoNaNs() && N->getFlags().hasNoSignedZeros()) {
     if (N0CFP && N0CFP->isZero())
       return N2;
     if (N1CFP && N1CFP->isZero())
spatel added inline comments.Jul 25 2022, 6:32 AM
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
15029–15030

Right - it should be a one-line patch. Just need to see if any regression tests fail with that. If you want to do that as another patch, please put a FIXME note on it in this patch, so we don't lose track that it needs to be fixed.

llvm/test/CodeGen/AArch64/neon-fma-FMF.ll
64

Prefer to add positive CHECK lines for correctness rather than NOT lines for the absence of one particular kind of wrong.
It would be great to update this whole file using the script at "utils/update_llc_test_checks.py" - that way, it's complete and easier to update.

svenvh updated this revision to Diff 447339.Jul 25 2022, 7:48 AM
svenvh marked an inline comment as done.

Added FIXME and updated CHECK lines to avoid CHECK-NOT.

llvm/test/CodeGen/AArch64/neon-fma-FMF.ll
64

It would be great to update this whole file using the script at "utils/update_llc_test_checks.py"

I've tried that, but it seems to remove some CHECK patterns presumably because the IR is not exactly the same for the two llc RUN invocations (yet we still want the test to verify that fma fusing happened).

Either way, I've updated the CHECK lines for this function with what update_llc_test_checks.py generates.

spatel accepted this revision.Jul 25 2022, 8:22 AM

LGTM

llvm/test/CodeGen/AArch64/neon-fma-FMF.ll
64

OK - thanks for trying.

Probably need to add unique prefixes for each RUN line (presumably there is some potential difference between the runs that someone was trying to test for). There are many test file examples of that in this directory if you want to do that as a follow-up.

I assume we'll add another test like the one you're adding in this patch -- except with nsz + nnan FMF to match the code when it is updated again.

This revision is now accepted and ready to land.Jul 25 2022, 8:22 AM
This revision was landed with ongoing or failed builds.Jul 26 2022, 1:39 AM
This revision was automatically updated to reflect the committed changes.