[llvm] r346143 - [InstCombine] loosen FP 0.0 constraint for fcmp+select substitution

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 5 08:50:45 PST 2018


Author: spatel
Date: Mon Nov  5 08:50:44 2018
New Revision: 346143

URL: http://llvm.org/viewvc/llvm-project?rev=346143&view=rev
Log:
[InstCombine] loosen FP 0.0 constraint for fcmp+select substitution

It looks like we correctly removed edge cases with 0.0 from D50714,
but we were a bit conservative because getBinOpIdentity() doesn't
distinguish between +0.0 and -0.0 and 'nsz' is effectively always
true for fcmp (see discussion in:
https://bugs.llvm.org/show_bug.cgi?id=38086

Without this change, we would get regressions by canonicalizing
to +0.0 in all fcmp, and that's a step towards solving:
https://bugs.llvm.org/show_bug.cgi?id=39475


Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp
    llvm/trunk/test/Transforms/InstCombine/select-binop-cmp.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp?rev=346143&r1=346142&r2=346143&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp Mon Nov  5 08:50:44 2018
@@ -75,13 +75,22 @@ static Instruction *foldSelectBinOpIdent
   else
     return nullptr;
 
-  // A select operand must be a binop, and the compare constant must be the
-  // identity constant for that binop.
+  // A select operand must be a binop.
   BinaryOperator *BO;
-  if (!match(Sel.getOperand(IsEq ? 1 : 2), m_BinOp(BO)) ||
-      ConstantExpr::getBinOpIdentity(BO->getOpcode(), BO->getType(), true) != C)
+  if (!match(Sel.getOperand(IsEq ? 1 : 2), m_BinOp(BO)))
     return nullptr;
 
+  // The compare constant must be the identity constant for that binop.
+  // If this a floating-point compare with 0.0, any zero constant will do.
+  Type *Ty = BO->getType();
+  Constant *IdC = ConstantExpr::getBinOpIdentity(BO->getOpcode(), Ty, true);
+  if (IdC != C) {
+    if (!IdC || !CmpInst::isFPPredicate(Pred))
+      return nullptr;
+    if (!match(IdC, m_AnyZeroFP()) || !match(C, m_AnyZeroFP()))
+      return nullptr;
+  }
+
   // Last, match the compare variable operand with a binop operand.
   Value *Y;
   if (!BO->isCommutative() && !match(BO, m_BinOp(m_Value(Y), m_Specific(X))))

Modified: llvm/trunk/test/Transforms/InstCombine/select-binop-cmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/select-binop-cmp.ll?rev=346143&r1=346142&r2=346143&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/select-binop-cmp.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/select-binop-cmp.ll Mon Nov  5 08:50:44 2018
@@ -152,13 +152,12 @@ define float @select_fadd_fcmp(float %x,
   ret float %C
 }
 
-; TODO: This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
+; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
 
 define float @select_fadd_fcmp_poszero(float %x, float %y, float %z) {
 ; CHECK-LABEL: @select_fadd_fcmp_poszero(
 ; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
-; CHECK-NEXT:    [[B:%.*]] = fadd nsz float [[Z:%.*]], [[X]]
-; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
+; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]
 ; CHECK-NEXT:    ret float [[C]]
 ;
   %A = fcmp oeq float %x, 0.0
@@ -181,14 +180,13 @@ define float @select_fadd_fcmp_2(float %
   ret float %C
 }
 
-; TODO: This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
+; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
 
 define float @select_fadd_fcmp_2_poszero(float %x, float %y, float %v) {
 ; CHECK-LABEL: @select_fadd_fcmp_2_poszero(
 ; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
 ; CHECK-NEXT:    [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00
-; CHECK-NEXT:    [[B:%.*]] = fadd float [[Z]], [[X]]
-; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
+; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z]]
 ; CHECK-NEXT:    ret float [[C]]
 ;
   %A = fcmp une float %x, 0.0
@@ -210,13 +208,12 @@ define float @select_fadd_fcmp_3(float %
   ret float %C
 }
 
-; TODO: This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
+; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
 
 define float @select_fadd_fcmp_3_poszero(float %x, float %y) {
 ; CHECK-LABEL: @select_fadd_fcmp_3_poszero(
 ; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
-; CHECK-NEXT:    [[B:%.*]] = fadd float [[X]], 6.000000e+00
-; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
+; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float 6.000000e+00
 ; CHECK-NEXT:    ret float [[C]]
 ;
   %A = fcmp une float %x, 0.0
@@ -237,13 +234,12 @@ define float @select_fadd_fcmp_4(float %
   ret float %C
 }
 
-; TODO: This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
+; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
 
 define float @select_fadd_fcmp_4_poszero(float %x, float %y, float %z) {
 ; CHECK-LABEL: @select_fadd_fcmp_4_poszero(
 ; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
-; CHECK-NEXT:    [[B:%.*]] = fadd nsz float [[Z:%.*]], [[X]]
-; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
+; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z:%.*]]
 ; CHECK-NEXT:    ret float [[C]]
 ;
   %A = fcmp une float %x, 0.0
@@ -266,14 +262,13 @@ define float @select_fadd_fcmp_5(float %
   ret float %C
 }
 
-; TODO: This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
+; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
 
 define float @select_fadd_fcmp_5_poszero(float %x, float %y, float %v) {
 ; CHECK-LABEL: @select_fadd_fcmp_5_poszero(
 ; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
 ; CHECK-NEXT:    [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00
-; CHECK-NEXT:    [[B:%.*]] = fadd float [[Z]], [[X]]
-; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
+; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Z]], float [[Y:%.*]]
 ; CHECK-NEXT:    ret float [[C]]
 ;
   %A = fcmp oeq float %x, 0.0
@@ -295,13 +290,12 @@ define float @select_fadd_fcmp_6(float %
   ret float %C
 }
 
-; TODO: This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
+; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
 
 define float @select_fadd_fcmp_6_poszero(float %x, float %y, float %z) {
 ; CHECK-LABEL: @select_fadd_fcmp_6_poszero(
 ; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
-; CHECK-NEXT:    [[B:%.*]] = fadd float [[X]], 6.000000e+00
-; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
+; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float 6.000000e+00, float [[Y:%.*]]
 ; CHECK-NEXT:    ret float [[C]]
 ;
   %A = fcmp oeq float %x, 0.0
@@ -334,13 +328,12 @@ define float @select_fsub_fcmp(float %x,
   ret float %C
 }
 
-; TODO: This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
+; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
 
 define float @select_fsub_fcmp_negzero(float %x, float %y, float %z) {
 ; CHECK-LABEL: @select_fsub_fcmp_negzero(
 ; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], -0.000000e+00
-; CHECK-NEXT:    [[B:%.*]] = fsub nsz float [[Z:%.*]], [[X]]
-; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
+; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]
 ; CHECK-NEXT:    ret float [[C]]
 ;
   %A = fcmp oeq float %x, -0.0




More information about the llvm-commits mailing list