[llvm] r346147 - [InstCombine] canonicalize -0.0 to +0.0 in fcmp

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 5 09:26:42 PST 2018


Author: spatel
Date: Mon Nov  5 09:26:42 2018
New Revision: 346147

URL: http://llvm.org/viewvc/llvm-project?rev=346147&view=rev
Log:
[InstCombine] canonicalize -0.0 to +0.0 in fcmp

As stated in IEEE-754 and discussed in:
https://bugs.llvm.org/show_bug.cgi?id=38086
...the sign of zero does not affect any FP compare predicate.

Known regressions were fixed with:
rL346097 (D54001)
rL346143

The transform will help reduce pattern-matching complexity to solve:
https://bugs.llvm.org/show_bug.cgi?id=39475
...as well as improve CSE and codegen (a zero constant is almost always
easier to produce than 0x80..00).


Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
    llvm/trunk/test/Transforms/InstCombine/fcmp-special.ll
    llvm/trunk/test/Transforms/InstCombine/fcmp.ll
    llvm/trunk/test/Transforms/InstCombine/minmax-fp.ll
    llvm/trunk/test/Transforms/InstCombine/select-binop-cmp.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=346147&r1=346146&r2=346147&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Mon Nov  5 09:26:42 2018
@@ -5397,6 +5397,13 @@ Instruction *InstCombiner::visitFCmpInst
         return nullptr;
     }
 
+  // The sign of 0.0 is ignored by fcmp, so canonicalize to +0.0:
+  // fcmp Pred X, -0.0 --> fcmp Pred X, 0.0
+  if (match(Op1, m_AnyZeroFP()) && !match(Op1, m_PosZeroFP())) {
+    I.setOperand(1, ConstantFP::getNullValue(Op1->getType()));
+    return &I;
+  }
+
   // Handle fcmp with instruction LHS and constant RHS.
   Instruction *LHSI;
   Constant *RHSC;

Modified: llvm/trunk/test/Transforms/InstCombine/fcmp-special.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fcmp-special.ll?rev=346147&r1=346146&r2=346147&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/fcmp-special.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/fcmp-special.ll Mon Nov  5 09:26:42 2018
@@ -190,7 +190,7 @@ define i1 @nnan_ops_to_fcmp_uno(float %x
 
 define i1 @negative_zero_oeq(float %x) {
 ; CHECK-LABEL: @negative_zero_oeq(
-; CHECK-NEXT:    [[R:%.*]] = fcmp oeq float [[X:%.*]], -0.000000e+00
+; CHECK-NEXT:    [[R:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %r = fcmp oeq float %x, -0.0
@@ -199,7 +199,7 @@ define i1 @negative_zero_oeq(float %x) {
 
 define i1 @negative_zero_oge(double %x) {
 ; CHECK-LABEL: @negative_zero_oge(
-; CHECK-NEXT:    [[R:%.*]] = fcmp nnan oge double [[X:%.*]], -0.000000e+00
+; CHECK-NEXT:    [[R:%.*]] = fcmp nnan oge double [[X:%.*]], 0.000000e+00
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %r = fcmp nnan oge double %x, -0.0
@@ -208,7 +208,7 @@ define i1 @negative_zero_oge(double %x)
 
 define i1 @negative_zero_uge(half %x) {
 ; CHECK-LABEL: @negative_zero_uge(
-; CHECK-NEXT:    [[R:%.*]] = fcmp fast uge half [[X:%.*]], 0xH8000
+; CHECK-NEXT:    [[R:%.*]] = fcmp fast uge half [[X:%.*]], 0xH0000
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %r = fcmp fast uge half %x, -0.0
@@ -217,7 +217,7 @@ define i1 @negative_zero_uge(half %x) {
 
 define <2 x i1> @negative_zero_olt_vec(<2 x float> %x) {
 ; CHECK-LABEL: @negative_zero_olt_vec(
-; CHECK-NEXT:    [[R:%.*]] = fcmp reassoc ninf olt <2 x float> [[X:%.*]], <float -0.000000e+00, float -0.000000e+00>
+; CHECK-NEXT:    [[R:%.*]] = fcmp reassoc ninf olt <2 x float> [[X:%.*]], zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[R]]
 ;
   %r = fcmp reassoc ninf olt <2 x float> %x, <float -0.0, float -0.0>
@@ -226,7 +226,7 @@ define <2 x i1> @negative_zero_olt_vec(<
 
 define <2 x i1> @negative_zero_une_vec_undef(<2 x double> %x) {
 ; CHECK-LABEL: @negative_zero_une_vec_undef(
-; CHECK-NEXT:    [[R:%.*]] = fcmp nnan une <2 x double> [[X:%.*]], <double -0.000000e+00, double undef>
+; CHECK-NEXT:    [[R:%.*]] = fcmp nnan une <2 x double> [[X:%.*]], zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[R]]
 ;
   %r = fcmp nnan une <2 x double> %x, <double -0.0, double undef>
@@ -235,7 +235,7 @@ define <2 x i1> @negative_zero_une_vec_u
 
 define <2 x i1> @negative_zero_ule_vec_mixed(<2 x float> %x) {
 ; CHECK-LABEL: @negative_zero_ule_vec_mixed(
-; CHECK-NEXT:    [[R:%.*]] = fcmp ule <2 x float> [[X:%.*]], <float 0.000000e+00, float -0.000000e+00>
+; CHECK-NEXT:    [[R:%.*]] = fcmp ule <2 x float> [[X:%.*]], zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[R]]
 ;
   %r = fcmp ule <2 x float> %x, <float 0.0, float -0.0>

Modified: llvm/trunk/test/Transforms/InstCombine/fcmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fcmp.ll?rev=346147&r1=346146&r2=346147&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/fcmp.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/fcmp.ll Mon Nov  5 09:26:42 2018
@@ -360,7 +360,7 @@ define i1 @test26_recipX_unorderd(float
 ; Fold <-1.0, -1.0> / X > <-0.0, -0.0>
 define <2 x i1> @test27_recipX_gt_vecsplat(<2 x float> %X) {
 ; CHECK-LABEL: @test27_recipX_gt_vecsplat(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf olt <2 x float> [[X:%.*]], <float -0.000000e+00, float -0.000000e+00>
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf olt <2 x float> [[X:%.*]], zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
 ;
   %div = fdiv ninf <2 x float> <float -1.0, float -1.0>, %X

Modified: llvm/trunk/test/Transforms/InstCombine/minmax-fp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/minmax-fp.ll?rev=346147&r1=346146&r2=346147&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/minmax-fp.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/minmax-fp.ll Mon Nov  5 09:26:42 2018
@@ -78,7 +78,7 @@ define double @t6(float %a) {
 
 define double @t7(float %a) {
 ; CHECK-LABEL: @t7(
-; CHECK-NEXT:    [[DOTINV:%.*]] = fcmp oge float [[A:%.*]], -0.000000e+00
+; CHECK-NEXT:    [[DOTINV:%.*]] = fcmp oge float [[A:%.*]], 0.000000e+00
 ; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[DOTINV]], float -0.000000e+00, float [[A]]
 ; CHECK-NEXT:    [[TMP2:%.*]] = fpext float [[TMP1]] to double
 ; CHECK-NEXT:    ret double [[TMP2]]

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=346147&r1=346146&r2=346147&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/select-binop-cmp.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/select-binop-cmp.ll Mon Nov  5 09:26:42 2018
@@ -142,7 +142,7 @@ define i32 @select_xor_inv_icmp2(i32 %x,
 
 define float @select_fadd_fcmp(float %x, float %y, float %z) {
 ; CHECK-LABEL: @select_fadd_fcmp(
-; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], -0.000000e+00
+; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]
 ; CHECK-NEXT:    ret float [[C]]
 ;
@@ -168,7 +168,7 @@ define float @select_fadd_fcmp_poszero(f
 
 define float @select_fadd_fcmp_2(float %x, float %y, float %v) {
 ; CHECK-LABEL: @select_fadd_fcmp_2(
-; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], -0.000000e+00
+; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
 ; CHECK-NEXT:    [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00
 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z]]
 ; CHECK-NEXT:    ret float [[C]]
@@ -198,7 +198,7 @@ define float @select_fadd_fcmp_2_poszero
 
 define float @select_fadd_fcmp_3(float %x, float %y) {
 ; CHECK-LABEL: @select_fadd_fcmp_3(
-; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], -0.000000e+00
+; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float 6.000000e+00
 ; CHECK-NEXT:    ret float [[C]]
 ;
@@ -224,7 +224,7 @@ define float @select_fadd_fcmp_3_poszero
 
 define float @select_fadd_fcmp_4(float %x, float %y, float %z) {
 ; CHECK-LABEL: @select_fadd_fcmp_4(
-; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], -0.000000e+00
+; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z:%.*]]
 ; CHECK-NEXT:    ret float [[C]]
 ;
@@ -250,7 +250,7 @@ define float @select_fadd_fcmp_4_poszero
 
 define float @select_fadd_fcmp_5(float %x, float %y, float %v) {
 ; CHECK-LABEL: @select_fadd_fcmp_5(
-; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], -0.000000e+00
+; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
 ; CHECK-NEXT:    [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00
 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Z]], float [[Y:%.*]]
 ; CHECK-NEXT:    ret float [[C]]
@@ -280,7 +280,7 @@ define float @select_fadd_fcmp_5_poszero
 
 define float @select_fadd_fcmp_6(float %x, float %y, float %z) {
 ; CHECK-LABEL: @select_fadd_fcmp_6(
-; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], -0.000000e+00
+; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float 6.000000e+00, float [[Y:%.*]]
 ; CHECK-NEXT:    ret float [[C]]
 ;
@@ -332,7 +332,7 @@ define float @select_fsub_fcmp(float %x,
 
 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:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]
 ; CHECK-NEXT:    ret float [[C]]
 ;
@@ -675,7 +675,7 @@ define float @select_fadd_fcmp_bad_3(flo
 ; Invalid order of operands of select
 define float @select_fadd_fcmp_bad_4(float %x, float %y, float %z) {
 ; CHECK-LABEL: @select_fadd_fcmp_bad_4(
-; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], -0.000000e+00
+; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
 ; CHECK-NEXT:    [[B:%.*]] = fadd float [[X]], [[Z:%.*]]
 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
 ; CHECK-NEXT:    ret float [[C]]
@@ -689,7 +689,7 @@ define float @select_fadd_fcmp_bad_4(flo
 ; Invalid comparison type
 define float @select_fadd_fcmp_bad_5(float %x, float %y, float %z) {
 ; CHECK-LABEL: @select_fadd_fcmp_bad_5(
-; CHECK-NEXT:    [[A:%.*]] = fcmp one float [[X:%.*]], -0.000000e+00
+; CHECK-NEXT:    [[A:%.*]] = fcmp one 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:    ret float [[C]]
@@ -703,7 +703,7 @@ define float @select_fadd_fcmp_bad_5(flo
 ; Invalid order of operands of select
 define float @select_fadd_fcmp_bad_6(float %x, float %y, float %z) {
 ; CHECK-LABEL: @select_fadd_fcmp_bad_6(
-; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], -0.000000e+00
+; 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 [[Y:%.*]], float [[B]]
 ; CHECK-NEXT:    ret float [[C]]
@@ -717,7 +717,7 @@ define float @select_fadd_fcmp_bad_6(flo
 ; Do not transform if we have signed zeros and if Z is possibly negative zero
 define float @select_fadd_fcmp_bad_7(float %x, float %y, float %z) {
 ; CHECK-LABEL: @select_fadd_fcmp_bad_7(
-; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], -0.000000e+00
+; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
 ; CHECK-NEXT:    [[B:%.*]] = fadd float [[X]], [[Z:%.*]]
 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
 ; CHECK-NEXT:    ret float [[C]]
@@ -731,7 +731,7 @@ define float @select_fadd_fcmp_bad_7(flo
 ; Invalid comparison type
 define float @select_fadd_fcmp_bad_8(float %x, float %y, float %v) {
 ; CHECK-LABEL: @select_fadd_fcmp_bad_8(
-; CHECK-NEXT:    [[A:%.*]] = fcmp one float [[X:%.*]], -0.000000e+00
+; CHECK-NEXT:    [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00
 ; CHECK-NEXT:    [[Z:%.*]] = fadd float [[V:%.*]], -1.000000e+00
 ; CHECK-NEXT:    [[B:%.*]] = fadd float [[Z]], [[X]]
 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
@@ -747,7 +747,7 @@ define float @select_fadd_fcmp_bad_8(flo
 ; Invalid comparison type
 define float @select_fadd_fcmp_bad_9(float %x, float %y, float %z) {
 ; CHECK-LABEL: @select_fadd_fcmp_bad_9(
-; CHECK-NEXT:    [[A:%.*]] = fcmp one float [[X:%.*]], -0.000000e+00
+; CHECK-NEXT:    [[A:%.*]] = fcmp one 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:    ret float [[C]]
@@ -761,7 +761,7 @@ define float @select_fadd_fcmp_bad_9(flo
 ; Invalid comparison type
 define float @select_fadd_fcmp_bad_10(float %x, float %y, float %v) {
 ; CHECK-LABEL: @select_fadd_fcmp_bad_10(
-; CHECK-NEXT:    [[A:%.*]] = fcmp one float [[X:%.*]], -0.000000e+00
+; CHECK-NEXT:    [[A:%.*]] = fcmp one 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]]
@@ -777,7 +777,7 @@ define float @select_fadd_fcmp_bad_10(fl
 ; Do not transform if Z is possibly negative zero
 define float @select_fadd_fcmp_bad_11(float %x, float %y, float %v) {
 ; CHECK-LABEL: @select_fadd_fcmp_bad_11(
-; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], -0.000000e+00
+; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
 ; CHECK-NEXT:    [[Z:%.*]] = fadd float [[V:%.*]], -1.000000e+00
 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z]]
 ; CHECK-NEXT:    ret float [[C]]
@@ -792,7 +792,7 @@ define float @select_fadd_fcmp_bad_11(fl
 ; Do not transform if we have signed zeros and if Z is possibly negative zero
 define float @select_fadd_fcmp_bad_12(float %x, float %y, float %z) {
 ; CHECK-LABEL: @select_fadd_fcmp_bad_12(
-; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], -0.000000e+00
+; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
 ; CHECK-NEXT:    [[B:%.*]] = fadd float [[Z:%.*]], [[X]]
 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
 ; CHECK-NEXT:    ret float [[C]]
@@ -806,7 +806,7 @@ define float @select_fadd_fcmp_bad_12(fl
 ; Invalid order of operands of select
 define float @select_fadd_fcmp_bad_13(float %x, float %y, float %z) {
 ; CHECK-LABEL: @select_fadd_fcmp_bad_13(
-; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], -0.000000e+00
+; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
 ; CHECK-NEXT:    [[B:%.*]] = fadd nsz float [[X]], [[Z:%.*]]
 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
 ; CHECK-NEXT:    ret float [[C]]




More information about the llvm-commits mailing list