summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@sifive.com>2022-03-09 09:07:22 -0800
committerCraig Topper <craig.topper@sifive.com>2022-03-09 09:17:09 -0800
commitf72fe2ef67aac421d77270d0bd9550950a474787 (patch)
tree196bf17ba1085e625cae06b3d399fac4b3f408ef
parentd65e6ff2f1a480df52b275cadc9bc3e7b31d4fb6 (diff)
[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
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp8
-rw-r--r--llvm/test/Transforms/InstCombine/and-fcmp.ll44
-rw-r--r--llvm/test/Transforms/InstCombine/or-fcmp.ll44
3 files changed, 96 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 38bd74b8f89d..1cd06a0371b7 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 48edc3973b9b..03dbf339b245 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 eeed99d5474b..0ff3d3ddd10a 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
+}