[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
This commit is contained in:
parent
6db02dc431
commit
07286b1fcd
@ -6793,6 +6793,9 @@ static Value *simplifyIntrinsic(CallBase *Call, Value *Callee,
|
||||
Function *F = cast<Function>(Callee);
|
||||
Intrinsic::ID IID = F->getIntrinsicID();
|
||||
|
||||
if (IID != Intrinsic::not_intrinsic && intrinsicPropagatesPoison(IID) &&
|
||||
any_of(Args, IsaPred<PoisonValue>))
|
||||
return PoisonValue::get(F->getReturnType());
|
||||
// Most of the intrinsics with no operands have some kind of side effect.
|
||||
// Don't simplify.
|
||||
if (!NumOperands) {
|
||||
|
||||
@ -7912,6 +7912,8 @@ bool llvm::intrinsicPropagatesPoison(Intrinsic::ID IID) {
|
||||
case Intrinsic::ushl_sat:
|
||||
case Intrinsic::smul_fix:
|
||||
case Intrinsic::smul_fix_sat:
|
||||
case Intrinsic::pow:
|
||||
case Intrinsic::powi:
|
||||
case Intrinsic::canonicalize:
|
||||
case Intrinsic::sqrt:
|
||||
return true;
|
||||
|
||||
@ -36,7 +36,7 @@ define {i8, i1} @test_uadd3(i8 %v) {
|
||||
|
||||
define {i8, i1} @test_uadd3_poison(i8 %v) {
|
||||
; CHECK-LABEL: @test_uadd3_poison(
|
||||
; CHECK-NEXT: ret { i8, i1 } { i8 -1, i1 false }
|
||||
; CHECK-NEXT: ret { i8, i1 } poison
|
||||
;
|
||||
%result = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %v, i8 poison)
|
||||
ret {i8, i1} %result
|
||||
@ -52,7 +52,7 @@ define {i8, i1} @test_uadd4(i8 %v) {
|
||||
|
||||
define {i8, i1} @test_uadd4_poison(i8 %v) {
|
||||
; CHECK-LABEL: @test_uadd4_poison(
|
||||
; CHECK-NEXT: ret { i8, i1 } { i8 -1, i1 false }
|
||||
; CHECK-NEXT: ret { i8, i1 } poison
|
||||
;
|
||||
%result = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 poison, i8 %v)
|
||||
ret {i8, i1} %result
|
||||
@ -86,7 +86,7 @@ define {i8, i1} @test_sadd3(i8 %v) {
|
||||
|
||||
define {i8, i1} @test_sadd3_poison(i8 %v) {
|
||||
; CHECK-LABEL: @test_sadd3_poison(
|
||||
; CHECK-NEXT: ret { i8, i1 } { i8 -1, i1 false }
|
||||
; CHECK-NEXT: ret { i8, i1 } poison
|
||||
;
|
||||
%result = call {i8, i1} @llvm.sadd.with.overflow.i8(i8 %v, i8 poison)
|
||||
ret {i8, i1} %result
|
||||
@ -102,7 +102,7 @@ define {i8, i1} @test_sadd4(i8 %v) {
|
||||
|
||||
define {i8, i1} @test_sadd4_poison(i8 %v) {
|
||||
; CHECK-LABEL: @test_sadd4_poison(
|
||||
; CHECK-NEXT: ret { i8, i1 } { i8 -1, i1 false }
|
||||
; CHECK-NEXT: ret { i8, i1 } poison
|
||||
;
|
||||
%result = call {i8, i1} @llvm.sadd.with.overflow.i8(i8 poison, i8 %v)
|
||||
ret {i8, i1} %result
|
||||
@ -126,7 +126,7 @@ define {i8, i1} @test_usub2(i8 %V) {
|
||||
|
||||
define {i8, i1} @test_usub2_poison(i8 %V) {
|
||||
; CHECK-LABEL: @test_usub2_poison(
|
||||
; CHECK-NEXT: ret { i8, i1 } zeroinitializer
|
||||
; CHECK-NEXT: ret { i8, i1 } poison
|
||||
;
|
||||
%x = call {i8, i1} @llvm.usub.with.overflow.i8(i8 %V, i8 poison)
|
||||
ret {i8, i1} %x
|
||||
@ -142,7 +142,7 @@ define {i8, i1} @test_usub3(i8 %V) {
|
||||
|
||||
define {i8, i1} @test_usub3_poison(i8 %V) {
|
||||
; CHECK-LABEL: @test_usub3_poison(
|
||||
; CHECK-NEXT: ret { i8, i1 } zeroinitializer
|
||||
; CHECK-NEXT: ret { i8, i1 } poison
|
||||
;
|
||||
%x = call {i8, i1} @llvm.usub.with.overflow.i8(i8 poison, i8 %V)
|
||||
ret {i8, i1} %x
|
||||
@ -166,7 +166,7 @@ define {i8, i1} @test_ssub2(i8 %V) {
|
||||
|
||||
define {i8, i1} @test_ssub2_poison(i8 %V) {
|
||||
; CHECK-LABEL: @test_ssub2_poison(
|
||||
; CHECK-NEXT: ret { i8, i1 } zeroinitializer
|
||||
; CHECK-NEXT: ret { i8, i1 } poison
|
||||
;
|
||||
%x = call {i8, i1} @llvm.ssub.with.overflow.i8(i8 %V, i8 poison)
|
||||
ret {i8, i1} %x
|
||||
@ -182,7 +182,7 @@ define {i8, i1} @test_ssub3(i8 %V) {
|
||||
|
||||
define {i8, i1} @test_ssub3_poison(i8 %V) {
|
||||
; CHECK-LABEL: @test_ssub3_poison(
|
||||
; CHECK-NEXT: ret { i8, i1 } zeroinitializer
|
||||
; CHECK-NEXT: ret { i8, i1 } poison
|
||||
;
|
||||
%x = call {i8, i1} @llvm.ssub.with.overflow.i8(i8 poison, i8 %V)
|
||||
ret {i8, i1} %x
|
||||
@ -206,7 +206,7 @@ define {i8, i1} @test_umul2(i8 %V) {
|
||||
|
||||
define {i8, i1} @test_umul2_poison(i8 %V) {
|
||||
; CHECK-LABEL: @test_umul2_poison(
|
||||
; CHECK-NEXT: ret { i8, i1 } zeroinitializer
|
||||
; CHECK-NEXT: ret { i8, i1 } poison
|
||||
;
|
||||
%x = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %V, i8 poison)
|
||||
ret {i8, i1} %x
|
||||
@ -230,7 +230,7 @@ define {i8, i1} @test_umul4(i8 %V) {
|
||||
|
||||
define {i8, i1} @test_umul4_poison(i8 %V) {
|
||||
; CHECK-LABEL: @test_umul4_poison(
|
||||
; CHECK-NEXT: ret { i8, i1 } zeroinitializer
|
||||
; CHECK-NEXT: ret { i8, i1 } poison
|
||||
;
|
||||
%x = call {i8, i1} @llvm.umul.with.overflow.i8(i8 poison, i8 %V)
|
||||
ret {i8, i1} %x
|
||||
@ -254,7 +254,7 @@ define {i8, i1} @test_smul2(i8 %V) {
|
||||
|
||||
define {i8, i1} @test_smul2_poison(i8 %V) {
|
||||
; CHECK-LABEL: @test_smul2_poison(
|
||||
; CHECK-NEXT: ret { i8, i1 } zeroinitializer
|
||||
; CHECK-NEXT: ret { i8, i1 } poison
|
||||
;
|
||||
%x = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %V, i8 poison)
|
||||
ret {i8, i1} %x
|
||||
@ -278,7 +278,7 @@ define {i8, i1} @test_smul4(i8 %V) {
|
||||
|
||||
define {i8, i1} @test_smul4_poison(i8 %V) {
|
||||
; CHECK-LABEL: @test_smul4_poison(
|
||||
; CHECK-NEXT: ret { i8, i1 } zeroinitializer
|
||||
; CHECK-NEXT: ret { i8, i1 } poison
|
||||
;
|
||||
%x = call {i8, i1} @llvm.smul.with.overflow.i8(i8 poison, i8 %V)
|
||||
ret {i8, i1} %x
|
||||
|
||||
@ -33,7 +33,7 @@ define void @powi(double %V, ptr%P) {
|
||||
define void @powi_i16(float %V, ptr%P) {
|
||||
; CHECK-LABEL: @powi_i16(
|
||||
; CHECK-NEXT: store volatile float 1.000000e+00, ptr [[P:%.*]], align 4
|
||||
; CHECK-NEXT: store volatile float [[V:%.*]], ptr [[P]], align 4
|
||||
; CHECK-NEXT: store volatile float [[D:%.*]], ptr [[P]], align 4
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%B = tail call float @llvm.powi.f32.i16(float %V, i16 0) nounwind
|
||||
@ -52,3 +52,38 @@ define i32 @test_ctpop_poison(i32 %a) {
|
||||
%res = tail call i32 @llvm.ctpop.i32(i32 poison)
|
||||
ret i32 %res
|
||||
}
|
||||
|
||||
define void @pow_poison(i16 %arg_int,float %arg_flt, ptr %P) {
|
||||
; CHECK-LABEL: @pow_poison(
|
||||
; CHECK-NEXT: store volatile float poison, ptr [[P:%.*]], align 4
|
||||
; CHECK-NEXT: store volatile float poison, ptr [[P]], align 4
|
||||
; CHECK-NEXT: store volatile float poison, ptr [[P]], align 4
|
||||
; CHECK-NEXT: store volatile float poison, ptr [[P]], align 4
|
||||
; CHECK-NEXT: store volatile float poison, ptr [[P]], align 4
|
||||
; CHECK-NEXT: store volatile float poison, ptr [[P]], align 4
|
||||
; CHECK-NEXT: store volatile <2 x float> poison, ptr [[P]], align 8
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%2 = tail call float @llvm.powi(float poison, i16 %arg_int) nounwind
|
||||
store volatile float %2, ptr %P
|
||||
|
||||
%3 = tail call float @llvm.pow(float poison, float %arg_flt) nounwind
|
||||
store volatile float %3, ptr %P
|
||||
|
||||
%4 = tail call float @llvm.powi(float %arg_flt, i16 poison) nounwind
|
||||
store volatile float %4, ptr %P
|
||||
|
||||
%5 = tail call float @llvm.pow(float %arg_flt, float poison) nounwind
|
||||
store volatile float %5, ptr %P
|
||||
|
||||
%6 = tail call float @llvm.powi(float poison, i16 poison) nounwind
|
||||
store volatile float %6, ptr %P
|
||||
|
||||
%7 = tail call float @llvm.pow(float poison, float poison) nounwind
|
||||
store volatile float %7, ptr %P
|
||||
|
||||
%8 = tail call <2 x float> @llvm.pow(<2 x float> poison, <2 x float> poison) nounwind
|
||||
store volatile <2 x float> %8, ptr %P
|
||||
|
||||
ret void
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@ define i8 @uadd_scalar_undef(i8 %a) {
|
||||
|
||||
define i8 @uadd_scalar_poison(i8 %a) {
|
||||
; CHECK-LABEL: @uadd_scalar_poison(
|
||||
; CHECK-NEXT: ret i8 -1
|
||||
; CHECK-NEXT: ret i8 poison
|
||||
;
|
||||
%x5 = call i8 @llvm.uadd.sat.i8(i8 %a, i8 poison)
|
||||
ret i8 %x5
|
||||
@ -106,7 +106,7 @@ define <2 x i8> @uadd_vector_undef(<2 x i8> %a) {
|
||||
|
||||
define <2 x i8> @uadd_vector_poison(<2 x i8> %a) {
|
||||
; CHECK-LABEL: @uadd_vector_poison(
|
||||
; CHECK-NEXT: ret <2 x i8> splat (i8 -1)
|
||||
; CHECK-NEXT: ret <2 x i8> poison
|
||||
;
|
||||
%x5v = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 poison, i8 poison>)
|
||||
ret <2 x i8> %x5v
|
||||
@ -122,7 +122,7 @@ define i8 @uadd_scalar_undef_commute(i8 %a) {
|
||||
|
||||
define i8 @uadd_scalar_poison_commute(i8 %a) {
|
||||
; CHECK-LABEL: @uadd_scalar_poison_commute(
|
||||
; CHECK-NEXT: ret i8 -1
|
||||
; CHECK-NEXT: ret i8 poison
|
||||
;
|
||||
%x6 = call i8 @llvm.uadd.sat.i8(i8 poison, i8 %a)
|
||||
ret i8 %x6
|
||||
@ -138,7 +138,7 @@ define <2 x i8> @uadd_vector_undef_commute(<2 x i8> %a) {
|
||||
|
||||
define <2 x i8> @uadd_vector_poison_commute(<2 x i8> %a) {
|
||||
; CHECK-LABEL: @uadd_vector_poison_commute(
|
||||
; CHECK-NEXT: ret <2 x i8> splat (i8 -1)
|
||||
; CHECK-NEXT: ret <2 x i8> poison
|
||||
;
|
||||
%x5v = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> poison, <2 x i8> %a)
|
||||
ret <2 x i8> %x5v
|
||||
@ -222,7 +222,7 @@ define i8 @sadd_scalar_undef(i8 %a) {
|
||||
|
||||
define i8 @sadd_scalar_poison(i8 %a) {
|
||||
; CHECK-LABEL: @sadd_scalar_poison(
|
||||
; CHECK-NEXT: ret i8 -1
|
||||
; CHECK-NEXT: ret i8 poison
|
||||
;
|
||||
%y5 = call i8 @llvm.sadd.sat.i8(i8 %a, i8 poison)
|
||||
ret i8 %y5
|
||||
@ -238,7 +238,7 @@ define <2 x i8> @sadd_vector_undef(<2 x i8> %a) {
|
||||
|
||||
define <2 x i8> @sadd_vector_poison(<2 x i8> %a) {
|
||||
; CHECK-LABEL: @sadd_vector_poison(
|
||||
; CHECK-NEXT: ret <2 x i8> splat (i8 -1)
|
||||
; CHECK-NEXT: ret <2 x i8> poison
|
||||
;
|
||||
%y5v = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> %a, <2 x i8> poison)
|
||||
ret <2 x i8> %y5v
|
||||
@ -254,7 +254,7 @@ define i8 @sadd_scalar_undef_commute(i8 %a) {
|
||||
|
||||
define i8 @sadd_scalar_poison_commute(i8 %a) {
|
||||
; CHECK-LABEL: @sadd_scalar_poison_commute(
|
||||
; CHECK-NEXT: ret i8 -1
|
||||
; CHECK-NEXT: ret i8 poison
|
||||
;
|
||||
%y6 = call i8 @llvm.sadd.sat.i8(i8 poison, i8 %a)
|
||||
ret i8 %y6
|
||||
@ -270,7 +270,7 @@ define <2 x i8> @sadd_vector_undef_commute(<2 x i8> %a) {
|
||||
|
||||
define <2 x i8> @sadd_vector_poison_commute(<2 x i8> %a) {
|
||||
; CHECK-LABEL: @sadd_vector_poison_commute(
|
||||
; CHECK-NEXT: ret <2 x i8> splat (i8 -1)
|
||||
; CHECK-NEXT: ret <2 x i8> poison
|
||||
;
|
||||
%y6v = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> poison, <2 x i8> %a)
|
||||
ret <2 x i8> %y6v
|
||||
@ -334,7 +334,7 @@ define i8 @usub_scalar_undef(i8 %a) {
|
||||
|
||||
define i8 @usub_scalar_poison(i8 %a) {
|
||||
; CHECK-LABEL: @usub_scalar_poison(
|
||||
; CHECK-NEXT: ret i8 0
|
||||
; CHECK-NEXT: ret i8 poison
|
||||
;
|
||||
%x4 = call i8 @llvm.usub.sat.i8(i8 %a, i8 poison)
|
||||
ret i8 %x4
|
||||
@ -350,7 +350,7 @@ define <2 x i8> @usub_vector_undef(<2 x i8> %a) {
|
||||
|
||||
define <2 x i8> @usub_vector_poison(<2 x i8> %a) {
|
||||
; CHECK-LABEL: @usub_vector_poison(
|
||||
; CHECK-NEXT: ret <2 x i8> zeroinitializer
|
||||
; CHECK-NEXT: ret <2 x i8> poison
|
||||
;
|
||||
%x4v = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 poison, i8 poison>)
|
||||
ret <2 x i8> %x4v
|
||||
@ -366,7 +366,7 @@ define i8 @usub_scalar_undef_commute(i8 %a) {
|
||||
|
||||
define i8 @usub_scalar_poison_commute(i8 %a) {
|
||||
; CHECK-LABEL: @usub_scalar_poison_commute(
|
||||
; CHECK-NEXT: ret i8 0
|
||||
; CHECK-NEXT: ret i8 poison
|
||||
;
|
||||
%x5 = call i8 @llvm.usub.sat.i8(i8 poison, i8 %a)
|
||||
ret i8 %x5
|
||||
@ -382,7 +382,7 @@ define <2 x i8> @usub_vector_undef_commute(<2 x i8> %a) {
|
||||
|
||||
define <2 x i8> @usub_vector_poison_commute(<2 x i8> %a) {
|
||||
; CHECK-LABEL: @usub_vector_poison_commute(
|
||||
; CHECK-NEXT: ret <2 x i8> zeroinitializer
|
||||
; CHECK-NEXT: ret <2 x i8> poison
|
||||
;
|
||||
%x5v = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> <i8 poison, i8 poison>, <2 x i8> %a)
|
||||
ret <2 x i8> %x5v
|
||||
@ -466,7 +466,7 @@ define i8 @ssub_scalar_undef(i8 %a) {
|
||||
|
||||
define i8 @ssub_scalar_poison(i8 %a) {
|
||||
; CHECK-LABEL: @ssub_scalar_poison(
|
||||
; CHECK-NEXT: ret i8 0
|
||||
; CHECK-NEXT: ret i8 poison
|
||||
;
|
||||
%y4 = call i8 @llvm.ssub.sat.i8(i8 %a, i8 poison)
|
||||
ret i8 %y4
|
||||
@ -482,7 +482,7 @@ define <2 x i8> @ssub_vector_undef(<2 x i8> %a) {
|
||||
|
||||
define <2 x i8> @ssub_vector_poison(<2 x i8> %a) {
|
||||
; CHECK-LABEL: @ssub_vector_poison(
|
||||
; CHECK-NEXT: ret <2 x i8> zeroinitializer
|
||||
; CHECK-NEXT: ret <2 x i8> poison
|
||||
;
|
||||
%y4v = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %a, <2 x i8> poison)
|
||||
ret <2 x i8> %y4v
|
||||
@ -498,7 +498,7 @@ define i8 @ssub_scalar_undef_commute(i8 %a) {
|
||||
|
||||
define i8 @ssub_scalar_poison_commute(i8 %a) {
|
||||
; CHECK-LABEL: @ssub_scalar_poison_commute(
|
||||
; CHECK-NEXT: ret i8 0
|
||||
; CHECK-NEXT: ret i8 poison
|
||||
;
|
||||
%y5 = call i8 @llvm.ssub.sat.i8(i8 poison, i8 %a)
|
||||
ret i8 %y5
|
||||
@ -514,7 +514,7 @@ define <2 x i8> @ssub_vector_undef_commute(<2 x i8> %a) {
|
||||
|
||||
define <2 x i8> @ssub_vector_poison_commute(<2 x i8> %a) {
|
||||
; CHECK-LABEL: @ssub_vector_poison_commute(
|
||||
; CHECK-NEXT: ret <2 x i8> zeroinitializer
|
||||
; CHECK-NEXT: ret <2 x i8> poison
|
||||
;
|
||||
%y5v = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> <i8 poison, i8 poison>, <2 x i8> %a)
|
||||
ret <2 x i8> %y5v
|
||||
|
||||
@ -911,10 +911,10 @@ TEST(ValueTracking, propagatesPoison) {
|
||||
{false, "call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 %shamt)", 1},
|
||||
{false, "call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 %shamt)", 2},
|
||||
{true, "call float @llvm.sqrt.f32(float %fx)", 0},
|
||||
{false, "call float @llvm.powi.f32.i32(float %fx, i32 %x)", 0},
|
||||
{true, "call float @llvm.powi.f32.i32(float %fx, i32 %x)", 0},
|
||||
{false, "call float @llvm.sin.f32(float %fx)", 0},
|
||||
{false, "call float @llvm.cos.f32(float %fx)", 0},
|
||||
{false, "call float @llvm.pow.f32(float %fx, float %fy)", 0},
|
||||
{true, "call float @llvm.pow.f32(float %fx, float %fy)", 0},
|
||||
{false, "call float @llvm.exp.f32(float %fx)", 0},
|
||||
{false, "call float @llvm.exp2.f32(float %fx)", 0},
|
||||
{false, "call float @llvm.log.f32(float %fx)", 0},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user