[llvm] 93099c7 - [InstCombine] allow more fast-math-flags to propagate in fneg-of-select fold

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 9 08:11:24 PST 2022


Author: Sanjay Patel
Date: 2022-12-09T11:07:24-05:00
New Revision: 93099c7d21727dd94383783020de4c89a6c5809c

URL: https://github.com/llvm/llvm-project/commit/93099c7d21727dd94383783020de4c89a6c5809c
DIFF: https://github.com/llvm/llvm-project/commit/93099c7d21727dd94383783020de4c89a6c5809c.diff

LOG: [InstCombine] allow more fast-math-flags to propagate in fneg-of-select fold

We were conservatively intersecting flags, but we can take the union here
because forbidden special values (nsz/nnan/ninf) are not altered by fneg.
So if they were guaranteed not present on the select or fneg, then they
are guaranteed not present on the new select. Alive2 appears to agree on
the test diffs (reduced to not include irrelevant flags like reassoc):
https://alive2.llvm.org/ce/z/ViqqrO

This prevents a potential regression if we tighten up the FMF behavior
for fabs with NAN as suggested in issue #59279.

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
    llvm/test/Transforms/InstCombine/fneg.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 6f1b0b9b070bb..9c6624f86f135 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -2408,14 +2408,18 @@ Instruction *InstCombinerImpl::visitFNeg(UnaryOperator &I) {
   Value *Cond;
   if (match(Op, m_OneUse(m_Select(m_Value(Cond), m_Value(X), m_Value(Y))))) {
     // Unlike most transforms, this one is not safe to propagate nsz unless
-    // it is present on the original select. (We are conservatively intersecting
-    // the nsz flags from the select and root fneg instruction.)
+    // it is present on the original select. We union the flags from the select
+    // and fneg and then remove nsz if needed.
     auto propagateSelectFMF = [&](SelectInst *S, bool CommonOperand) {
       S->copyFastMathFlags(&I);
-      if (auto *OldSel = dyn_cast<SelectInst>(Op))
+      if (auto *OldSel = dyn_cast<SelectInst>(Op)) {
+        FastMathFlags FMF = I.getFastMathFlags();
+        FMF |= OldSel->getFastMathFlags();
+        S->setFastMathFlags(FMF);
         if (!OldSel->hasNoSignedZeros() && !CommonOperand &&
             !isGuaranteedNotToBeUndefOrPoison(OldSel->getCondition()))
           S->setHasNoSignedZeros(false);
+      }
     };
     // -(Cond ? -P : Y) --> Cond ? P : -Y
     Value *P;

diff  --git a/llvm/test/Transforms/InstCombine/fneg.ll b/llvm/test/Transforms/InstCombine/fneg.ll
index 41b2146143abd..2c47b33175c21 100644
--- a/llvm/test/Transforms/InstCombine/fneg.ll
+++ b/llvm/test/Transforms/InstCombine/fneg.ll
@@ -629,7 +629,7 @@ define float @select_fneg_true(float %x, float %y, i1 %b) {
 define <2 x float> @select_fneg_false(<2 x float> %x, <2 x float> %y, <2 x i1> %b) {
 ; CHECK-LABEL: @select_fneg_false(
 ; CHECK-NEXT:    [[X_NEG:%.*]] = fneg nnan nsz <2 x float> [[X:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = select nnan <2 x i1> [[B:%.*]], <2 x float> [[X_NEG]], <2 x float> [[Y:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = select nnan ninf <2 x i1> [[B:%.*]], <2 x float> [[X_NEG]], <2 x float> [[Y:%.*]]
 ; CHECK-NEXT:    ret <2 x float> [[R]]
 ;
   %ny = fneg nnan <2 x float> %y
@@ -772,7 +772,7 @@ define float @select_fneg_use1(float %x, float %y, i1 %b) {
 ; CHECK-NEXT:    [[NX:%.*]] = fneg ninf float [[X:%.*]]
 ; CHECK-NEXT:    call void @use(float [[NX]])
 ; CHECK-NEXT:    [[Y_NEG:%.*]] = fneg float [[Y:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = select i1 [[B:%.*]], float [[X]], float [[Y_NEG]]
+; CHECK-NEXT:    [[R:%.*]] = select fast i1 [[B:%.*]], float [[X]], float [[Y_NEG]]
 ; CHECK-NEXT:    ret float [[R]]
 ;
   %nx = fneg ninf float %x


        


More information about the llvm-commits mailing list