This revision was automatically updated to reflect the committed changes. Closed by commit rGd871ef4e6ade: [instcombine] remove fsub to fneg hacks; only emit fneg (authored by simoll).
Changed prior to commit: https://reviews.llvm.org/D75467?vs=249396&id=249409#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75467/new/ https://reviews.llvm.org/D75467 Files: clang/test/CodeGen/fma-builtins-constrained.c llvm/include/llvm/IR/PatternMatch.h llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp llvm/test/Transforms/InstCombine/X86/x86-avx512.ll llvm/test/Transforms/InstCombine/cos-1.ll llvm/test/Transforms/InstCombine/fadd.ll llvm/test/Transforms/InstCombine/fast-math.ll llvm/test/Transforms/InstCombine/fdiv.ll llvm/test/Transforms/InstCombine/fmul.ll llvm/test/Transforms/InstCombine/fneg.ll llvm/test/Transforms/InstCombine/fpextend.ll llvm/test/Transforms/InstCombine/fsub.ll llvm/test/Transforms/InstCombine/maximum.ll llvm/test/Transforms/InstCombine/maxnum.ll llvm/test/Transforms/InstCombine/minimum.ll llvm/test/Transforms/InstCombine/minnum.ll llvm/test/Transforms/InstCombine/operand-complexity.ll llvm/test/Transforms/InstCombine/vec_shuffle.ll
Index: llvm/test/Transforms/InstCombine/vec_shuffle.ll =================================================================== --- llvm/test/Transforms/InstCombine/vec_shuffle.ll +++ llvm/test/Transforms/InstCombine/vec_shuffle.ll @@ -1263,7 +1263,7 @@ define <2 x float> @fneg(<2 x float> %x) { ; CHECK-LABEL: @fneg( -; CHECK-NEXT: [[TMP1:%.*]] = fsub <2 x float> <float -0.000000e+00, float undef>, [[X:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = fneg <2 x float> [[X:%.*]] ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> undef, <2 x i32> zeroinitializer ; CHECK-NEXT: ret <2 x float> [[R]] ; Index: llvm/test/Transforms/InstCombine/operand-complexity.ll =================================================================== --- llvm/test/Transforms/InstCombine/operand-complexity.ll +++ llvm/test/Transforms/InstCombine/operand-complexity.ll @@ -92,7 +92,7 @@ define float @fneg(float %x) { ; CHECK-LABEL: @fneg( ; CHECK-NEXT: [[BO:%.*]] = fdiv float [[X:%.*]], 4.200000e+01 -; CHECK-NEXT: [[FNEGX:%.*]] = fsub float -0.000000e+00, [[X]] +; CHECK-NEXT: [[FNEGX:%.*]] = fneg float [[X]] ; CHECK-NEXT: [[R:%.*]] = fmul float [[BO]], [[FNEGX]] ; CHECK-NEXT: call void @use(float [[FNEGX]]) ; CHECK-NEXT: ret float [[R]] @@ -122,7 +122,7 @@ define <2 x float> @fneg_vec(<2 x float> %x) { ; CHECK-LABEL: @fneg_vec( ; CHECK-NEXT: [[BO:%.*]] = fdiv <2 x float> [[X:%.*]], <float 4.200000e+01, float -4.200000e+01> -; CHECK-NEXT: [[FNEGX:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X]] +; CHECK-NEXT: [[FNEGX:%.*]] = fneg <2 x float> [[X]] ; CHECK-NEXT: [[R:%.*]] = fmul <2 x float> [[BO]], [[FNEGX]] ; CHECK-NEXT: call void @use_vec(<2 x float> [[FNEGX]]) ; CHECK-NEXT: ret <2 x float> [[R]] @@ -137,7 +137,7 @@ define <2 x float> @fneg_vec_undef(<2 x float> %x) { ; CHECK-LABEL: @fneg_vec_undef( ; CHECK-NEXT: [[BO:%.*]] = fdiv <2 x float> [[X:%.*]], <float 4.200000e+01, float -4.200000e+01> -; CHECK-NEXT: [[FNEGX:%.*]] = fsub <2 x float> <float -0.000000e+00, float undef>, [[X]] +; CHECK-NEXT: [[FNEGX:%.*]] = fneg <2 x float> [[X]] ; CHECK-NEXT: [[R:%.*]] = fmul <2 x float> [[BO]], [[FNEGX]] ; CHECK-NEXT: call void @use_vec(<2 x float> [[FNEGX]]) ; CHECK-NEXT: ret <2 x float> [[R]] Index: llvm/test/Transforms/InstCombine/minnum.ll =================================================================== --- llvm/test/Transforms/InstCombine/minnum.ll +++ llvm/test/Transforms/InstCombine/minnum.ll @@ -301,7 +301,7 @@ declare void @use(double) define double @neg_neg_extra_use_x(double %x, double %y) { ; CHECK-LABEL: @neg_neg_extra_use_x( -; CHECK-NEXT: [[NEGX:%.*]] = fsub double -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[NEGX:%.*]] = fneg double [[X:%.*]] ; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.maxnum.f64(double [[X]], double [[Y:%.*]]) ; CHECK-NEXT: [[R:%.*]] = fneg double [[TMP1]] ; CHECK-NEXT: call void @use(double [[NEGX]]) @@ -331,7 +331,7 @@ define double @neg_neg_extra_use_y(double %x, double %y) { ; CHECK-LABEL: @neg_neg_extra_use_y( -; CHECK-NEXT: [[NEGY:%.*]] = fsub double -0.000000e+00, [[Y:%.*]] +; CHECK-NEXT: [[NEGY:%.*]] = fneg double [[Y:%.*]] ; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.maxnum.f64(double [[X:%.*]], double [[Y]]) ; CHECK-NEXT: [[R:%.*]] = fneg double [[TMP1]] ; CHECK-NEXT: call void @use(double [[NEGY]]) @@ -361,8 +361,8 @@ define double @neg_neg_extra_use_x_and_y(double %x, double %y) { ; CHECK-LABEL: @neg_neg_extra_use_x_and_y( -; CHECK-NEXT: [[NEGX:%.*]] = fsub double -0.000000e+00, [[X:%.*]] -; CHECK-NEXT: [[NEGY:%.*]] = fsub double -0.000000e+00, [[Y:%.*]] +; CHECK-NEXT: [[NEGX:%.*]] = fneg double [[X:%.*]] +; CHECK-NEXT: [[NEGY:%.*]] = fneg double [[Y:%.*]] ; CHECK-NEXT: [[R:%.*]] = call double @llvm.minnum.f64(double [[NEGX]], double [[NEGY]]) ; CHECK-NEXT: call void @use(double [[NEGX]]) ; CHECK-NEXT: call void @use(double [[NEGY]]) Index: llvm/test/Transforms/InstCombine/minimum.ll =================================================================== --- llvm/test/Transforms/InstCombine/minimum.ll +++ llvm/test/Transforms/InstCombine/minimum.ll @@ -295,7 +295,7 @@ declare void @use(double) define double @neg_neg_extra_use_x(double %x, double %y) { ; CHECK-LABEL: @neg_neg_extra_use_x( -; CHECK-NEXT: [[NEGX:%.*]] = fsub double -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[NEGX:%.*]] = fneg double [[X:%.*]] ; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.maximum.f64(double [[X]], double [[Y:%.*]]) ; CHECK-NEXT: [[R:%.*]] = fneg double [[TMP1]] ; CHECK-NEXT: call void @use(double [[NEGX]]) @@ -325,7 +325,7 @@ define double @neg_neg_extra_use_y(double %x, double %y) { ; CHECK-LABEL: @neg_neg_extra_use_y( -; CHECK-NEXT: [[NEGY:%.*]] = fsub double -0.000000e+00, [[Y:%.*]] +; CHECK-NEXT: [[NEGY:%.*]] = fneg double [[Y:%.*]] ; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.maximum.f64(double [[X:%.*]], double [[Y]]) ; CHECK-NEXT: [[R:%.*]] = fneg double [[TMP1]] ; CHECK-NEXT: call void @use(double [[NEGY]]) @@ -355,8 +355,8 @@ define double @neg_neg_extra_use_x_and_y(double %x, double %y) { ; CHECK-LABEL: @neg_neg_extra_use_x_and_y( -; CHECK-NEXT: [[NEGX:%.*]] = fsub double -0.000000e+00, [[X:%.*]] -; CHECK-NEXT: [[NEGY:%.*]] = fsub double -0.000000e+00, [[Y:%.*]] +; CHECK-NEXT: [[NEGX:%.*]] = fneg double [[X:%.*]] +; CHECK-NEXT: [[NEGY:%.*]] = fneg double [[Y:%.*]] ; CHECK-NEXT: [[R:%.*]] = call double @llvm.minimum.f64(double [[NEGX]], double [[NEGY]]) ; CHECK-NEXT: call void @use(double [[NEGX]]) ; CHECK-NEXT: call void @use(double [[NEGY]]) Index: llvm/test/Transforms/InstCombine/maxnum.ll =================================================================== --- llvm/test/Transforms/InstCombine/maxnum.ll +++ llvm/test/Transforms/InstCombine/maxnum.ll @@ -264,7 +264,7 @@ declare void @use(float) define float @neg_neg_extra_use_x(float %x, float %y) { ; CHECK-LABEL: @neg_neg_extra_use_x( -; CHECK-NEXT: [[NEGX:%.*]] = fsub float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[NEGX:%.*]] = fneg float [[X:%.*]] ; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.minnum.f32(float [[X]], float [[Y:%.*]]) ; CHECK-NEXT: [[R:%.*]] = fneg float [[TMP1]] ; CHECK-NEXT: call void @use(float [[NEGX]]) @@ -294,7 +294,7 @@ define float @neg_neg_extra_use_y(float %x, float %y) { ; CHECK-LABEL: @neg_neg_extra_use_y( -; CHECK-NEXT: [[NEGY:%.*]] = fsub float -0.000000e+00, [[Y:%.*]] +; CHECK-NEXT: [[NEGY:%.*]] = fneg float [[Y:%.*]] ; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y]]) ; CHECK-NEXT: [[R:%.*]] = fneg float [[TMP1]] ; CHECK-NEXT: call void @use(float [[NEGY]]) @@ -324,8 +324,8 @@ define float @neg_neg_extra_use_x_and_y(float %x, float %y) { ; CHECK-LABEL: @neg_neg_extra_use_x_and_y( -; CHECK-NEXT: [[NEGX:%.*]] = fsub float -0.000000e+00, [[X:%.*]] -; CHECK-NEXT: [[NEGY:%.*]] = fsub float -0.000000e+00, [[Y:%.*]] +; CHECK-NEXT: [[NEGX:%.*]] = fneg float [[X:%.*]] +; CHECK-NEXT: [[NEGY:%.*]] = fneg float [[Y:%.*]] ; CHECK-NEXT: [[R:%.*]] = call float @llvm.maxnum.f32(float [[NEGX]], float [[NEGY]]) ; CHECK-NEXT: call void @use(float [[NEGX]]) ; CHECK-NEXT: call void @use(float [[NEGY]]) Index: llvm/test/Transforms/InstCombine/maximum.ll =================================================================== --- llvm/test/Transforms/InstCombine/maximum.ll +++ llvm/test/Transforms/InstCombine/maximum.ll @@ -270,7 +270,7 @@ declare void @use(float) define float @neg_neg_extra_use_x(float %x, float %y) { ; CHECK-LABEL: @neg_neg_extra_use_x( -; CHECK-NEXT: [[NEGX:%.*]] = fsub float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[NEGX:%.*]] = fneg float [[X:%.*]] ; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.minimum.f32(float [[X]], float [[Y:%.*]]) ; CHECK-NEXT: [[R:%.*]] = fneg float [[TMP1]] ; CHECK-NEXT: call void @use(float [[NEGX]]) @@ -300,7 +300,7 @@ define float @neg_neg_extra_use_y(float %x, float %y) { ; CHECK-LABEL: @neg_neg_extra_use_y( -; CHECK-NEXT: [[NEGY:%.*]] = fsub float -0.000000e+00, [[Y:%.*]] +; CHECK-NEXT: [[NEGY:%.*]] = fneg float [[Y:%.*]] ; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y]]) ; CHECK-NEXT: [[R:%.*]] = fneg float [[TMP1]] ; CHECK-NEXT: call void @use(float [[NEGY]]) @@ -330,8 +330,8 @@ define float @neg_neg_extra_use_x_and_y(float %x, float %y) { ; CHECK-LABEL: @neg_neg_extra_use_x_and_y( -; CHECK-NEXT: [[NEGX:%.*]] = fsub float -0.000000e+00, [[X:%.*]] -; CHECK-NEXT: [[NEGY:%.*]] = fsub float -0.000000e+00, [[Y:%.*]] +; CHECK-NEXT: [[NEGX:%.*]] = fneg float [[X:%.*]] +; CHECK-NEXT: [[NEGY:%.*]] = fneg float [[Y:%.*]] ; CHECK-NEXT: [[R:%.*]] = call float @llvm.maximum.f32(float [[NEGX]], float [[NEGY]]) ; CHECK-NEXT: call void @use(float [[NEGX]]) ; CHECK-NEXT: call void @use(float [[NEGY]]) Index: llvm/test/Transforms/InstCombine/fsub.ll =================================================================== --- llvm/test/Transforms/InstCombine/fsub.ll +++ llvm/test/Transforms/InstCombine/fsub.ll @@ -6,7 +6,7 @@ define float @test1(float %x, float %y) { ; CHECK-LABEL: @test1( ; CHECK-NEXT: [[T1:%.*]] = fsub float [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: [[T2:%.*]] = fsub float -0.000000e+00, [[T1]] +; CHECK-NEXT: [[T2:%.*]] = fneg float [[T1]] ; CHECK-NEXT: ret float [[T2]] ; %t1 = fsub float %x, %y @@ -58,7 +58,7 @@ define float @neg_sub_nsz_extra_use(float %x, float %y) { ; CHECK-LABEL: @neg_sub_nsz_extra_use( ; CHECK-NEXT: [[T1:%.*]] = fsub float [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: [[T2:%.*]] = fsub nsz float -0.000000e+00, [[T1]] +; CHECK-NEXT: [[T2:%.*]] = fneg nsz float [[T1]] ; CHECK-NEXT: call void @use(float [[T1]]) ; CHECK-NEXT: ret float [[T2]] ; @@ -296,7 +296,7 @@ define float @neg_ext_op1_extra_use(half %a, float %b) { ; CHECK-LABEL: @neg_ext_op1_extra_use( -; CHECK-NEXT: [[T1:%.*]] = fsub half 0xH8000, [[A:%.*]] +; CHECK-NEXT: [[T1:%.*]] = fneg half [[A:%.*]] ; CHECK-NEXT: [[T2:%.*]] = fpext half [[T1]] to float ; CHECK-NEXT: [[T3:%.*]] = fsub float [[B:%.*]], [[T2]] ; CHECK-NEXT: call void @use(float [[T2]]) @@ -362,7 +362,7 @@ define float @neg_trunc_op1_extra_uses(double %a, float %b) { ; CHECK-LABEL: @neg_trunc_op1_extra_uses( -; CHECK-NEXT: [[T1:%.*]] = fsub double -0.000000e+00, [[A:%.*]] +; CHECK-NEXT: [[T1:%.*]] = fneg double [[A:%.*]] ; CHECK-NEXT: [[T2:%.*]] = fptrunc double [[T1]] to float ; CHECK-NEXT: [[T3:%.*]] = fsub float [[B:%.*]], [[T2]] ; CHECK-NEXT: call void @use2(float [[T2]], double [[T1]]) @@ -454,7 +454,7 @@ define float @fsub_fdiv_fneg1_extra_use(float %x, float %y, float %z) { ; CHECK-LABEL: @fsub_fdiv_fneg1_extra_use( -; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]] ; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[NEG]], [[Y:%.*]] ; CHECK-NEXT: call void @use(float [[DIV]]) ; CHECK-NEXT: [[R:%.*]] = fsub float [[Z:%.*]], [[DIV]] @@ -469,7 +469,7 @@ define float @fsub_fdiv_fneg2_extra_use(float %x, float %y, float %z) { ; CHECK-LABEL: @fsub_fdiv_fneg2_extra_use( -; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]] ; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[Y:%.*]], [[NEG]] ; CHECK-NEXT: call void @use(float [[DIV]]) ; CHECK-NEXT: [[R:%.*]] = fsub float [[Z:%.*]], [[DIV]] @@ -486,7 +486,7 @@ define <2 x float> @fsub_fmul_fneg1_extra_use(<2 x float> %x, <2 x float> %y, <2 x float> %z) { ; CHECK-LABEL: @fsub_fmul_fneg1_extra_use( -; CHECK-NEXT: [[NEG:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]] +; CHECK-NEXT: [[NEG:%.*]] = fneg <2 x float> [[X:%.*]] ; CHECK-NEXT: [[MUL:%.*]] = fmul <2 x float> [[NEG]], [[Y:%.*]] ; CHECK-NEXT: call void @use_vec(<2 x float> [[MUL]]) ; CHECK-NEXT: [[R:%.*]] = fsub <2 x float> [[Z:%.*]], [[MUL]] @@ -501,7 +501,7 @@ define float @fsub_fmul_fneg2_extra_use(float %x, float %y, float %z) { ; CHECK-LABEL: @fsub_fmul_fneg2_extra_use( -; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]] ; CHECK-NEXT: [[MUL:%.*]] = fmul float [[NEG]], [[Y:%.*]] ; CHECK-NEXT: call void @use(float [[MUL]]) ; CHECK-NEXT: [[R:%.*]] = fsub float [[Z:%.*]], [[MUL]] @@ -516,7 +516,7 @@ define float @fsub_fdiv_fneg1_extra_use2(float %x, float %y, float %z) { ; CHECK-LABEL: @fsub_fdiv_fneg1_extra_use2( -; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]] ; CHECK-NEXT: call void @use(float [[NEG]]) ; CHECK-NEXT: [[TMP1:%.*]] = fdiv float [[X]], [[Y:%.*]] ; CHECK-NEXT: [[R:%.*]] = fadd float [[TMP1]], [[Z:%.*]] @@ -531,7 +531,7 @@ define float @fsub_fdiv_fneg2_extra_use2(float %x, float %y, float %z) { ; CHECK-LABEL: @fsub_fdiv_fneg2_extra_use2( -; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]] ; CHECK-NEXT: call void @use(float [[NEG]]) ; CHECK-NEXT: [[TMP1:%.*]] = fdiv float [[Y:%.*]], [[X]] ; CHECK-NEXT: [[R:%.*]] = fadd float [[TMP1]], [[Z:%.*]] @@ -546,7 +546,7 @@ define <2 x float> @fsub_fmul_fneg1_extra_use2(<2 x float> %x, <2 x float> %y, <2 x float> %z) { ; CHECK-LABEL: @fsub_fmul_fneg1_extra_use2( -; CHECK-NEXT: [[NEG:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]] +; CHECK-NEXT: [[NEG:%.*]] = fneg <2 x float> [[X:%.*]] ; CHECK-NEXT: call void @use_vec(<2 x float> [[NEG]]) ; CHECK-NEXT: [[TMP1:%.*]] = fmul <2 x float> [[X]], [[Y:%.*]] ; CHECK-NEXT: [[R:%.*]] = fadd <2 x float> [[TMP1]], [[Z:%.*]] @@ -561,7 +561,7 @@ define float @fsub_fmul_fneg2_extra_use2(float %x, float %y, float %z) { ; CHECK-LABEL: @fsub_fmul_fneg2_extra_use2( -; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]] ; CHECK-NEXT: call void @use(float [[NEG]]) ; CHECK-NEXT: [[TMP1:%.*]] = fmul float [[X]], [[Y:%.*]] ; CHECK-NEXT: [[R:%.*]] = fadd float [[TMP1]], [[Z:%.*]] @@ -576,7 +576,7 @@ define float @fsub_fdiv_fneg1_extra_use3(float %x, float %y, float %z) { ; CHECK-LABEL: @fsub_fdiv_fneg1_extra_use3( -; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]] ; CHECK-NEXT: call void @use(float [[NEG]]) ; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[NEG]], [[Y:%.*]] ; CHECK-NEXT: call void @use(float [[DIV]]) @@ -593,7 +593,7 @@ define float @fsub_fdiv_fneg2_extra_use3(float %x, float %y, float %z) { ; CHECK-LABEL: @fsub_fdiv_fneg2_extra_use3( -; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]] ; CHECK-NEXT: call void @use(float [[NEG]]) ; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[Y:%.*]], [[NEG]] ; CHECK-NEXT: call void @use(float [[DIV]]) @@ -610,7 +610,7 @@ define <2 x float> @fsub_fmul_fneg1_extra_use3(<2 x float> %x, <2 x float> %y, <2 x float> %z) { ; CHECK-LABEL: @fsub_fmul_fneg1_extra_use3( -; CHECK-NEXT: [[NEG:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]] +; CHECK-NEXT: [[NEG:%.*]] = fneg <2 x float> [[X:%.*]] ; CHECK-NEXT: call void @use_vec(<2 x float> [[NEG]]) ; CHECK-NEXT: [[MUL:%.*]] = fmul <2 x float> [[NEG]], [[Y:%.*]] ; CHECK-NEXT: call void @use_vec(<2 x float> [[MUL]]) @@ -627,7 +627,7 @@ define float @fsub_fmul_fneg2_extra_use3(float %x, float %y, float %z) { ; CHECK-LABEL: @fsub_fmul_fneg2_extra_use3( -; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]] ; CHECK-NEXT: call void @use(float [[NEG]]) ; CHECK-NEXT: [[MUL:%.*]] = fmul float [[NEG]], [[Y:%.*]] ; CHECK-NEXT: call void @use(float [[MUL]]) @@ -753,9 +753,9 @@ define float @fake_fneg_fsub_fast_extra_use(float %x, float %y) { ; CHECK-LABEL: @fake_fneg_fsub_fast_extra_use( -; CHECK-NEXT: [[NEGX:%.*]] = fsub float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[NEGX:%.*]] = fneg float [[X:%.*]] ; CHECK-NEXT: call void @use(float [[NEGX]]) -; CHECK-NEXT: [[SUB:%.*]] = fsub fast float [[NEGX]], [[Y:%.*]] +; CHECK-NEXT: [[SUB:%.*]] = fsub fast float [[NEGX:%.*]], [[Y:%.*]] ; CHECK-NEXT: ret float [[SUB]] ; %negx = fsub float -0.0, %x Index: llvm/test/Transforms/InstCombine/fpextend.ll =================================================================== --- llvm/test/Transforms/InstCombine/fpextend.ll +++ llvm/test/Transforms/InstCombine/fpextend.ll @@ -38,7 +38,7 @@ define float @test4(float %x) nounwind { ; CHECK-LABEL: @test4( -; CHECK-NEXT: [[T34:%.*]] = fsub float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[T34:%.*]] = fneg float [[X:%.*]] ; CHECK-NEXT: ret float [[T34]] ; %t1 = fpext float %x to double Index: llvm/test/Transforms/InstCombine/fneg.ll =================================================================== --- llvm/test/Transforms/InstCombine/fneg.ll +++ llvm/test/Transforms/InstCombine/fneg.ll @@ -62,7 +62,7 @@ define float @fmul_fsub_extra_use(float %x) { ; CHECK-LABEL: @fmul_fsub_extra_use( ; CHECK-NEXT: [[M:%.*]] = fmul float [[X:%.*]], 4.200000e+01 -; CHECK-NEXT: [[R:%.*]] = fsub float -0.000000e+00, [[M]] +; CHECK-NEXT: [[R:%.*]] = fneg float [[M]] ; CHECK-NEXT: call void @use(float [[M]]) ; CHECK-NEXT: ret float [[R]] ; @@ -156,7 +156,7 @@ define float @fdiv_op1_constant_fsub_extra_use(float %x) { ; CHECK-LABEL: @fdiv_op1_constant_fsub_extra_use( ; CHECK-NEXT: [[D:%.*]] = fdiv float [[X:%.*]], 4.200000e+01 -; CHECK-NEXT: [[R:%.*]] = fsub float -0.000000e+00, [[D]] +; CHECK-NEXT: [[R:%.*]] = fneg float [[D]] ; CHECK-NEXT: call void @use(float [[D]]) ; CHECK-NEXT: ret float [[R]] ; @@ -250,7 +250,7 @@ define float @fdiv_op0_constant_fsub_extra_use(float %x) { ; CHECK-LABEL: @fdiv_op0_constant_fsub_extra_use( ; CHECK-NEXT: [[D:%.*]] = fdiv float -4.200000e+01, [[X:%.*]] -; CHECK-NEXT: [[R:%.*]] = fsub float -0.000000e+00, [[D]] +; CHECK-NEXT: [[R:%.*]] = fneg float [[D]] ; CHECK-NEXT: call void @use(float [[D]]) ; CHECK-NEXT: ret float [[R]] ; @@ -346,7 +346,7 @@ define float @fsub_fsub_sel_extra_use1(float %x, float %y, i1 %cond) { ; CHECK-LABEL: @fsub_fsub_sel_extra_use1( -; CHECK-NEXT: [[N1:%.*]] = fsub float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[N1:%.*]] = fneg float [[X:%.*]] ; CHECK-NEXT: call void @use(float [[N1]]) ; CHECK-NEXT: [[SEL_V:%.*]] = select i1 [[COND:%.*]], float [[X]], float [[Y:%.*]] ; CHECK-NEXT: [[SEL:%.*]] = fneg float [[SEL_V]] @@ -396,7 +396,7 @@ define float @fake_nsz_fadd_constant(float %x) { ; CHECK-LABEL: @fake_nsz_fadd_constant( ; CHECK-NEXT: [[A:%.*]] = fadd float [[X:%.*]], 4.200000e+01 -; CHECK-NEXT: [[R:%.*]] = fsub float -0.000000e+00, [[A]] +; CHECK-NEXT: [[R:%.*]] = fneg float [[A]] ; CHECK-NEXT: ret float [[R]] ; %a = fadd float %x, 42.0 @@ -449,7 +449,7 @@ ; CHECK-LABEL: @fake_fneg_nsz_fadd_constant_extra_use( ; CHECK-NEXT: [[A:%.*]] = fadd float [[X:%.*]], 4.200000e+01 ; CHECK-NEXT: call void @use(float [[A]]) -; CHECK-NEXT: [[R:%.*]] = fsub fast float -0.000000e+00, [[A]] +; CHECK-NEXT: [[R:%.*]] = fneg fast float [[A]] ; CHECK-NEXT: ret float [[R]] ; %a = fadd float %x, 42.0 Index: llvm/test/Transforms/InstCombine/fmul.ll =================================================================== --- llvm/test/Transforms/InstCombine/fmul.ll +++ llvm/test/Transforms/InstCombine/fmul.ll @@ -211,8 +211,8 @@ define float @neg_neg_multi_use(float %x, float %y) { ; CHECK-LABEL: @neg_neg_multi_use( -; CHECK-NEXT: [[NX:%.*]] = fsub float -0.000000e+00, [[X:%.*]] -; CHECK-NEXT: [[NY:%.*]] = fsub float -0.000000e+00, [[Y:%.*]] +; CHECK-NEXT: [[NX:%.*]] = fneg float [[X:%.*]] +; CHECK-NEXT: [[NY:%.*]] = fneg float [[Y:%.*]] ; CHECK-NEXT: [[MUL:%.*]] = fmul afn float [[X]], [[Y]] ; CHECK-NEXT: call void @use_f32(float [[NX]]) ; CHECK-NEXT: call void @use_f32(float [[NY]]) @@ -246,7 +246,7 @@ define float @unary_neg_neg_multi_use(float %x, float %y) { ; CHECK-LABEL: @unary_neg_neg_multi_use( ; CHECK-NEXT: [[NX:%.*]] = fneg float [[X:%.*]] -; CHECK-NEXT: [[NY:%.*]] = fsub float -0.000000e+00, [[Y:%.*]] +; CHECK-NEXT: [[NY:%.*]] = fneg float [[Y:%.*]] ; CHECK-NEXT: [[MUL:%.*]] = fmul afn float [[X]], [[Y]] ; CHECK-NEXT: call void @use_f32(float [[NX]]) ; CHECK-NEXT: call void @use_f32(float [[NY]]) @@ -262,7 +262,7 @@ define float @neg_unary_neg_multi_use(float %x, float %y) { ; CHECK-LABEL: @neg_unary_neg_multi_use( -; CHECK-NEXT: [[NX:%.*]] = fsub float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[NX:%.*]] = fneg float [[X:%.*]] ; CHECK-NEXT: [[NY:%.*]] = fneg float [[Y:%.*]] ; CHECK-NEXT: [[MUL:%.*]] = fmul afn float [[X]], [[Y]] ; CHECK-NEXT: call void @use_f32(float [[NX]]) @@ -280,7 +280,7 @@ ; (-0.0 - X) * Y define float @neg_mul(float %x, float %y) { ; CHECK-LABEL: @neg_mul( -; CHECK-NEXT: [[SUB:%.*]] = fsub float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[SUB:%.*]] = fneg float [[X:%.*]] ; CHECK-NEXT: [[MUL:%.*]] = fmul float [[SUB]], [[Y:%.*]] ; CHECK-NEXT: ret float [[MUL]] ; @@ -302,7 +302,7 @@ define <2 x float> @neg_mul_vec(<2 x float> %x, <2 x float> %y) { ; CHECK-LABEL: @neg_mul_vec( -; CHECK-NEXT: [[SUB:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]] +; CHECK-NEXT: [[SUB:%.*]] = fneg <2 x float> [[X:%.*]] ; CHECK-NEXT: [[MUL:%.*]] = fmul <2 x float> [[SUB]], [[Y:%.*]] ; CHECK-NEXT: ret <2 x float> [[MUL]] ; @@ -324,7 +324,7 @@ define <2 x float> @neg_mul_vec_undef(<2 x float> %x, <2 x float> %y) { ; CHECK-LABEL: @neg_mul_vec_undef( -; CHECK-NEXT: [[SUB:%.*]] = fsub <2 x float> <float undef, float -0.000000e+00>, [[X:%.*]] +; CHECK-NEXT: [[SUB:%.*]] = fneg <2 x float> [[X:%.*]] ; CHECK-NEXT: [[MUL:%.*]] = fmul <2 x float> [[SUB]], [[Y:%.*]] ; CHECK-NEXT: ret <2 x float> [[MUL]] ; @@ -347,7 +347,7 @@ define float @neg_sink_multi_use(float %x, float %y) { ; CHECK-LABEL: @neg_sink_multi_use( -; CHECK-NEXT: [[SUB1:%.*]] = fsub float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[SUB1:%.*]] = fneg float [[X:%.*]] ; CHECK-NEXT: [[MUL:%.*]] = fmul float [[SUB1]], [[Y:%.*]] ; CHECK-NEXT: [[MUL2:%.*]] = fmul float [[MUL]], [[SUB1]] ; CHECK-NEXT: ret float [[MUL2]] Index: llvm/test/Transforms/InstCombine/fdiv.ll =================================================================== --- llvm/test/Transforms/InstCombine/fdiv.ll +++ llvm/test/Transforms/InstCombine/fdiv.ll @@ -516,7 +516,7 @@ define double @fdiv_fneg1(double %x, double %y) { ; CHECK-LABEL: @fdiv_fneg1( -; CHECK-NEXT: [[NEG:%.*]] = fsub double -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[NEG:%.*]] = fneg double [[X:%.*]] ; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[NEG]], [[Y:%.*]] ; CHECK-NEXT: ret double [[DIV]] ; @@ -538,7 +538,7 @@ define <2 x float> @fdiv_fneg2(<2 x float> %x, <2 x float> %y) { ; CHECK-LABEL: @fdiv_fneg2( -; CHECK-NEXT: [[NEG:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]] +; CHECK-NEXT: [[NEG:%.*]] = fneg <2 x float> [[X:%.*]] ; CHECK-NEXT: [[DIV:%.*]] = fdiv <2 x float> [[Y:%.*]], [[NEG]] ; CHECK-NEXT: ret <2 x float> [[DIV]] ; @@ -560,7 +560,7 @@ define float @fdiv_fneg1_extra_use(float %x, float %y) { ; CHECK-LABEL: @fdiv_fneg1_extra_use( -; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]] ; CHECK-NEXT: call void @use_f32(float [[NEG]]) ; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[NEG]], [[Y:%.*]] ; CHECK-NEXT: ret float [[DIV]] Index: llvm/test/Transforms/InstCombine/fast-math.ll =================================================================== --- llvm/test/Transforms/InstCombine/fast-math.ll +++ llvm/test/Transforms/InstCombine/fast-math.ll @@ -429,7 +429,7 @@ define double @fail2(double %f1, double %f2) { ; CHECK-LABEL: @fail2( ; CHECK-NEXT: [[TMP1:%.*]] = fadd fast double [[F2:%.*]], [[F2]] -; CHECK-NEXT: [[TMP2:%.*]] = fsub fast double -0.000000e+00, [[TMP1]] +; CHECK-NEXT: [[TMP2:%.*]] = fneg fast double [[TMP1]] ; CHECK-NEXT: ret double [[TMP2]] ; %t1 = fsub fast double %f1, %f2 Index: llvm/test/Transforms/InstCombine/fadd.ll =================================================================== --- llvm/test/Transforms/InstCombine/fadd.ll +++ llvm/test/Transforms/InstCombine/fadd.ll @@ -165,7 +165,7 @@ define float @fdiv_fneg1_extra_use(float %x, float %y, float %pz) { ; CHECK-LABEL: @fdiv_fneg1_extra_use( ; CHECK-NEXT: [[Z:%.*]] = frem float 4.200000e+01, [[PZ:%.*]] -; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]] ; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[NEG]], [[Y:%.*]] ; CHECK-NEXT: call void @use(float [[DIV]]) ; CHECK-NEXT: [[R:%.*]] = fadd float [[Z]], [[DIV]] @@ -185,7 +185,7 @@ ; CHECK-LABEL: @fdiv_fneg2_extra_use( ; CHECK-NEXT: [[Y:%.*]] = frem float -4.200000e+01, [[PY:%.*]] ; CHECK-NEXT: [[Z:%.*]] = frem float 4.200000e+01, [[PZ:%.*]] -; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]] ; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[Y]], [[NEG]] ; CHECK-NEXT: call void @use(float [[DIV]]) ; CHECK-NEXT: [[R:%.*]] = fadd float [[Z]], [[DIV]] @@ -205,7 +205,7 @@ define <2 x float> @fmul_fneg1_extra_use(<2 x float> %x, <2 x float> %y, <2 x float> %pz) { ; CHECK-LABEL: @fmul_fneg1_extra_use( ; CHECK-NEXT: [[Z:%.*]] = frem <2 x float> <float 4.200000e+01, float -1.000000e+00>, [[PZ:%.*]] -; CHECK-NEXT: [[NEG:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]] +; CHECK-NEXT: [[NEG:%.*]] = fneg <2 x float> [[X:%.*]] ; CHECK-NEXT: [[MUL:%.*]] = fmul <2 x float> [[NEG]], [[Y:%.*]] ; CHECK-NEXT: call void @use_vec(<2 x float> [[MUL]]) ; CHECK-NEXT: [[R:%.*]] = fadd <2 x float> [[Z]], [[MUL]] @@ -225,7 +225,7 @@ ; CHECK-LABEL: @fmul_fneg2_extra_use( ; CHECK-NEXT: [[Y:%.*]] = frem float -4.200000e+01, [[PY:%.*]] ; CHECK-NEXT: [[Z:%.*]] = frem float 4.200000e+01, [[PZ:%.*]] -; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]] ; CHECK-NEXT: [[MUL:%.*]] = fmul float [[Y]], [[NEG]] ; CHECK-NEXT: call void @use(float [[MUL]]) ; CHECK-NEXT: [[R:%.*]] = fadd float [[Z]], [[MUL]] @@ -244,7 +244,7 @@ define float @fdiv_fneg1_extra_use2(float %x, float %y, float %z) { ; CHECK-LABEL: @fdiv_fneg1_extra_use2( -; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]] ; CHECK-NEXT: call void @use(float [[NEG]]) ; CHECK-NEXT: [[TMP1:%.*]] = fdiv float [[X]], [[Y:%.*]] ; CHECK-NEXT: [[R:%.*]] = fsub float [[Z:%.*]], [[TMP1]] @@ -261,7 +261,7 @@ define float @fdiv_fneg2_extra_use2(float %x, float %y, float %z) { ; CHECK-LABEL: @fdiv_fneg2_extra_use2( -; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]] ; CHECK-NEXT: call void @use(float [[NEG]]) ; CHECK-NEXT: [[TMP1:%.*]] = fdiv float [[Y:%.*]], [[X]] ; CHECK-NEXT: [[R:%.*]] = fsub float [[Z:%.*]], [[TMP1]] @@ -278,7 +278,7 @@ define <2 x float> @fmul_fneg1_extra_use2(<2 x float> %x, <2 x float> %y, <2 x float> %z) { ; CHECK-LABEL: @fmul_fneg1_extra_use2( -; CHECK-NEXT: [[NEG:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]] +; CHECK-NEXT: [[NEG:%.*]] = fneg <2 x float> [[X:%.*]] ; CHECK-NEXT: call void @use_vec(<2 x float> [[NEG]]) ; CHECK-NEXT: [[TMP1:%.*]] = fmul <2 x float> [[X]], [[Y:%.*]] ; CHECK-NEXT: [[R:%.*]] = fsub <2 x float> [[Z:%.*]], [[TMP1]] @@ -296,7 +296,7 @@ define float @fmul_fneg2_extra_use2(float %x, float %py, float %z) { ; CHECK-LABEL: @fmul_fneg2_extra_use2( ; CHECK-NEXT: [[Y:%.*]] = frem float -4.200000e+01, [[PY:%.*]] -; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]] ; CHECK-NEXT: call void @use(float [[NEG]]) ; CHECK-NEXT: [[TMP1:%.*]] = fmul float [[Y]], [[X]] ; CHECK-NEXT: [[R:%.*]] = fsub float [[Z:%.*]], [[TMP1]] @@ -314,7 +314,7 @@ define float @fdiv_fneg1_extra_use3(float %x, float %y, float %z) { ; CHECK-LABEL: @fdiv_fneg1_extra_use3( -; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]] ; CHECK-NEXT: call void @use(float [[NEG]]) ; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[NEG]], [[Y:%.*]] ; CHECK-NEXT: call void @use(float [[DIV]]) @@ -333,7 +333,7 @@ define float @fdiv_fneg2_extra_use3(float %x, float %y, float %z) { ; CHECK-LABEL: @fdiv_fneg2_extra_use3( -; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]] ; CHECK-NEXT: call void @use(float [[NEG]]) ; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[Y:%.*]], [[NEG]] ; CHECK-NEXT: call void @use(float [[DIV]]) @@ -352,7 +352,7 @@ define <2 x float> @fmul_fneg1_extra_use3(<2 x float> %x, <2 x float> %y, <2 x float> %z) { ; CHECK-LABEL: @fmul_fneg1_extra_use3( -; CHECK-NEXT: [[NEG:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]] +; CHECK-NEXT: [[NEG:%.*]] = fneg <2 x float> [[X:%.*]] ; CHECK-NEXT: call void @use_vec(<2 x float> [[NEG]]) ; CHECK-NEXT: [[MUL:%.*]] = fmul <2 x float> [[NEG]], [[Y:%.*]] ; CHECK-NEXT: call void @use_vec(<2 x float> [[MUL]]) @@ -372,7 +372,7 @@ define float @fmul_fneg2_extra_use3(float %x, float %py, float %z) { ; CHECK-LABEL: @fmul_fneg2_extra_use3( ; CHECK-NEXT: [[Y:%.*]] = frem float -4.200000e+01, [[PY:%.*]] -; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]] ; CHECK-NEXT: call void @use(float [[NEG]]) ; CHECK-NEXT: [[MUL:%.*]] = fmul float [[Y]], [[NEG]] ; CHECK-NEXT: call void @use(float [[MUL]]) Index: llvm/test/Transforms/InstCombine/cos-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/cos-1.ll +++ llvm/test/Transforms/InstCombine/cos-1.ll @@ -151,7 +151,7 @@ define double @sin_negated_arg_extra_use(double %x) { ; ANY-LABEL: @sin_negated_arg_extra_use( -; ANY-NEXT: [[NEG:%.*]] = fsub double -0.000000e+00, [[X:%.*]] +; ANY-NEXT: [[NEG:%.*]] = fneg double [[X:%.*]] ; ANY-NEXT: [[R:%.*]] = call double @sin(double [[NEG]]) ; ANY-NEXT: call void @use(double [[NEG]]) ; ANY-NEXT: ret double [[R]] Index: llvm/test/Transforms/InstCombine/X86/x86-avx512.ll =================================================================== --- llvm/test/Transforms/InstCombine/X86/x86-avx512.ll +++ llvm/test/Transforms/InstCombine/X86/x86-avx512.ll @@ -1345,7 +1345,7 @@ ; CHECK-NEXT: [[TMP1:%.*]] = extractelement <4 x float> [[A:%.*]], i64 0 ; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x float> [[B:%.*]], i64 0 ; CHECK-NEXT: [[TMP3:%.*]] = extractelement <4 x float> [[C:%.*]], i64 0 -; CHECK-NEXT: [[TMP4:%.*]] = fsub float -0.000000e+00, [[TMP3]] +; CHECK-NEXT: [[TMP4:%.*]] = fneg float [[TMP3]] ; CHECK-NEXT: [[TMP5:%.*]] = call float @llvm.fma.f32(float [[TMP1]], float [[TMP2]], float [[TMP4]]) ; CHECK-NEXT: [[TMP6:%.*]] = extractelement <4 x float> [[C]], i64 0 ; CHECK-NEXT: [[TMP7:%.*]] = bitcast i8 [[MASK:%.*]] to <8 x i1> @@ -1378,7 +1378,7 @@ ; CHECK-NEXT: [[TMP1:%.*]] = extractelement <4 x float> [[A:%.*]], i64 0 ; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x float> [[B:%.*]], i64 0 ; CHECK-NEXT: [[TMP3:%.*]] = extractelement <4 x float> [[C:%.*]], i32 0 -; CHECK-NEXT: [[TMP4:%.*]] = fsub float -0.000000e+00, [[TMP3]] +; CHECK-NEXT: [[TMP4:%.*]] = fneg float [[TMP3]] ; CHECK-NEXT: [[TMP5:%.*]] = call float @llvm.fma.f32(float [[TMP1]], float [[TMP2]], float [[TMP4]]) ; CHECK-NEXT: [[TMP6:%.*]] = extractelement <4 x float> [[C]], i32 0 ; CHECK-NEXT: [[TMP7:%.*]] = bitcast i8 [[MASK:%.*]] to <8 x i1> @@ -1450,7 +1450,7 @@ ; CHECK-NEXT: [[TMP1:%.*]] = extractelement <2 x double> [[A:%.*]], i64 0 ; CHECK-NEXT: [[TMP2:%.*]] = extractelement <2 x double> [[B:%.*]], i64 0 ; CHECK-NEXT: [[TMP3:%.*]] = extractelement <2 x double> [[C:%.*]], i64 0 -; CHECK-NEXT: [[TMP4:%.*]] = fsub double -0.000000e+00, [[TMP3]] +; CHECK-NEXT: [[TMP4:%.*]] = fneg double [[TMP3]] ; CHECK-NEXT: [[TMP5:%.*]] = call double @llvm.fma.f64(double [[TMP1]], double [[TMP2]], double [[TMP4]]) ; CHECK-NEXT: [[TMP6:%.*]] = extractelement <2 x double> [[C]], i64 0 ; CHECK-NEXT: [[TMP7:%.*]] = bitcast i8 [[MASK:%.*]] to <8 x i1> @@ -1479,7 +1479,7 @@ ; CHECK-NEXT: [[TMP1:%.*]] = extractelement <2 x double> [[A:%.*]], i64 0 ; CHECK-NEXT: [[TMP2:%.*]] = extractelement <2 x double> [[B:%.*]], i64 0 ; CHECK-NEXT: [[TMP3:%.*]] = extractelement <2 x double> [[C:%.*]], i64 0 -; CHECK-NEXT: [[TMP4:%.*]] = fsub double -0.000000e+00, [[TMP3]] +; CHECK-NEXT: [[TMP4:%.*]] = fneg double [[TMP3]] ; CHECK-NEXT: [[TMP5:%.*]] = call double @llvm.fma.f64(double [[TMP1]], double [[TMP2]], double [[TMP4]]) ; CHECK-NEXT: [[TMP6:%.*]] = extractelement <2 x double> [[C]], i64 0 ; CHECK-NEXT: [[TMP7:%.*]] = bitcast i8 [[MASK:%.*]] to <8 x i1> @@ -1543,10 +1543,10 @@ define <4 x float> @test_mask3_vfnmsub_ss(<4 x float> %a, <4 x float> %b, <4 x float> %c, i8 %mask) { ; CHECK-LABEL: @test_mask3_vfnmsub_ss( ; CHECK-NEXT: [[TMP1:%.*]] = extractelement <4 x float> [[A:%.*]], i64 0 -; CHECK-NEXT: [[TMP2:%.*]] = fsub float -0.000000e+00, [[TMP1]] +; CHECK-NEXT: [[TMP2:%.*]] = fneg float [[TMP1]] ; CHECK-NEXT: [[TMP3:%.*]] = extractelement <4 x float> [[B:%.*]], i64 0 ; CHECK-NEXT: [[TMP4:%.*]] = extractelement <4 x float> [[C:%.*]], i64 0 -; CHECK-NEXT: [[TMP5:%.*]] = fsub float -0.000000e+00, [[TMP4]] +; CHECK-NEXT: [[TMP5:%.*]] = fneg float [[TMP4]] ; CHECK-NEXT: [[TMP6:%.*]] = call float @llvm.fma.f32(float [[TMP2]], float [[TMP3]], float [[TMP5]]) ; CHECK-NEXT: [[TMP7:%.*]] = extractelement <4 x float> [[C]], i64 0 ; CHECK-NEXT: [[TMP8:%.*]] = bitcast i8 [[MASK:%.*]] to <8 x i1> @@ -1578,10 +1578,10 @@ define float @test_mask3_vfnmsub_ss_0(<4 x float> %a, <4 x float> %b, <4 x float> %c, i8 %mask) { ; CHECK-LABEL: @test_mask3_vfnmsub_ss_0( ; CHECK-NEXT: [[TMP1:%.*]] = extractelement <4 x float> [[A:%.*]], i64 0 -; CHECK-NEXT: [[TMP2:%.*]] = fsub float -0.000000e+00, [[TMP1]] +; CHECK-NEXT: [[TMP2:%.*]] = fneg float [[TMP1]] ; CHECK-NEXT: [[TMP3:%.*]] = extractelement <4 x float> [[B:%.*]], i64 0 ; CHECK-NEXT: [[TMP4:%.*]] = extractelement <4 x float> [[C:%.*]], i32 0 -; CHECK-NEXT: [[TMP5:%.*]] = fsub float -0.000000e+00, [[TMP4]] +; CHECK-NEXT: [[TMP5:%.*]] = fneg float [[TMP4]] ; CHECK-NEXT: [[TMP6:%.*]] = call float @llvm.fma.f32(float [[TMP2]], float [[TMP3]], float [[TMP5]]) ; CHECK-NEXT: [[TMP7:%.*]] = extractelement <4 x float> [[C]], i32 0 ; CHECK-NEXT: [[TMP8:%.*]] = bitcast i8 [[MASK:%.*]] to <8 x i1> @@ -1654,10 +1654,10 @@ define <2 x double> @test_mask3_vfnmsub_sd(<2 x double> %a, <2 x double> %b, <2 x double> %c, i8 %mask) { ; CHECK-LABEL: @test_mask3_vfnmsub_sd( ; CHECK-NEXT: [[TMP1:%.*]] = extractelement <2 x double> [[A:%.*]], i64 0 -; CHECK-NEXT: [[TMP2:%.*]] = fsub double -0.000000e+00, [[TMP1]] +; CHECK-NEXT: [[TMP2:%.*]] = fneg double [[TMP1]] ; CHECK-NEXT: [[TMP3:%.*]] = extractelement <2 x double> [[B:%.*]], i64 0 ; CHECK-NEXT: [[TMP4:%.*]] = extractelement <2 x double> [[C:%.*]], i64 0 -; CHECK-NEXT: [[TMP5:%.*]] = fsub double -0.000000e+00, [[TMP4]] +; CHECK-NEXT: [[TMP5:%.*]] = fneg double [[TMP4]] ; CHECK-NEXT: [[TMP6:%.*]] = call double @llvm.fma.f64(double [[TMP2]], double [[TMP3]], double [[TMP5]]) ; CHECK-NEXT: [[TMP7:%.*]] = extractelement <2 x double> [[C]], i64 0 ; CHECK-NEXT: [[TMP8:%.*]] = bitcast i8 [[MASK:%.*]] to <8 x i1> @@ -1685,10 +1685,10 @@ define double @test_mask3_vfnmsub_sd_0(<2 x double> %a, <2 x double> %b, <2 x double> %c, i8 %mask) { ; CHECK-LABEL: @test_mask3_vfnmsub_sd_0( ; CHECK-NEXT: [[TMP1:%.*]] = extractelement <2 x double> [[A:%.*]], i64 0 -; CHECK-NEXT: [[TMP2:%.*]] = fsub double -0.000000e+00, [[TMP1]] +; CHECK-NEXT: [[TMP2:%.*]] = fneg double [[TMP1]] ; CHECK-NEXT: [[TMP3:%.*]] = extractelement <2 x double> [[B:%.*]], i64 0 ; CHECK-NEXT: [[TMP4:%.*]] = extractelement <2 x double> [[C:%.*]], i64 0 -; CHECK-NEXT: [[TMP5:%.*]] = fsub double -0.000000e+00, [[TMP4]] +; CHECK-NEXT: [[TMP5:%.*]] = fneg double [[TMP4]] ; CHECK-NEXT: [[TMP6:%.*]] = call double @llvm.fma.f64(double [[TMP2]], double [[TMP3]], double [[TMP5]]) ; CHECK-NEXT: [[TMP7:%.*]] = extractelement <2 x double> [[C]], i64 0 ; CHECK-NEXT: [[TMP8:%.*]] = bitcast i8 [[MASK:%.*]] to <8 x i1> Index: llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp @@ -63,6 +63,9 @@ if (match(V, m_OneUse(m_Load(m_Value())))) return true; + if (match(V, m_OneUse(m_UnOp()))) + return true; + Value *V0, *V1; if (match(V, m_OneUse(m_BinOp(m_Value(V0), m_Value(V1))))) if (cheapToScalarize(V0, IsConstantExtractIndex) || @@ -373,6 +376,16 @@ return ScalarPHI; } + // TODO come up with a n-ary matcher that subsumes both unary and + // binary matchers. + UnaryOperator *UO; + if (match(SrcVec, m_UnOp(UO)) && cheapToScalarize(SrcVec, IndexC)) { + // extelt (unop X), Index --> unop (extelt X, Index) + Value *X = UO->getOperand(0); + Value *E = Builder.CreateExtractElement(X, Index); + return UnaryOperator::CreateWithCopiedFlags(UO->getOpcode(), E, UO); + } + BinaryOperator *BO; if (match(SrcVec, m_BinOp(BO)) && cheapToScalarize(SrcVec, IndexC)) { // extelt (binop X, Y), Index --> binop (extelt X, Index), (extelt Y, Index) Index: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -338,11 +338,7 @@ if (match(TI, m_FNeg(m_Value(X))) && match(FI, m_FNeg(m_Value(Y))) && (TI->hasOneUse() || FI->hasOneUse())) { Value *NewSel = Builder.CreateSelect(Cond, X, Y, SI.getName() + ".v", &SI); - // TODO: Remove the hack for the binop form when the unary op is optimized - // properly with all IR passes. - if (TI->getOpcode() != Instruction::FNeg) - return UnaryOperator::CreateFNegFMF(NewSel, cast<BinaryOperator>(TI)); - return UnaryOperator::CreateFNeg(NewSel); + return UnaryOperator::CreateFNegFMF(NewSel, TI); } // Only handle binary operators (including two-operand getelementptr) with Index: llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -1634,10 +1634,6 @@ if (match(Op, m_FNeg(m_Value(X)))) { Value *InnerTrunc = Builder.CreateFPTrunc(X, Ty); - // FIXME: Once we're sure that unary FNeg optimizations are on par with - // binary FNeg, this should always return a unary operator. - if (isa<BinaryOperator>(Op)) - return UnaryOperator::CreateFNegFMF(InnerTrunc, Op); return UnaryOperator::CreateFNegFMF(InnerTrunc, Op); } Index: llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -663,8 +663,7 @@ } Value *FAddCombine::createFNeg(Value *V) { - Value *Zero = cast<Value>(ConstantFP::getZeroValueForNegation(V->getType())); - Value *NewV = createFSub(Zero, V); + Value *NewV = Builder.CreateFNeg(V); if (Instruction *I = dyn_cast<Instruction>(NewV)) createInstPostProc(I, true); // fneg's don't receive instruction numbers. return NewV; @@ -724,8 +723,6 @@ if (!CE.isMinusOne() && !CE.isOne()) InstrNeeded++; } - if (NegOpndNum == OpndNum) - InstrNeeded++; return InstrNeeded; } @@ -2133,10 +2130,15 @@ return X; // Subtraction from -0.0 is the canonical form of fneg. - // fsub nsz 0, X ==> fsub nsz -0.0, X - Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); - if (I.hasNoSignedZeros() && match(Op0, m_PosZeroFP())) - return UnaryOperator::CreateFNegFMF(Op1, &I); + // fsub -0.0, X ==> fneg X + // fsub nsz 0.0, X ==> fneg nsz X + // + // FIXME This matcher does not respect FTZ or DAZ yet: + // fsub -0.0, Denorm ==> +-0 + // fneg Denorm ==> -Denorm + Value *Op; + if (match(&I, m_FNeg(m_Value(Op)))) + return UnaryOperator::CreateFNegFMF(Op, &I); if (Instruction *X = foldFNegIntoConstant(I)) return X; @@ -2147,6 +2149,7 @@ Value *X, *Y; Constant *C; + Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); // If Op0 is not -0.0 or we can ignore -0.0: Z - (X - Y) --> Z + (Y - X) // Canonicalize to fadd to make analysis easier. // This can also help codegen because fadd is commutative. Index: llvm/include/llvm/IR/PatternMatch.h =================================================================== --- llvm/include/llvm/IR/PatternMatch.h +++ llvm/include/llvm/IR/PatternMatch.h @@ -71,6 +71,11 @@ /// Match an arbitrary value and ignore it. inline class_match<Value> m_Value() { return class_match<Value>(); } +/// Match an arbitrary unary operation and ignore it. +inline class_match<UnaryOperator> m_UnOp() { + return class_match<UnaryOperator>(); +} + /// Match an arbitrary binary operation and ignore it. inline class_match<BinaryOperator> m_BinOp() { return class_match<BinaryOperator>(); @@ -614,6 +619,8 @@ /// Match an instruction, capturing it if we match. inline bind_ty<Instruction> m_Instruction(Instruction *&I) { return I; } +/// Match a unary operator, capturing it if we match. +inline bind_ty<UnaryOperator> m_UnOp(UnaryOperator *&I) { return I; } /// Match a binary operator, capturing it if we match. inline bind_ty<BinaryOperator> m_BinOp(BinaryOperator *&I) { return I; } /// Match a with overflow intrinsic, capturing it if we match. @@ -786,6 +793,26 @@ } //===----------------------------------------------------------------------===// +// Matcher for any unary operator. +// TODO fuse unary, binary matcher into n-ary matcher +// +template <typename OP_t> struct AnyUnaryOp_match { + OP_t X; + + AnyUnaryOp_match(const OP_t &X) : X(X) {} + + template <typename OpTy> bool match(OpTy *V) { + if (auto *I = dyn_cast<UnaryOperator>(V)) + return X.match(I->getOperand(0)); + return false; + } +}; + +template <typename OP_t> inline AnyUnaryOp_match<OP_t> m_UnOp(const OP_t &X) { + return AnyUnaryOp_match<OP_t>(X); +} + +//===----------------------------------------------------------------------===// // Matchers for specific binary operators. // Index: clang/test/CodeGen/fma-builtins-constrained.c =================================================================== --- clang/test/CodeGen/fma-builtins-constrained.c +++ clang/test/CodeGen/fma-builtins-constrained.c @@ -66,10 +66,10 @@ __m128 test_mm_fmsub_ss(__m128 a, __m128 b, __m128 c) { // COMMON-LABEL: test_mm_fmsub_ss - // COMMONIR: [[NEG:%.+]] = fneg <4 x float> %{{.+}} // COMMONIR: extractelement <4 x float> %{{.*}}, i64 0 // COMMONIR: extractelement <4 x float> %{{.*}}, i64 0 // COMMONIR: extractelement <4 x float> %{{.*}}, i64 0 + // COMMONIR: [[NEG:%.+]] = fneg float %{{.+}} // UNCONSTRAINED: call float @llvm.fma.f32(float %{{.*}}, float %{{.*}}, float %{{.*}}) // CONSTRAINED: call float @llvm.experimental.constrained.fma.f32(float %{{.*}}, float %{{.*}}, float %{{.*}}, metadata !{{.*}}) // CHECK-ASM: vfmsub213ss @@ -79,10 +79,10 @@ __m128d test_mm_fmsub_sd(__m128d a, __m128d b, __m128d c) { // COMMON-LABEL: test_mm_fmsub_sd - // COMMONIR: [[NEG:%.+]] = fneg <2 x double> %{{.+}} // COMMONIR: extractelement <2 x double> %{{.*}}, i64 0 // COMMONIR: extractelement <2 x double> %{{.*}}, i64 0 // COMMONIR: extractelement <2 x double> %{{.*}}, i64 0 + // COMMONIR: [[NEG:%.+]] = fneg double %{{.+}} // UNCONSTRAINED: call double @llvm.fma.f64(double %{{.*}}, double %{{.*}}, double %{{.*}}) // CONSTRAINED: call double @llvm.experimental.constrained.fma.f64(double %{{.*}}, double %{{.*}}, double %{{.*}}, metadata !{{.*}}) // CHECK-ASM: vfmsub213sd @@ -110,9 +110,9 @@ __m128 test_mm_fnmadd_ss(__m128 a, __m128 b, __m128 c) { // COMMON-LABEL: test_mm_fnmadd_ss - // COMMONIR: [[NEG:%.+]] = fneg <4 x float> %{{.+}} // COMMONIR: extractelement <4 x float> %{{.*}}, i64 0 // COMMONIR: extractelement <4 x float> %{{.*}}, i64 0 + // COMMONIR: [[NEG:%.+]] = fneg float %{{.+}} // COMMONIR: extractelement <4 x float> %{{.*}}, i64 0 // UNCONSTRAINED: call float @llvm.fma.f32(float %{{.*}}, float %{{.*}}, float %{{.*}}) // CONSTRAINED: call float @llvm.experimental.constrained.fma.f32(float %{{.*}}, float %{{.*}}, float %{{.*}}, metadata !{{.*}}) @@ -123,9 +123,9 @@ __m128d test_mm_fnmadd_sd(__m128d a, __m128d b, __m128d c) { // COMMON-LABEL: test_mm_fnmadd_sd - // COMMONIR: [[NEG:%.+]] = fneg <2 x double> %{{.+}} // COMMONIR: extractelement <2 x double> %{{.*}}, i64 0 // COMMONIR: extractelement <2 x double> %{{.*}}, i64 0 + // COMMONIR: [[NEG:%.+]] = fneg double %{{.+}} // COMMONIR: extractelement <2 x double> %{{.*}}, i64 0 // UNCONSTRAINED: call double @llvm.fma.f64(double %{{.*}}, double %{{.*}}, double %{{.*}}) // CONSTRAINED: call double @llvm.experimental.constrained.fma.f64(double %{{.*}}, double %{{.*}}, double %{{.*}}, metadata !{{.*}}) @@ -156,11 +156,11 @@ __m128 test_mm_fnmsub_ss(__m128 a, __m128 b, __m128 c) { // COMMON-LABEL: test_mm_fnmsub_ss - // COMMONIR: [[NEG:%.+]] = fneg <4 x float> %{{.+}} - // COMMONIR: [[NEG2:%.+]] = fneg <4 x float> %{{.+}} // COMMONIR: extractelement <4 x float> %{{.*}}, i64 0 // COMMONIR: extractelement <4 x float> %{{.*}}, i64 0 + // COMMONIR: [[NEG:%.+]] = fneg float %{{.+}} // COMMONIR: extractelement <4 x float> %{{.*}}, i64 0 + // COMMONIR: [[NEG2:%.+]] = fneg float %{{.+}} // UNCONSTRAINED: call float @llvm.fma.f32(float %{{.*}}, float %{{.*}}, float %{{.*}}) // CONSTRAINED: call float @llvm.experimental.constrained.fma.f32(float %{{.*}}, float %{{.*}}, float %{{.*}}, metadata !{{.*}}) // CHECK-ASM: vfnmsub213ss @@ -170,11 +170,11 @@ __m128d test_mm_fnmsub_sd(__m128d a, __m128d b, __m128d c) { // COMMON-LABEL: test_mm_fnmsub_sd - // COMMONIR: [[NEG:%.+]] = fneg <2 x double> %{{.+}} - // COMMONIR: [[NEG2:%.+]] = fneg <2 x double> %{{.+}} // COMMONIR: extractelement <2 x double> %{{.*}}, i64 0 // COMMONIR: extractelement <2 x double> %{{.*}}, i64 0 + // COMMONIR: [[NEG:%.+]] = fneg double %{{.+}} // COMMONIR: extractelement <2 x double> %{{.*}}, i64 0 + // COMMONIR: [[NEG2:%.+]] = fneg double %{{.+}} // UNCONSTRAINED: call double @llvm.fma.f64(double %{{.*}}, double %{{.*}}, double %{{.*}}) // CONSTRAINED: call double @llvm.experimental.constrained.fma.f64(double %{{.*}}, double %{{.*}}, double %{{.*}}, metadata !{{.*}}) // CHECK-ASM: vfnmsub213sd
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits