Skip to content

Commit 07286b1

Browse files
authored
[InstCombine] Propagate poison pow[i], [us]add, [us]sub and [us]mul (#146750)
Fixes #146560 as well as propagate poison for [us]add, [us]sub and [us]mul
1 parent 6db02dc commit 07286b1

File tree

6 files changed

+71
-31
lines changed

6 files changed

+71
-31
lines changed

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6793,6 +6793,9 @@ static Value *simplifyIntrinsic(CallBase *Call, Value *Callee,
67936793
Function *F = cast<Function>(Callee);
67946794
Intrinsic::ID IID = F->getIntrinsicID();
67956795

6796+
if (IID != Intrinsic::not_intrinsic && intrinsicPropagatesPoison(IID) &&
6797+
any_of(Args, IsaPred<PoisonValue>))
6798+
return PoisonValue::get(F->getReturnType());
67966799
// Most of the intrinsics with no operands have some kind of side effect.
67976800
// Don't simplify.
67986801
if (!NumOperands) {

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7912,6 +7912,8 @@ bool llvm::intrinsicPropagatesPoison(Intrinsic::ID IID) {
79127912
case Intrinsic::ushl_sat:
79137913
case Intrinsic::smul_fix:
79147914
case Intrinsic::smul_fix_sat:
7915+
case Intrinsic::pow:
7916+
case Intrinsic::powi:
79157917
case Intrinsic::canonicalize:
79167918
case Intrinsic::sqrt:
79177919
return true;

llvm/test/Transforms/InstSimplify/call.ll

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ define {i8, i1} @test_uadd3(i8 %v) {
3636

3737
define {i8, i1} @test_uadd3_poison(i8 %v) {
3838
; CHECK-LABEL: @test_uadd3_poison(
39-
; CHECK-NEXT: ret { i8, i1 } { i8 -1, i1 false }
39+
; CHECK-NEXT: ret { i8, i1 } poison
4040
;
4141
%result = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %v, i8 poison)
4242
ret {i8, i1} %result
@@ -52,7 +52,7 @@ define {i8, i1} @test_uadd4(i8 %v) {
5252

5353
define {i8, i1} @test_uadd4_poison(i8 %v) {
5454
; CHECK-LABEL: @test_uadd4_poison(
55-
; CHECK-NEXT: ret { i8, i1 } { i8 -1, i1 false }
55+
; CHECK-NEXT: ret { i8, i1 } poison
5656
;
5757
%result = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 poison, i8 %v)
5858
ret {i8, i1} %result
@@ -86,7 +86,7 @@ define {i8, i1} @test_sadd3(i8 %v) {
8686

8787
define {i8, i1} @test_sadd3_poison(i8 %v) {
8888
; CHECK-LABEL: @test_sadd3_poison(
89-
; CHECK-NEXT: ret { i8, i1 } { i8 -1, i1 false }
89+
; CHECK-NEXT: ret { i8, i1 } poison
9090
;
9191
%result = call {i8, i1} @llvm.sadd.with.overflow.i8(i8 %v, i8 poison)
9292
ret {i8, i1} %result
@@ -102,7 +102,7 @@ define {i8, i1} @test_sadd4(i8 %v) {
102102

103103
define {i8, i1} @test_sadd4_poison(i8 %v) {
104104
; CHECK-LABEL: @test_sadd4_poison(
105-
; CHECK-NEXT: ret { i8, i1 } { i8 -1, i1 false }
105+
; CHECK-NEXT: ret { i8, i1 } poison
106106
;
107107
%result = call {i8, i1} @llvm.sadd.with.overflow.i8(i8 poison, i8 %v)
108108
ret {i8, i1} %result
@@ -126,7 +126,7 @@ define {i8, i1} @test_usub2(i8 %V) {
126126

127127
define {i8, i1} @test_usub2_poison(i8 %V) {
128128
; CHECK-LABEL: @test_usub2_poison(
129-
; CHECK-NEXT: ret { i8, i1 } zeroinitializer
129+
; CHECK-NEXT: ret { i8, i1 } poison
130130
;
131131
%x = call {i8, i1} @llvm.usub.with.overflow.i8(i8 %V, i8 poison)
132132
ret {i8, i1} %x
@@ -142,7 +142,7 @@ define {i8, i1} @test_usub3(i8 %V) {
142142

143143
define {i8, i1} @test_usub3_poison(i8 %V) {
144144
; CHECK-LABEL: @test_usub3_poison(
145-
; CHECK-NEXT: ret { i8, i1 } zeroinitializer
145+
; CHECK-NEXT: ret { i8, i1 } poison
146146
;
147147
%x = call {i8, i1} @llvm.usub.with.overflow.i8(i8 poison, i8 %V)
148148
ret {i8, i1} %x
@@ -166,7 +166,7 @@ define {i8, i1} @test_ssub2(i8 %V) {
166166

167167
define {i8, i1} @test_ssub2_poison(i8 %V) {
168168
; CHECK-LABEL: @test_ssub2_poison(
169-
; CHECK-NEXT: ret { i8, i1 } zeroinitializer
169+
; CHECK-NEXT: ret { i8, i1 } poison
170170
;
171171
%x = call {i8, i1} @llvm.ssub.with.overflow.i8(i8 %V, i8 poison)
172172
ret {i8, i1} %x
@@ -182,7 +182,7 @@ define {i8, i1} @test_ssub3(i8 %V) {
182182

183183
define {i8, i1} @test_ssub3_poison(i8 %V) {
184184
; CHECK-LABEL: @test_ssub3_poison(
185-
; CHECK-NEXT: ret { i8, i1 } zeroinitializer
185+
; CHECK-NEXT: ret { i8, i1 } poison
186186
;
187187
%x = call {i8, i1} @llvm.ssub.with.overflow.i8(i8 poison, i8 %V)
188188
ret {i8, i1} %x
@@ -206,7 +206,7 @@ define {i8, i1} @test_umul2(i8 %V) {
206206

207207
define {i8, i1} @test_umul2_poison(i8 %V) {
208208
; CHECK-LABEL: @test_umul2_poison(
209-
; CHECK-NEXT: ret { i8, i1 } zeroinitializer
209+
; CHECK-NEXT: ret { i8, i1 } poison
210210
;
211211
%x = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %V, i8 poison)
212212
ret {i8, i1} %x
@@ -230,7 +230,7 @@ define {i8, i1} @test_umul4(i8 %V) {
230230

231231
define {i8, i1} @test_umul4_poison(i8 %V) {
232232
; CHECK-LABEL: @test_umul4_poison(
233-
; CHECK-NEXT: ret { i8, i1 } zeroinitializer
233+
; CHECK-NEXT: ret { i8, i1 } poison
234234
;
235235
%x = call {i8, i1} @llvm.umul.with.overflow.i8(i8 poison, i8 %V)
236236
ret {i8, i1} %x
@@ -254,7 +254,7 @@ define {i8, i1} @test_smul2(i8 %V) {
254254

255255
define {i8, i1} @test_smul2_poison(i8 %V) {
256256
; CHECK-LABEL: @test_smul2_poison(
257-
; CHECK-NEXT: ret { i8, i1 } zeroinitializer
257+
; CHECK-NEXT: ret { i8, i1 } poison
258258
;
259259
%x = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %V, i8 poison)
260260
ret {i8, i1} %x
@@ -278,7 +278,7 @@ define {i8, i1} @test_smul4(i8 %V) {
278278

279279
define {i8, i1} @test_smul4_poison(i8 %V) {
280280
; CHECK-LABEL: @test_smul4_poison(
281-
; CHECK-NEXT: ret { i8, i1 } zeroinitializer
281+
; CHECK-NEXT: ret { i8, i1 } poison
282282
;
283283
%x = call {i8, i1} @llvm.smul.with.overflow.i8(i8 poison, i8 %V)
284284
ret {i8, i1} %x

llvm/test/Transforms/InstSimplify/fold-intrinsics.ll

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ define void @powi(double %V, ptr%P) {
3333
define void @powi_i16(float %V, ptr%P) {
3434
; CHECK-LABEL: @powi_i16(
3535
; CHECK-NEXT: store volatile float 1.000000e+00, ptr [[P:%.*]], align 4
36-
; CHECK-NEXT: store volatile float [[V:%.*]], ptr [[P]], align 4
36+
; CHECK-NEXT: store volatile float [[D:%.*]], ptr [[P]], align 4
3737
; CHECK-NEXT: ret void
3838
;
3939
%B = tail call float @llvm.powi.f32.i16(float %V, i16 0) nounwind
@@ -52,3 +52,38 @@ define i32 @test_ctpop_poison(i32 %a) {
5252
%res = tail call i32 @llvm.ctpop.i32(i32 poison)
5353
ret i32 %res
5454
}
55+
56+
define void @pow_poison(i16 %arg_int,float %arg_flt, ptr %P) {
57+
; CHECK-LABEL: @pow_poison(
58+
; CHECK-NEXT: store volatile float poison, ptr [[P:%.*]], align 4
59+
; CHECK-NEXT: store volatile float poison, ptr [[P]], align 4
60+
; CHECK-NEXT: store volatile float poison, ptr [[P]], align 4
61+
; CHECK-NEXT: store volatile float poison, ptr [[P]], align 4
62+
; CHECK-NEXT: store volatile float poison, ptr [[P]], align 4
63+
; CHECK-NEXT: store volatile float poison, ptr [[P]], align 4
64+
; CHECK-NEXT: store volatile <2 x float> poison, ptr [[P]], align 8
65+
; CHECK-NEXT: ret void
66+
;
67+
%2 = tail call float @llvm.powi(float poison, i16 %arg_int) nounwind
68+
store volatile float %2, ptr %P
69+
70+
%3 = tail call float @llvm.pow(float poison, float %arg_flt) nounwind
71+
store volatile float %3, ptr %P
72+
73+
%4 = tail call float @llvm.powi(float %arg_flt, i16 poison) nounwind
74+
store volatile float %4, ptr %P
75+
76+
%5 = tail call float @llvm.pow(float %arg_flt, float poison) nounwind
77+
store volatile float %5, ptr %P
78+
79+
%6 = tail call float @llvm.powi(float poison, i16 poison) nounwind
80+
store volatile float %6, ptr %P
81+
82+
%7 = tail call float @llvm.pow(float poison, float poison) nounwind
83+
store volatile float %7, ptr %P
84+
85+
%8 = tail call <2 x float> @llvm.pow(<2 x float> poison, <2 x float> poison) nounwind
86+
store volatile <2 x float> %8, ptr %P
87+
88+
ret void
89+
}

llvm/test/Transforms/InstSimplify/saturating-add-sub.ll

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ define i8 @uadd_scalar_undef(i8 %a) {
9090

9191
define i8 @uadd_scalar_poison(i8 %a) {
9292
; CHECK-LABEL: @uadd_scalar_poison(
93-
; CHECK-NEXT: ret i8 -1
93+
; CHECK-NEXT: ret i8 poison
9494
;
9595
%x5 = call i8 @llvm.uadd.sat.i8(i8 %a, i8 poison)
9696
ret i8 %x5
@@ -106,7 +106,7 @@ define <2 x i8> @uadd_vector_undef(<2 x i8> %a) {
106106

107107
define <2 x i8> @uadd_vector_poison(<2 x i8> %a) {
108108
; CHECK-LABEL: @uadd_vector_poison(
109-
; CHECK-NEXT: ret <2 x i8> splat (i8 -1)
109+
; CHECK-NEXT: ret <2 x i8> poison
110110
;
111111
%x5v = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 poison, i8 poison>)
112112
ret <2 x i8> %x5v
@@ -122,7 +122,7 @@ define i8 @uadd_scalar_undef_commute(i8 %a) {
122122

123123
define i8 @uadd_scalar_poison_commute(i8 %a) {
124124
; CHECK-LABEL: @uadd_scalar_poison_commute(
125-
; CHECK-NEXT: ret i8 -1
125+
; CHECK-NEXT: ret i8 poison
126126
;
127127
%x6 = call i8 @llvm.uadd.sat.i8(i8 poison, i8 %a)
128128
ret i8 %x6
@@ -138,7 +138,7 @@ define <2 x i8> @uadd_vector_undef_commute(<2 x i8> %a) {
138138

139139
define <2 x i8> @uadd_vector_poison_commute(<2 x i8> %a) {
140140
; CHECK-LABEL: @uadd_vector_poison_commute(
141-
; CHECK-NEXT: ret <2 x i8> splat (i8 -1)
141+
; CHECK-NEXT: ret <2 x i8> poison
142142
;
143143
%x5v = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> poison, <2 x i8> %a)
144144
ret <2 x i8> %x5v
@@ -222,7 +222,7 @@ define i8 @sadd_scalar_undef(i8 %a) {
222222

223223
define i8 @sadd_scalar_poison(i8 %a) {
224224
; CHECK-LABEL: @sadd_scalar_poison(
225-
; CHECK-NEXT: ret i8 -1
225+
; CHECK-NEXT: ret i8 poison
226226
;
227227
%y5 = call i8 @llvm.sadd.sat.i8(i8 %a, i8 poison)
228228
ret i8 %y5
@@ -238,7 +238,7 @@ define <2 x i8> @sadd_vector_undef(<2 x i8> %a) {
238238

239239
define <2 x i8> @sadd_vector_poison(<2 x i8> %a) {
240240
; CHECK-LABEL: @sadd_vector_poison(
241-
; CHECK-NEXT: ret <2 x i8> splat (i8 -1)
241+
; CHECK-NEXT: ret <2 x i8> poison
242242
;
243243
%y5v = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> %a, <2 x i8> poison)
244244
ret <2 x i8> %y5v
@@ -254,7 +254,7 @@ define i8 @sadd_scalar_undef_commute(i8 %a) {
254254

255255
define i8 @sadd_scalar_poison_commute(i8 %a) {
256256
; CHECK-LABEL: @sadd_scalar_poison_commute(
257-
; CHECK-NEXT: ret i8 -1
257+
; CHECK-NEXT: ret i8 poison
258258
;
259259
%y6 = call i8 @llvm.sadd.sat.i8(i8 poison, i8 %a)
260260
ret i8 %y6
@@ -270,7 +270,7 @@ define <2 x i8> @sadd_vector_undef_commute(<2 x i8> %a) {
270270

271271
define <2 x i8> @sadd_vector_poison_commute(<2 x i8> %a) {
272272
; CHECK-LABEL: @sadd_vector_poison_commute(
273-
; CHECK-NEXT: ret <2 x i8> splat (i8 -1)
273+
; CHECK-NEXT: ret <2 x i8> poison
274274
;
275275
%y6v = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> poison, <2 x i8> %a)
276276
ret <2 x i8> %y6v
@@ -334,7 +334,7 @@ define i8 @usub_scalar_undef(i8 %a) {
334334

335335
define i8 @usub_scalar_poison(i8 %a) {
336336
; CHECK-LABEL: @usub_scalar_poison(
337-
; CHECK-NEXT: ret i8 0
337+
; CHECK-NEXT: ret i8 poison
338338
;
339339
%x4 = call i8 @llvm.usub.sat.i8(i8 %a, i8 poison)
340340
ret i8 %x4
@@ -350,7 +350,7 @@ define <2 x i8> @usub_vector_undef(<2 x i8> %a) {
350350

351351
define <2 x i8> @usub_vector_poison(<2 x i8> %a) {
352352
; CHECK-LABEL: @usub_vector_poison(
353-
; CHECK-NEXT: ret <2 x i8> zeroinitializer
353+
; CHECK-NEXT: ret <2 x i8> poison
354354
;
355355
%x4v = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 poison, i8 poison>)
356356
ret <2 x i8> %x4v
@@ -366,7 +366,7 @@ define i8 @usub_scalar_undef_commute(i8 %a) {
366366

367367
define i8 @usub_scalar_poison_commute(i8 %a) {
368368
; CHECK-LABEL: @usub_scalar_poison_commute(
369-
; CHECK-NEXT: ret i8 0
369+
; CHECK-NEXT: ret i8 poison
370370
;
371371
%x5 = call i8 @llvm.usub.sat.i8(i8 poison, i8 %a)
372372
ret i8 %x5
@@ -382,7 +382,7 @@ define <2 x i8> @usub_vector_undef_commute(<2 x i8> %a) {
382382

383383
define <2 x i8> @usub_vector_poison_commute(<2 x i8> %a) {
384384
; CHECK-LABEL: @usub_vector_poison_commute(
385-
; CHECK-NEXT: ret <2 x i8> zeroinitializer
385+
; CHECK-NEXT: ret <2 x i8> poison
386386
;
387387
%x5v = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> <i8 poison, i8 poison>, <2 x i8> %a)
388388
ret <2 x i8> %x5v
@@ -466,7 +466,7 @@ define i8 @ssub_scalar_undef(i8 %a) {
466466

467467
define i8 @ssub_scalar_poison(i8 %a) {
468468
; CHECK-LABEL: @ssub_scalar_poison(
469-
; CHECK-NEXT: ret i8 0
469+
; CHECK-NEXT: ret i8 poison
470470
;
471471
%y4 = call i8 @llvm.ssub.sat.i8(i8 %a, i8 poison)
472472
ret i8 %y4
@@ -482,7 +482,7 @@ define <2 x i8> @ssub_vector_undef(<2 x i8> %a) {
482482

483483
define <2 x i8> @ssub_vector_poison(<2 x i8> %a) {
484484
; CHECK-LABEL: @ssub_vector_poison(
485-
; CHECK-NEXT: ret <2 x i8> zeroinitializer
485+
; CHECK-NEXT: ret <2 x i8> poison
486486
;
487487
%y4v = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %a, <2 x i8> poison)
488488
ret <2 x i8> %y4v
@@ -498,7 +498,7 @@ define i8 @ssub_scalar_undef_commute(i8 %a) {
498498

499499
define i8 @ssub_scalar_poison_commute(i8 %a) {
500500
; CHECK-LABEL: @ssub_scalar_poison_commute(
501-
; CHECK-NEXT: ret i8 0
501+
; CHECK-NEXT: ret i8 poison
502502
;
503503
%y5 = call i8 @llvm.ssub.sat.i8(i8 poison, i8 %a)
504504
ret i8 %y5
@@ -514,7 +514,7 @@ define <2 x i8> @ssub_vector_undef_commute(<2 x i8> %a) {
514514

515515
define <2 x i8> @ssub_vector_poison_commute(<2 x i8> %a) {
516516
; CHECK-LABEL: @ssub_vector_poison_commute(
517-
; CHECK-NEXT: ret <2 x i8> zeroinitializer
517+
; CHECK-NEXT: ret <2 x i8> poison
518518
;
519519
%y5v = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> <i8 poison, i8 poison>, <2 x i8> %a)
520520
ret <2 x i8> %y5v

llvm/unittests/Analysis/ValueTrackingTest.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -911,10 +911,10 @@ TEST(ValueTracking, propagatesPoison) {
911911
{false, "call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 %shamt)", 1},
912912
{false, "call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 %shamt)", 2},
913913
{true, "call float @llvm.sqrt.f32(float %fx)", 0},
914-
{false, "call float @llvm.powi.f32.i32(float %fx, i32 %x)", 0},
914+
{true, "call float @llvm.powi.f32.i32(float %fx, i32 %x)", 0},
915915
{false, "call float @llvm.sin.f32(float %fx)", 0},
916916
{false, "call float @llvm.cos.f32(float %fx)", 0},
917-
{false, "call float @llvm.pow.f32(float %fx, float %fy)", 0},
917+
{true, "call float @llvm.pow.f32(float %fx, float %fy)", 0},
918918
{false, "call float @llvm.exp.f32(float %fx)", 0},
919919
{false, "call float @llvm.exp2.f32(float %fx)", 0},
920920
{false, "call float @llvm.log.f32(float %fx)", 0},

0 commit comments

Comments
 (0)