diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp index 9155ad12598..059f7523ff9 100644 --- a/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -5397,6 +5397,13 @@ Instruction *InstCombiner::visitFCmpInst(FCmpInst &I) { 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; diff --git a/test/Transforms/InstCombine/fcmp-special.ll b/test/Transforms/InstCombine/fcmp-special.ll index 5d4cc9a8616..490dab5f24d 100644 --- a/test/Transforms/InstCombine/fcmp-special.ll +++ b/test/Transforms/InstCombine/fcmp-special.ll @@ -190,7 +190,7 @@ define i1 @nnan_ops_to_fcmp_uno(float %x, float %y) { 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:%.*]], +; 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, @@ -226,7 +226,7 @@ define <2 x i1> @negative_zero_olt_vec(<2 x float> %x) { 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:%.*]], +; 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, @@ -235,7 +235,7 @@ define <2 x i1> @negative_zero_une_vec_undef(<2 x double> %x) { 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:%.*]], +; CHECK-NEXT: [[R:%.*]] = fcmp ule <2 x float> [[X:%.*]], zeroinitializer ; CHECK-NEXT: ret <2 x i1> [[R]] ; %r = fcmp ule <2 x float> %x, diff --git a/test/Transforms/InstCombine/fcmp.ll b/test/Transforms/InstCombine/fcmp.ll index c19aae4c03b..48c12a300a3 100644 --- a/test/Transforms/InstCombine/fcmp.ll +++ b/test/Transforms/InstCombine/fcmp.ll @@ -360,7 +360,7 @@ define i1 @test26_recipX_unorderd(float %X) { ; 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:%.*]], +; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf olt <2 x float> [[X:%.*]], zeroinitializer ; CHECK-NEXT: ret <2 x i1> [[CMP]] ; %div = fdiv ninf <2 x float> , %X diff --git a/test/Transforms/InstCombine/minmax-fp.ll b/test/Transforms/InstCombine/minmax-fp.ll index 7bf8f57d4e8..11418156a48 100644 --- a/test/Transforms/InstCombine/minmax-fp.ll +++ b/test/Transforms/InstCombine/minmax-fp.ll @@ -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]] diff --git a/test/Transforms/InstCombine/select-binop-cmp.ll b/test/Transforms/InstCombine/select-binop-cmp.ll index c7361fa040e..a473acd7304 100644 --- a/test/Transforms/InstCombine/select-binop-cmp.ll +++ b/test/Transforms/InstCombine/select-binop-cmp.ll @@ -142,7 +142,7 @@ define i32 @select_xor_inv_icmp2(i32 %x, i32 %y, i32 %z) { 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(float %x, float %y, float %z) { 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(float %x, float %y, float %v) { 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(float %x, float %y) { 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(float %x, float %y, float %z) { 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(float %x, float %y, float %v) { 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, float %y, float %z) { 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(float %x, float %y, float %z, float %k) { ; 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(float %x, float %y, float %z) { ; 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(float %x, float %y, float %z) { ; 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(float %x, float %y, float %z) { ; 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(float %x, float %y, float %z) { ; 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(float %x, float %y, float %v) { ; 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(float %x, float %y, float %z) { ; 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(float %x, float %y, float %v) { ; 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(float %x, float %y, float %v) { ; 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(float %x, float %y, float %z) { ; 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]]