[llvm] 4675bea - [InstCombine] intersect nsz and ninf fast-math-flags (FMF) for fneg(fdiv) fold

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 7 10:23:00 PDT 2021


Author: Sanjay Patel
Date: 2021-06-07T13:22:49-04:00
New Revision: 4675beaa2181b6ccb1a37fd49b51a45490023974

URL: https://github.com/llvm/llvm-project/commit/4675beaa2181b6ccb1a37fd49b51a45490023974
DIFF: https://github.com/llvm/llvm-project/commit/4675beaa2181b6ccb1a37fd49b51a45490023974.diff

LOG: [InstCombine] intersect nsz and ninf fast-math-flags (FMF) for fneg(fdiv) fold

https://alive2.llvm.org/ce/z/3KPvih

https://llvm.org/PR49654

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 2e0d3bf0a24b..2ed616f4ed7f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -2143,9 +2143,19 @@ static Instruction *foldFNegIntoConstant(Instruction &I) {
   if (match(FNegOp, m_FDiv(m_Value(X), m_Constant(C))))
     return BinaryOperator::CreateFDivFMF(X, ConstantExpr::getFNeg(C), &I);
   // -(C / X) --> (-C) / X
-  if (match(FNegOp, m_FDiv(m_Constant(C), m_Value(X))))
-    return BinaryOperator::CreateFDivFMF(ConstantExpr::getFNeg(C), X, &I);
-
+  if (match(FNegOp, m_FDiv(m_Constant(C), m_Value(X)))) {
+    Instruction *FDiv =
+        BinaryOperator::CreateFDivFMF(ConstantExpr::getFNeg(C), X, &I);
+
+    // Intersect 'nsz' and 'ninf' because those special value exceptions may not
+    // apply to the fdiv. Everything else propagates from the fneg.
+    // TODO: We could propagate nsz/ninf from fdiv alone?
+    FastMathFlags FMF = I.getFastMathFlags();
+    FastMathFlags OpFMF = FNegOp->getFastMathFlags();
+    FDiv->setHasNoSignedZeros(FMF.noSignedZeros() & OpFMF.noSignedZeros());
+    FDiv->setHasNoInfs(FMF.noInfs() & OpFMF.noInfs());
+    return FDiv;
+  }
   // With NSZ [ counter-example with -0.0: -(-0.0 + 0.0) != 0.0 + -0.0 ]:
   // -(X + C) --> -X + -C --> -C - X
   if (I.hasNoSignedZeros() && match(FNegOp, m_FAdd(m_Value(X), m_Constant(C))))

diff  --git a/llvm/test/Transforms/InstCombine/fneg.ll b/llvm/test/Transforms/InstCombine/fneg.ll
index 62d2f105e69c..50371f60932c 100644
--- a/llvm/test/Transforms/InstCombine/fneg.ll
+++ b/llvm/test/Transforms/InstCombine/fneg.ll
@@ -237,7 +237,7 @@ define float @fdiv_op0_constant_fneg_fast_fast(float %x) {
 
 define float @fdiv_op0_constant_fneg_fast(float %x) {
 ; CHECK-LABEL: @fdiv_op0_constant_fneg_fast(
-; CHECK-NEXT:    [[R:%.*]] = fdiv fast float -4.200000e+01, [[X:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = fdiv reassoc nnan arcp contract afn float -4.200000e+01, [[X:%.*]]
 ; CHECK-NEXT:    ret float [[R]]
 ;
   %d = fdiv float 42.0, %x
@@ -257,7 +257,7 @@ define float @fdiv_op0_constant_fneg_nsz_nsz(float %x) {
 
 define float @fdiv_op0_constant_fneg_nsz(float %x) {
 ; CHECK-LABEL: @fdiv_op0_constant_fneg_nsz(
-; CHECK-NEXT:    [[R:%.*]] = fdiv nsz float -4.200000e+01, [[X:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = fdiv float -4.200000e+01, [[X:%.*]]
 ; CHECK-NEXT:    ret float [[R]]
 ;
   %d = fdiv float 42.0, %x
@@ -277,7 +277,7 @@ define float @fdiv_op0_constant_fneg_ninf_ninf(float %x) {
 
 define float @fdiv_op0_constant_fneg_ninf(float %x) {
 ; CHECK-LABEL: @fdiv_op0_constant_fneg_ninf(
-; CHECK-NEXT:    [[R:%.*]] = fdiv ninf float -4.200000e+01, [[X:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = fdiv float -4.200000e+01, [[X:%.*]]
 ; CHECK-NEXT:    ret float [[R]]
 ;
   %d = fdiv float 42.0, %x


        


More information about the llvm-commits mailing list