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 +}