diff options
author | Craig Topper <craig.topper@sifive.com> | 2022-03-09 09:07:22 -0800 |
---|---|---|
committer | Craig Topper <craig.topper@sifive.com> | 2022-03-09 09:17:09 -0800 |
commit | f72fe2ef67aac421d77270d0bd9550950a474787 (patch) | |
tree | 196bf17ba1085e625cae06b3d399fac4b3f408ef | |
parent | d65e6ff2f1a480df52b275cadc9bc3e7b31d4fb6 (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.cpp | 8 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/and-fcmp.ll | 44 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/or-fcmp.ll | 44 |
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 +} |