[llvm] 3491f2f - [InstCombine] replace negated operand in fcmp with 0.0

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 10 09:53:41 PST 2022


Author: Sanjay Patel
Date: 2022-03-10T12:53:32-05:00
New Revision: 3491f2f4b0336cdb788fed3ff03a4b31c58db14e

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

LOG: [InstCombine] replace negated operand in fcmp with 0.0

X (any pred) -X --> X (any pred) 0.0

This works with all FP values and preserves FMF.
Alive2 examples:
https://alive2.llvm.org/ce/z/dj6jhp

This can also create one of the patterns that we match as "fabs"
as shown in one of the test diffs.

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
    llvm/test/Transforms/InstCombine/fabs.ll
    llvm/test/Transforms/InstCombine/fcmp.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index d3f6693b16db2..651d564763074 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -6527,6 +6527,25 @@ static Instruction *foldFabsWithFcmpZero(FCmpInst &I, InstCombinerImpl &IC) {
   }
 }
 
+static Instruction *foldFCmpFNegCommonOp(FCmpInst &I) {
+  CmpInst::Predicate Pred = I.getPredicate();
+  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
+
+  // Canonicalize fneg as Op1.
+  if (match(Op0, m_FNeg(m_Value())) && !match(Op1, m_FNeg(m_Value()))) {
+    std::swap(Op0, Op1);
+    Pred = I.getSwappedPredicate();
+  }
+
+  if (!match(Op1, m_FNeg(m_Specific(Op0))))
+    return nullptr;
+
+  // Replace the negated operand with 0.0:
+  // fcmp Pred Op0, -Op0 --> fcmp Pred Op0, 0.0
+  Constant *Zero = ConstantFP::getNullValue(Op0->getType());
+  return new FCmpInst(Pred, Op0, Zero, "", &I);
+}
+
 Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
   bool Changed = false;
 
@@ -6585,6 +6604,9 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
   if (match(Op0, m_FNeg(m_Value(X))) && match(Op1, m_FNeg(m_Value(Y))))
     return new FCmpInst(I.getSwappedPredicate(), X, Y, "", &I);
 
+  if (Instruction *R = foldFCmpFNegCommonOp(I))
+    return R;
+
   // Test if the FCmpInst instruction is used exclusively by a select as
   // part of a minimum or maximum operation. If so, refrain from doing
   // any other folding. This helps out other analyses which understand

diff  --git a/llvm/test/Transforms/InstCombine/fabs.ll b/llvm/test/Transforms/InstCombine/fabs.ll
index 6d42ca9989199..725b906f92bb9 100644
--- a/llvm/test/Transforms/InstCombine/fabs.ll
+++ b/llvm/test/Transforms/InstCombine/fabs.ll
@@ -351,10 +351,8 @@ define fp128 @select_fcmp_ogt_zero(fp128 %x) {
 
 define float @select_fcmp_ogt_fneg(float %a) {
 ; CHECK-LABEL: @select_fcmp_ogt_fneg(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[A:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[FNEG]], [[A]]
-; CHECK-NEXT:    [[R:%.*]] = select nsz i1 [[CMP]], float [[A]], float [[FNEG]]
-; CHECK-NEXT:    ret float [[R]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call nsz float @llvm.fabs.f32(float [[A:%.*]])
+; CHECK-NEXT:    ret float [[TMP1]]
 ;
   %fneg = fneg float %a
   %cmp = fcmp ogt float %a, %fneg

diff  --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll
index 5db6bd3c028e4..b0211d52f197f 100644
--- a/llvm/test/Transforms/InstCombine/fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp.ll
@@ -832,8 +832,7 @@ define i1 @lossy_uno(half %x) {
 
 define i1 @fneg_oeq(float %a) {
 ; CHECK-LABEL: @fneg_oeq(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[A:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[FNEG]], [[A]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[A:%.*]], 0.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %fneg = fneg float %a
@@ -843,8 +842,7 @@ define i1 @fneg_oeq(float %a) {
 
 define i1 @fneg_ogt(half %a) {
 ; CHECK-LABEL: @fneg_ogt(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg half [[A:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ogt half [[FNEG]], [[A]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast olt half [[A:%.*]], 0xH0000
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %fneg = fneg half %a
@@ -854,8 +852,7 @@ define i1 @fneg_ogt(half %a) {
 
 define <2 x i1> @fneg_oge(<2 x float> %a) {
 ; CHECK-LABEL: @fneg_oge(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg fast <2 x float> [[A:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge <2 x float> [[FNEG]], [[A]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ole <2 x float> [[A:%.*]], zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
 ;
   %fneg = fneg fast <2 x float> %a
@@ -867,7 +864,7 @@ define i1 @fneg_olt(float %a, float* %q) {
 ; CHECK-LABEL: @fneg_olt(
 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[A:%.*]]
 ; CHECK-NEXT:    store float [[FNEG]], float* [[Q:%.*]], align 4
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[FNEG]], [[A]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[A]], 0.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %fneg = fneg float %a
@@ -878,8 +875,7 @@ define i1 @fneg_olt(float %a, float* %q) {
 
 define i1 @fneg_ole(float %a) {
 ; CHECK-LABEL: @fneg_ole(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[A:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp nsz ole float [[FNEG]], [[A]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp nsz oge float [[A:%.*]], 0.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %fneg = fneg float %a
@@ -889,8 +885,7 @@ define i1 @fneg_ole(float %a) {
 
 define i1 @fneg_one(float %a) {
 ; CHECK-LABEL: @fneg_one(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[A:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan one float [[FNEG]], [[A]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan one float [[A:%.*]], 0.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %fneg = fneg float %a
@@ -900,8 +895,7 @@ define i1 @fneg_one(float %a) {
 
 define i1 @fneg_ord(float %a) {
 ; CHECK-LABEL: @fneg_ord(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[A:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ord float [[FNEG]], [[A]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ord float [[A:%.*]], 0.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %fneg = fneg float %a
@@ -911,8 +905,7 @@ define i1 @fneg_ord(float %a) {
 
 define i1 @fneg_uno(float %a) {
 ; CHECK-LABEL: @fneg_uno(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[A:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp uno float [[FNEG]], [[A]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp uno float [[A:%.*]], 0.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %fneg = fneg float %a
@@ -922,8 +915,7 @@ define i1 @fneg_uno(float %a) {
 
 define i1 @fneg_ueq(half %a) {
 ; CHECK-LABEL: @fneg_ueq(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg half [[A:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ueq half [[FNEG]], [[A]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ueq half [[A:%.*]], 0xH0000
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %fneg = fneg half %a
@@ -933,8 +925,7 @@ define i1 @fneg_ueq(half %a) {
 
 define <2 x i1> @fneg_ugt(<2 x float> %a) {
 ; CHECK-LABEL: @fneg_ugt(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg fast <2 x float> [[A:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ugt <2 x float> [[FNEG]], [[A]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult <2 x float> [[A:%.*]], zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
 ;
   %fneg = fneg fast <2 x float> %a
@@ -946,7 +937,7 @@ define i1 @fneg_uge(float %a, float* %q) {
 ; CHECK-LABEL: @fneg_uge(
 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[A:%.*]]
 ; CHECK-NEXT:    store float [[FNEG]], float* [[Q:%.*]], align 4
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge float [[FNEG]], [[A]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ule float [[A]], 0.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %fneg = fneg float %a
@@ -957,8 +948,7 @@ define i1 @fneg_uge(float %a, float* %q) {
 
 define i1 @fneg_ult(float %a) {
 ; CHECK-LABEL: @fneg_ult(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[A:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp nsz ult float [[FNEG]], [[A]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp nsz ugt float [[A:%.*]], 0.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %fneg = fneg float %a
@@ -968,8 +958,7 @@ define i1 @fneg_ult(float %a) {
 
 define i1 @fneg_ule(float %a) {
 ; CHECK-LABEL: @fneg_ule(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[A:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ule float [[FNEG]], [[A]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan uge float [[A:%.*]], 0.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %fneg = fneg float %a
@@ -979,8 +968,7 @@ define i1 @fneg_ule(float %a) {
 
 define i1 @fneg_une(float %a) {
 ; CHECK-LABEL: @fneg_une(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[A:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf une float [[FNEG]], [[A]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf une float [[A:%.*]], 0.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %fneg = fneg float %a
@@ -991,8 +979,7 @@ define i1 @fneg_une(float %a) {
 define i1 @fneg_oeq_swap(float %p) {
 ; CHECK-LABEL: @fneg_oeq_swap(
 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[P:%.*]], [[P]]
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[A]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[A]], [[FNEG]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[A]], 0.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %a = fadd float %p, %p ; thwart complexity-based canonicalization
@@ -1004,8 +991,7 @@ define i1 @fneg_oeq_swap(float %p) {
 define i1 @fneg_ogt_swap(half %p) {
 ; CHECK-LABEL: @fneg_ogt_swap(
 ; CHECK-NEXT:    [[A:%.*]] = fadd half [[P:%.*]], [[P]]
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg half [[A]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ogt half [[A]], [[FNEG]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ogt half [[A]], 0xH0000
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %a = fadd half %p, %p ; thwart complexity-based canonicalization
@@ -1017,8 +1003,7 @@ define i1 @fneg_ogt_swap(half %p) {
 define <2 x i1> @fneg_oge_swap(<2 x float> %p) {
 ; CHECK-LABEL: @fneg_oge_swap(
 ; CHECK-NEXT:    [[A:%.*]] = fadd <2 x float> [[P:%.*]], [[P]]
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg fast <2 x float> [[A]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge <2 x float> [[A]], [[FNEG]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge <2 x float> [[A]], zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
 ;
   %a = fadd <2 x float> %p, %p ; thwart complexity-based canonicalization
@@ -1032,7 +1017,7 @@ define i1 @fneg_olt_swap(float %p, float* %q) {
 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[P:%.*]], [[P]]
 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[A]]
 ; CHECK-NEXT:    store float [[FNEG]], float* [[Q:%.*]], align 4
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[A]], [[FNEG]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[A]], 0.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %a = fadd float %p, %p ; thwart complexity-based canonicalization
@@ -1045,8 +1030,7 @@ define i1 @fneg_olt_swap(float %p, float* %q) {
 define i1 @fneg_ole_swap(float %p) {
 ; CHECK-LABEL: @fneg_ole_swap(
 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[P:%.*]], [[P]]
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[A]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp nsz ole float [[A]], [[FNEG]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp nsz ole float [[A]], 0.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %a = fadd float %p, %p ; thwart complexity-based canonicalization
@@ -1058,8 +1042,7 @@ define i1 @fneg_ole_swap(float %p) {
 define i1 @fneg_one_swap(float %p) {
 ; CHECK-LABEL: @fneg_one_swap(
 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[P:%.*]], [[P]]
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[A]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan one float [[A]], [[FNEG]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan one float [[A]], 0.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %a = fadd float %p, %p ; thwart complexity-based canonicalization
@@ -1071,8 +1054,7 @@ define i1 @fneg_one_swap(float %p) {
 define i1 @fneg_ord_swap(float %p) {
 ; CHECK-LABEL: @fneg_ord_swap(
 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[P:%.*]], [[P]]
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[A]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ord float [[A]], [[FNEG]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ord float [[A]], 0.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %a = fadd float %p, %p ; thwart complexity-based canonicalization
@@ -1084,8 +1066,7 @@ define i1 @fneg_ord_swap(float %p) {
 define i1 @fneg_uno_swap(float %p) {
 ; CHECK-LABEL: @fneg_uno_swap(
 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[P:%.*]], [[P]]
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[A]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp uno float [[A]], [[FNEG]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp uno float [[A]], 0.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %a = fadd float %p, %p ; thwart complexity-based canonicalization
@@ -1097,8 +1078,7 @@ define i1 @fneg_uno_swap(float %p) {
 define i1 @fneg_ueq_swap(half %p) {
 ; CHECK-LABEL: @fneg_ueq_swap(
 ; CHECK-NEXT:    [[A:%.*]] = fadd half [[P:%.*]], [[P]]
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg half [[A]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ueq half [[A]], [[FNEG]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ueq half [[A]], 0xH0000
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %a = fadd half %p, %p ; thwart complexity-based canonicalization
@@ -1110,8 +1090,7 @@ define i1 @fneg_ueq_swap(half %p) {
 define <2 x i1> @fneg_ugt_swap(<2 x float> %p) {
 ; CHECK-LABEL: @fneg_ugt_swap(
 ; CHECK-NEXT:    [[A:%.*]] = fadd <2 x float> [[P:%.*]], [[P]]
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg fast <2 x float> [[A]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ugt <2 x float> [[A]], [[FNEG]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ugt <2 x float> [[A]], zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
 ;
   %a = fadd <2 x float> %p, %p ; thwart complexity-based canonicalization
@@ -1125,7 +1104,7 @@ define i1 @fneg_uge_swap(float %p, float* %q) {
 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[P:%.*]], [[P]]
 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[A]]
 ; CHECK-NEXT:    store float [[FNEG]], float* [[Q:%.*]], align 4
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge float [[A]], [[FNEG]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge float [[A]], 0.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %a = fadd float %p, %p ; thwart complexity-based canonicalization
@@ -1138,8 +1117,7 @@ define i1 @fneg_uge_swap(float %p, float* %q) {
 define i1 @fneg_ult_swap(float %p) {
 ; CHECK-LABEL: @fneg_ult_swap(
 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[P:%.*]], [[P]]
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[A]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp nsz ult float [[A]], [[FNEG]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp nsz ult float [[A]], 0.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %a = fadd float %p, %p ; thwart complexity-based canonicalization
@@ -1151,8 +1129,7 @@ define i1 @fneg_ult_swap(float %p) {
 define i1 @fneg_ule_swap(float %p) {
 ; CHECK-LABEL: @fneg_ule_swap(
 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[P:%.*]], [[P]]
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[A]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ule float [[A]], [[FNEG]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ule float [[A]], 0.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %a = fadd float %p, %p ; thwart complexity-based canonicalization
@@ -1164,8 +1141,7 @@ define i1 @fneg_ule_swap(float %p) {
 define i1 @fneg_une_swap(float %p) {
 ; CHECK-LABEL: @fneg_une_swap(
 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[P:%.*]], [[P]]
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[A]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf une float [[A]], [[FNEG]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf une float [[A]], 0.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %a = fadd float %p, %p ; thwart complexity-based canonicalization


        


More information about the llvm-commits mailing list