[llvm] f72fe2e - [InstCombine] Preserve FMF in foldLogicOfFCmps.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 9 09:17:45 PST 2022


Author: Craig Topper
Date: 2022-03-09T09:17:09-08:00
New Revision: f72fe2ef67aac421d77270d0bd9550950a474787

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

LOG: [InstCombine] Preserve FMF in foldLogicOfFCmps.

This patch intersects the fast math flags from the two fcmps instead
of dropping them.

I poked at this a bunch with Alive2 for nnan and ninf flags and it seemed
to check out. With the other flags it told me "Couldn't prove the
correctness of the transformation". Not sure if I should just preserve
nnan and ninf?

Reviewed By: spatel, lebedev.ri

Differential Revision: https://reviews.llvm.org/D121243

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
    llvm/test/Transforms/InstCombine/and-fcmp.ll
    llvm/test/Transforms/InstCombine/or-fcmp.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 38bd74b8f89da..1cd06a0371b79 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1351,6 +1351,14 @@ Value *InstCombinerImpl::foldLogicOfFCmps(FCmpInst *LHS, FCmpInst *RHS,
     unsigned FCmpCodeL = getFCmpCode(PredL);
     unsigned FCmpCodeR = getFCmpCode(PredR);
     unsigned NewPred = IsAnd ? FCmpCodeL & FCmpCodeR : FCmpCodeL | FCmpCodeR;
+
+    // Intersect the fast math flags.
+    // TODO: We can union the fast math flags.
+    IRBuilder<>::FastMathFlagGuard FMFG(Builder);
+    FastMathFlags FMF = LHS->getFastMathFlags();
+    FMF &= RHS->getFastMathFlags();
+    Builder.setFastMathFlags(FMF);
+
     return getFCmpValue(NewPred, LHS0, LHS1, Builder);
   }
 

diff  --git a/llvm/test/Transforms/InstCombine/and-fcmp.ll b/llvm/test/Transforms/InstCombine/and-fcmp.ll
index 48edc3973b9bd..03dbf339b2453 100644
--- a/llvm/test/Transforms/InstCombine/and-fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/and-fcmp.ll
@@ -3120,3 +3120,47 @@ define i1 @auto_gen_135_logical(double %a, double %b) {
   %retval = select i1 %cmp, i1 %cmp1, i1 false
   ret i1 %retval
 }
+
+define i1 @intersect_fmf_1(double %a, double %b) {
+; CHECK-LABEL: @intersect_fmf_1(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp fast oeq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp fast ole double %a, %b
+  %cmp1 = fcmp fast oge double %a, %b
+  %retval = and i1 %cmp, %cmp1
+  ret i1 %retval
+}
+
+define i1 @intersect_fmf_2(double %a, double %b) {
+; CHECK-LABEL: @intersect_fmf_2(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp fast ole double %a, %b
+  %cmp1 = fcmp oge double %a, %b
+  %retval = and i1 %cmp, %cmp1
+  ret i1 %retval
+}
+
+define i1 @intersect_fmf_3(double %a, double %b) {
+; CHECK-LABEL: @intersect_fmf_3(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ole double %a, %b
+  %cmp1 = fcmp fast oge double %a, %b
+  %retval = and i1 %cmp, %cmp1
+  ret i1 %retval
+}
+
+define i1 @intersect_fmf_4(double %a, double %b) {
+; CHECK-LABEL: @intersect_fmf_4(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ninf ole double %a, %b
+  %cmp1 = fcmp nnan oge double %a, %b
+  %retval = and i1 %cmp, %cmp1
+  ret i1 %retval
+}

diff  --git a/llvm/test/Transforms/InstCombine/or-fcmp.ll b/llvm/test/Transforms/InstCombine/or-fcmp.ll
index eeed99d5474b5..0ff3d3ddd10a3 100644
--- a/llvm/test/Transforms/InstCombine/or-fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/or-fcmp.ll
@@ -3072,3 +3072,47 @@ define i1 @auto_gen_135_logical(double %a, double %b) {
   %retval = select i1 %cmp, i1 true, i1 %cmp1
   ret i1 %retval
 }
+
+define i1 @intersect_fmf_1(double %a, double %b) {
+; CHECK-LABEL: @intersect_fmf_1(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp fast one double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp fast olt double %a, %b
+  %cmp1 = fcmp fast ogt double %a, %b
+  %retval = or i1 %cmp, %cmp1
+  ret i1 %retval
+}
+
+define i1 @intersect_fmf_2(double %a, double %b) {
+; CHECK-LABEL: @intersect_fmf_2(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp one double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp fast olt double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = or i1 %cmp, %cmp1
+  ret i1 %retval
+}
+
+define i1 @intersect_fmf_3(double %a, double %b) {
+; CHECK-LABEL: @intersect_fmf_3(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp one double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp olt double %a, %b
+  %cmp1 = fcmp fast ogt double %a, %b
+  %retval = or i1 %cmp, %cmp1
+  ret i1 %retval
+}
+
+define i1 @intersect_fmf_4(double %a, double %b) {
+; CHECK-LABEL: @intersect_fmf_4(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp one double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ninf olt double %a, %b
+  %cmp1 = fcmp nnan ogt double %a, %b
+  %retval = or i1 %cmp, %cmp1
+  ret i1 %retval
+}


        


More information about the llvm-commits mailing list