Skip to content

Commit fd81698

Browse files
committed
[InstCombine] Fold fmul X, -0.0 into copysign(0.0, -X)
1 parent df72b2c commit fd81698

File tree

4 files changed

+29
-20
lines changed

4 files changed

+29
-20
lines changed

llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -814,8 +814,15 @@ Instruction *InstCombinerImpl::visitFMul(BinaryOperator &I) {
814814
if (match(Op1, m_SpecificFP(-1.0)))
815815
return UnaryOperator::CreateFNegFMF(Op0, &I);
816816

817-
// With no-nans: X * 0.0 --> copysign(0.0, X)
818-
if (I.hasNoNaNs() && match(Op1, m_PosZeroFP())) {
817+
// With no-nans/no-infs:
818+
// X * 0.0 --> copysign(0.0, X)
819+
// X * -0.0 --> copysign(0.0, -X)
820+
if ((match(Op1, m_CombineOr(m_PosZeroFP(), m_NegZeroFP()))) &&
821+
((I.hasNoInfs() &&
822+
isKnownNeverNaN(Op0, /*Depth=*/0, SQ.getWithInstruction(&I))) ||
823+
isKnownNeverNaN(&I, /*Depth=*/0, SQ.getWithInstruction(&I)))) {
824+
if (match(Op1, m_NegZeroFP()))
825+
Op0 = Builder.CreateFNegFMF(Op0, &I);
819826
CallInst *CopySign = Builder.CreateIntrinsic(Intrinsic::copysign,
820827
{I.getType()}, {Op1, Op0}, &I);
821828
return replaceInstUsesWith(I, CopySign);

llvm/test/Transforms/InstCombine/binop-itofp.ll

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,7 +1012,7 @@ define float @missed_nonzero_check_on_constant_for_si_fmul(i1 %c, i1 %.b, ptr %g
10121012
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i32 65529, i32 53264
10131013
; CHECK-NEXT: [[CONV_I:%.*]] = trunc i32 [[SEL]] to i16
10141014
; CHECK-NEXT: [[CONV1_I:%.*]] = sitofp i16 [[CONV_I]] to float
1015-
; CHECK-NEXT: [[MUL3_I_I:%.*]] = fmul float [[CONV1_I]], 0.000000e+00
1015+
; CHECK-NEXT: [[MUL3_I_I:%.*]] = call float @llvm.copysign.f32(float 0.000000e+00, float [[CONV1_I]])
10161016
; CHECK-NEXT: store i32 [[SEL]], ptr [[G_2345:%.*]], align 4
10171017
; CHECK-NEXT: ret float [[MUL3_I_I]]
10181018
;
@@ -1031,7 +1031,7 @@ define <2 x float> @missed_nonzero_check_on_constant_for_si_fmul_vec(i1 %c, i1 %
10311031
; CHECK-NEXT: [[CONV_I_V:%.*]] = insertelement <2 x i16> poison, i16 [[CONV_I_S]], i64 0
10321032
; CHECK-NEXT: [[CONV_I:%.*]] = shufflevector <2 x i16> [[CONV_I_V]], <2 x i16> poison, <2 x i32> zeroinitializer
10331033
; CHECK-NEXT: [[CONV1_I:%.*]] = sitofp <2 x i16> [[CONV_I]] to <2 x float>
1034-
; CHECK-NEXT: [[MUL3_I_I:%.*]] = fmul <2 x float> [[CONV1_I]], zeroinitializer
1034+
; CHECK-NEXT: [[MUL3_I_I:%.*]] = call <2 x float> @llvm.copysign.v2f32(<2 x float> zeroinitializer, <2 x float> [[CONV1_I]])
10351035
; CHECK-NEXT: store i32 [[SEL]], ptr [[G_2345:%.*]], align 4
10361036
; CHECK-NEXT: ret <2 x float> [[MUL3_I_I]]
10371037
;
@@ -1050,7 +1050,8 @@ define float @negzero_check_on_constant_for_si_fmul(i1 %c, i1 %.b, ptr %g_2345)
10501050
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i32 65529, i32 53264
10511051
; CHECK-NEXT: [[CONV_I:%.*]] = trunc i32 [[SEL]] to i16
10521052
; CHECK-NEXT: [[CONV1_I:%.*]] = sitofp i16 [[CONV_I]] to float
1053-
; CHECK-NEXT: [[MUL3_I_I:%.*]] = fmul float [[CONV1_I]], -0.000000e+00
1053+
; CHECK-NEXT: [[TMP1:%.*]] = fneg float [[CONV1_I]]
1054+
; CHECK-NEXT: [[MUL3_I_I:%.*]] = call float @llvm.copysign.f32(float -0.000000e+00, float [[TMP1]])
10541055
; CHECK-NEXT: store i32 [[SEL]], ptr [[G_2345:%.*]], align 4
10551056
; CHECK-NEXT: ret float [[MUL3_I_I]]
10561057
;
@@ -1069,7 +1070,7 @@ define <2 x float> @nonzero_check_on_constant_for_si_fmul_vec_w_undef(i1 %c, i1
10691070
; CHECK-NEXT: [[CONV_I_V:%.*]] = insertelement <2 x i16> poison, i16 [[CONV_I_S]], i64 0
10701071
; CHECK-NEXT: [[CONV_I:%.*]] = shufflevector <2 x i16> [[CONV_I_V]], <2 x i16> poison, <2 x i32> zeroinitializer
10711072
; CHECK-NEXT: [[CONV1_I:%.*]] = sitofp <2 x i16> [[CONV_I]] to <2 x float>
1072-
; CHECK-NEXT: [[MUL3_I_I:%.*]] = fmul <2 x float> [[CONV1_I]], <float undef, float 0.000000e+00>
1073+
; CHECK-NEXT: [[MUL3_I_I:%.*]] = call <2 x float> @llvm.copysign.v2f32(<2 x float> <float undef, float 0.000000e+00>, <2 x float> [[CONV1_I]])
10731074
; CHECK-NEXT: store i32 [[SEL]], ptr [[G_2345:%.*]], align 4
10741075
; CHECK-NEXT: ret <2 x float> [[MUL3_I_I]]
10751076
;
@@ -1111,7 +1112,8 @@ define <2 x float> @nonzero_check_on_constant_for_si_fmul_negz_vec_w_undef(i1 %c
11111112
; CHECK-NEXT: [[CONV_I_V:%.*]] = insertelement <2 x i16> poison, i16 [[CONV_I_S]], i64 0
11121113
; CHECK-NEXT: [[CONV_I:%.*]] = shufflevector <2 x i16> [[CONV_I_V]], <2 x i16> poison, <2 x i32> zeroinitializer
11131114
; CHECK-NEXT: [[CONV1_I:%.*]] = sitofp <2 x i16> [[CONV_I]] to <2 x float>
1114-
; CHECK-NEXT: [[MUL3_I_I:%.*]] = fmul <2 x float> [[CONV1_I]], <float undef, float -0.000000e+00>
1115+
; CHECK-NEXT: [[TMP1:%.*]] = fneg <2 x float> [[CONV1_I]]
1116+
; CHECK-NEXT: [[MUL3_I_I:%.*]] = call <2 x float> @llvm.copysign.v2f32(<2 x float> <float undef, float -0.000000e+00>, <2 x float> [[TMP1]])
11151117
; CHECK-NEXT: store i32 [[SEL]], ptr [[G_2345:%.*]], align 4
11161118
; CHECK-NEXT: ret <2 x float> [[MUL3_I_I]]
11171119
;

llvm/test/Transforms/InstCombine/fmul.ll

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,11 +1268,10 @@ define half @mul_zero(half %x) {
12681268
ret half %r
12691269
}
12701270

1271-
; TODO: This could be fneg+copysign.
1272-
12731271
define half @mul_negzero_nnan(half %x) {
12741272
; CHECK-LABEL: @mul_negzero_nnan(
1275-
; CHECK-NEXT: [[R:%.*]] = fmul nnan half [[X:%.*]], 0xH8000
1273+
; CHECK-NEXT: [[TMP1:%.*]] = fneg nnan half [[X:%.*]]
1274+
; CHECK-NEXT: [[R:%.*]] = call nnan half @llvm.copysign.f16(half 0xH8000, half [[TMP1]])
12761275
; CHECK-NEXT: ret half [[R]]
12771276
;
12781277
%r = fmul nnan half %x, -0.0
@@ -1282,7 +1281,7 @@ define half @mul_negzero_nnan(half %x) {
12821281
define float @mul_pos_zero_nnan_ninf(float nofpclass(inf nan) %a) {
12831282
; CHECK-LABEL: @mul_pos_zero_nnan_ninf(
12841283
; CHECK-NEXT: entry:
1285-
; CHECK-NEXT: [[RET:%.*]] = fmul float [[A:%.*]], 0.000000e+00
1284+
; CHECK-NEXT: [[RET:%.*]] = call float @llvm.copysign.f32(float 0.000000e+00, float [[A:%.*]])
12861285
; CHECK-NEXT: ret float [[RET]]
12871286
;
12881287
entry:
@@ -1304,7 +1303,7 @@ entry:
13041303
define float @mul_pos_zero_nnan_ninf_fmf(float nofpclass(nan) %a) {
13051304
; CHECK-LABEL: @mul_pos_zero_nnan_ninf_fmf(
13061305
; CHECK-NEXT: entry:
1307-
; CHECK-NEXT: [[RET:%.*]] = fmul ninf float [[A:%.*]], 0.000000e+00
1306+
; CHECK-NEXT: [[RET:%.*]] = call ninf float @llvm.copysign.f32(float 0.000000e+00, float [[A:%.*]])
13081307
; CHECK-NEXT: ret float [[RET]]
13091308
;
13101309
entry:
@@ -1315,7 +1314,8 @@ entry:
13151314
define float @mul_neg_zero_nnan_ninf(float nofpclass(inf nan) %a) {
13161315
; CHECK-LABEL: @mul_neg_zero_nnan_ninf(
13171316
; CHECK-NEXT: entry:
1318-
; CHECK-NEXT: [[RET:%.*]] = fmul float [[A:%.*]], -0.000000e+00
1317+
; CHECK-NEXT: [[TMP0:%.*]] = fneg float [[A:%.*]]
1318+
; CHECK-NEXT: [[RET:%.*]] = call float @llvm.copysign.f32(float -0.000000e+00, float [[TMP0]])
13191319
; CHECK-NEXT: ret float [[RET]]
13201320
;
13211321
entry:
@@ -1326,7 +1326,8 @@ entry:
13261326
define float @mul_neg_zero_nnan_fmf(float %a) {
13271327
; CHECK-LABEL: @mul_neg_zero_nnan_fmf(
13281328
; CHECK-NEXT: entry:
1329-
; CHECK-NEXT: [[RET:%.*]] = fmul nnan float [[A:%.*]], -0.000000e+00
1329+
; CHECK-NEXT: [[TMP0:%.*]] = fneg nnan float [[A:%.*]]
1330+
; CHECK-NEXT: [[RET:%.*]] = call nnan float @llvm.copysign.f32(float -0.000000e+00, float [[TMP0]])
13301331
; CHECK-NEXT: ret float [[RET]]
13311332
;
13321333
entry:
@@ -1337,7 +1338,8 @@ entry:
13371338
define float @mul_neg_zero_nnan_ninf_fmf(float nofpclass(inf nan) %a) {
13381339
; CHECK-LABEL: @mul_neg_zero_nnan_ninf_fmf(
13391340
; CHECK-NEXT: entry:
1340-
; CHECK-NEXT: [[RET:%.*]] = fmul nnan ninf float [[A:%.*]], -0.000000e+00
1341+
; CHECK-NEXT: [[TMP0:%.*]] = fneg nnan ninf float [[A:%.*]]
1342+
; CHECK-NEXT: [[RET:%.*]] = call nnan ninf float @llvm.copysign.f32(float -0.000000e+00, float [[TMP0]])
13411343
; CHECK-NEXT: ret float [[RET]]
13421344
;
13431345
entry:
@@ -1350,7 +1352,8 @@ entry:
13501352
define <2 x float> @mul_neg_zero_nnan_ninf_vec(<2 x float> nofpclass(inf nan) %a) {
13511353
; CHECK-LABEL: @mul_neg_zero_nnan_ninf_vec(
13521354
; CHECK-NEXT: entry:
1353-
; CHECK-NEXT: [[RET:%.*]] = fmul <2 x float> [[A:%.*]], <float -0.000000e+00, float poison>
1355+
; CHECK-NEXT: [[TMP0:%.*]] = fneg <2 x float> [[A:%.*]]
1356+
; CHECK-NEXT: [[RET:%.*]] = call <2 x float> @llvm.copysign.v2f32(<2 x float> <float -0.000000e+00, float poison>, <2 x float> [[TMP0]])
13541357
; CHECK-NEXT: ret <2 x float> [[RET]]
13551358
;
13561359
entry:

llvm/test/Transforms/InstCombine/fpcast.ll

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -424,10 +424,7 @@ define i32 @fptosi_select(i1 %cond) {
424424
define i32 @mul_pos_zero_convert(i32 %a) {
425425
; CHECK-LABEL: @mul_pos_zero_convert(
426426
; CHECK-NEXT: entry:
427-
; CHECK-NEXT: [[FP:%.*]] = sitofp i32 [[A:%.*]] to float
428-
; CHECK-NEXT: [[RET:%.*]] = fmul float [[FP]], 0.000000e+00
429-
; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[RET]] to i32
430-
; CHECK-NEXT: ret i32 [[CONV]]
427+
; CHECK-NEXT: ret i32 0
431428
;
432429
entry:
433430
%fp = sitofp i32 %a to float

0 commit comments

Comments
 (0)