[llvm] [InstCombine] Propagate poison pow[i] (PR #146750)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 4 12:42:42 PDT 2025


https://github.com/badumbatish updated https://github.com/llvm/llvm-project/pull/146750

>From 61d05be6093cd1b1581ae2de8b7052e7fd4ab8a4 Mon Sep 17 00:00:00 2001
From: badumbatish <--show-origin>
Date: Wed, 2 Jul 2025 09:34:48 -0700
Subject: [PATCH 1/8] Precommit missed opt for pow poison

---
 .../InstSimplify/fold-intrinsics.ll           | 38 ++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)

diff --git a/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll b/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
index b66d0c76d5ede..f42cf3b71a069 100644
--- a/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
+++ b/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
@@ -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,39 @@ define i32 @test_ctpop_poison(i32 %a) {
   %res = tail call i32 @llvm.ctpop.i32(i32 poison)
   ret i32 %res
 }
+
+define void @pow_poison_i16(i16 %arg_int,float %arg_flt, ptr %P) {
+; CHECK-LABEL: @pow_poison_i16(
+; CHECK-NEXT:    [[TMP1:%.*]] = tail call float @llvm.powi.f32.i16(float poison, i16 [[ARG_INT:%.*]]) #[[ATTR1:[0-9]+]]
+; CHECK-NEXT:    store volatile float [[TMP1]], ptr [[P:%.*]], align 4
+; CHECK-NEXT:    [[TMP2:%.*]] = tail call float @llvm.pow.f32(float poison, float [[ARG_FLT:%.*]]) #[[ATTR1]]
+; CHECK-NEXT:    store volatile float [[TMP2]], ptr [[P]], align 4
+; CHECK-NEXT:    [[TMP3:%.*]] = tail call float @llvm.powi.f32.i16(float [[ARG_FLT]], i16 poison) #[[ATTR1]]
+; CHECK-NEXT:    store volatile float [[TMP3]], ptr [[P]], align 4
+; CHECK-NEXT:    [[TMP4:%.*]] = tail call float @llvm.pow.f32(float [[ARG_FLT]], float poison) #[[ATTR1]]
+; CHECK-NEXT:    store volatile float [[TMP4]], ptr [[P]], align 4
+; CHECK-NEXT:    [[TMP5:%.*]] = tail call float @llvm.powi.f32.i16(float poison, i16 poison) #[[ATTR1]]
+; CHECK-NEXT:    store volatile float [[TMP5]], ptr [[P]], align 4
+; CHECK-NEXT:    [[TMP6:%.*]] = tail call float @llvm.pow.f32(float poison, float poison) #[[ATTR1]]
+; CHECK-NEXT:    store volatile float [[TMP6]], ptr [[P]], align 4
+; CHECK-NEXT:    ret void
+;
+  %2 = tail call float @llvm.powi.f32.i16(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.f32.i16(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.f32.i16(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
+  ret void
+}

>From a67e87e6fed0d48c394f382bd6ee16a8c8ca7d33 Mon Sep 17 00:00:00 2001
From: badumbatish <--show-origin>
Date: Wed, 2 Jul 2025 10:22:24 -0700
Subject: [PATCH 2/8] [InstCombine] Fold poison pow to poison

---
 llvm/lib/Analysis/InstructionSimplify.cpp      |  6 ++++++
 .../Transforms/InstSimplify/fold-intrinsics.ll | 18 ++++++------------
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index cb1dae92faf92..c7cbd627117da 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -6673,7 +6673,13 @@ Value *llvm::simplifyBinaryIntrinsic(Intrinsic::ID IID, Type *ReturnType,
       if (auto *C1 = dyn_cast<Constant>(Op1))
         return simplifyRelativeLoad(C0, C1, Q.DL);
     break;
+  case Intrinsic::pow:
+    if (isa<PoisonValue>(Op0) || isa<PoisonValue>(Op1))
+      return PoisonValue::get(ReturnType);
+    break;
   case Intrinsic::powi:
+    if (isa<PoisonValue>(Op0) || isa<PoisonValue>(Op1))
+      return PoisonValue::get(ReturnType);
     if (auto *Power = dyn_cast<ConstantInt>(Op1)) {
       // powi(x, 0) -> 1.0
       if (Power->isZero())
diff --git a/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll b/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
index f42cf3b71a069..cf0bf8c2d52a7 100644
--- a/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
+++ b/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
@@ -55,18 +55,12 @@ define i32 @test_ctpop_poison(i32 %a) {
 
 define void @pow_poison_i16(i16 %arg_int,float %arg_flt, ptr %P) {
 ; CHECK-LABEL: @pow_poison_i16(
-; CHECK-NEXT:    [[TMP1:%.*]] = tail call float @llvm.powi.f32.i16(float poison, i16 [[ARG_INT:%.*]]) #[[ATTR1:[0-9]+]]
-; CHECK-NEXT:    store volatile float [[TMP1]], ptr [[P:%.*]], align 4
-; CHECK-NEXT:    [[TMP2:%.*]] = tail call float @llvm.pow.f32(float poison, float [[ARG_FLT:%.*]]) #[[ATTR1]]
-; CHECK-NEXT:    store volatile float [[TMP2]], ptr [[P]], align 4
-; CHECK-NEXT:    [[TMP3:%.*]] = tail call float @llvm.powi.f32.i16(float [[ARG_FLT]], i16 poison) #[[ATTR1]]
-; CHECK-NEXT:    store volatile float [[TMP3]], ptr [[P]], align 4
-; CHECK-NEXT:    [[TMP4:%.*]] = tail call float @llvm.pow.f32(float [[ARG_FLT]], float poison) #[[ATTR1]]
-; CHECK-NEXT:    store volatile float [[TMP4]], ptr [[P]], align 4
-; CHECK-NEXT:    [[TMP5:%.*]] = tail call float @llvm.powi.f32.i16(float poison, i16 poison) #[[ATTR1]]
-; CHECK-NEXT:    store volatile float [[TMP5]], ptr [[P]], align 4
-; CHECK-NEXT:    [[TMP6:%.*]] = tail call float @llvm.pow.f32(float poison, float poison) #[[ATTR1]]
-; CHECK-NEXT:    store volatile float [[TMP6]], 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 float poison, ptr [[P]], align 4
 ; CHECK-NEXT:    ret void
 ;
   %2 = tail call float @llvm.powi.f32.i16(float poison, i16 %arg_int) nounwind

>From 1da97c9d48fc53d7e1245788091527fdb2a56eb9 Mon Sep 17 00:00:00 2001
From: badumbatish <--show-origin>
Date: Thu, 3 Jul 2025 11:08:30 -0700
Subject: [PATCH 3/8] Refactor support for pow[i] poison folding

Refactor support for pow[i] poison folding by rebasing on Nikic's
changes and implement the changes in InstructionSimplify.

Fix a few test case and added more Intrinsics to switch case in
ValueTracking.
---
 llvm/lib/Analysis/InstructionSimplify.cpp     |  3 ++
 llvm/lib/Analysis/ValueTracking.cpp           | 45 +++++++++++++++++++
 llvm/test/Transforms/InstSimplify/call.ll     | 24 +++++-----
 .../InstSimplify/saturating-add-sub.ll        | 32 ++++++-------
 4 files changed, 76 insertions(+), 28 deletions(-)

diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index c7cbd627117da..108bdf9e642e0 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -6799,6 +6799,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) {
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 2b7b1ee273992..5ee8e3f571da0 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -7911,7 +7911,52 @@ bool llvm::intrinsicPropagatesPoison(Intrinsic::ID IID) {
   case Intrinsic::usub_sat:
   case Intrinsic::ushl_sat:
   case Intrinsic::smul_fix:
+  // case Intrinsic::umul_fix:
+  // case Intrinsic::umul_fix_sat:
   case Intrinsic::smul_fix_sat:
+  // case Intrinsic::asin:
+  // case Intrinsic::acos:
+  // case Intrinsic::atan:
+  // case Intrinsic::atan2:
+  // case Intrinsic::sin:
+  // case Intrinsic::cos:
+  // case Intrinsic::sincos:
+  // case Intrinsic::sincospi:
+  // case Intrinsic::tan:
+  // case Intrinsic::sinh:
+  // case Intrinsic::cosh:
+  // case Intrinsic::tanh:
+  // case Intrinsic::exp:
+  // case Intrinsic::exp10:
+  // case Intrinsic::exp2:
+  // case Intrinsic::log:
+  // case Intrinsic::log10:
+  // case Intrinsic::log2:
+  // case Intrinsic::fabs:
+  // case Intrinsic::minnum:
+  // case Intrinsic::maxnum:
+  // case Intrinsic::minimum:
+  // case Intrinsic::maximum:
+  // case Intrinsic::minimumnum:
+  // case Intrinsic::maximumnum:
+  // case Intrinsic::modf:
+  // case Intrinsic::copysign:
+  // case Intrinsic::floor:
+  // case Intrinsic::ceil:
+  // case Intrinsic::trunc:
+  // case Intrinsic::rint:
+  // case Intrinsic::nearbyint:
+  // case Intrinsic::round:
+  // case Intrinsic::roundeven:
+  case Intrinsic::pow:
+  // case Intrinsic::fma:
+  // case Intrinsic::fmuladd:
+  // case Intrinsic::is_fpclass:
+  case Intrinsic::powi:
+  // case Intrinsic::fptosi_sat:
+  // case Intrinsic::fptoui_sat:
+  // case Intrinsic::lrint:
+  // case Intrinsic::llrint:
   case Intrinsic::canonicalize:
   case Intrinsic::sqrt:
     return true;
diff --git a/llvm/test/Transforms/InstSimplify/call.ll b/llvm/test/Transforms/InstSimplify/call.ll
index 910750adf9d42..de71af414c25d 100644
--- a/llvm/test/Transforms/InstSimplify/call.ll
+++ b/llvm/test/Transforms/InstSimplify/call.ll
@@ -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
diff --git a/llvm/test/Transforms/InstSimplify/saturating-add-sub.ll b/llvm/test/Transforms/InstSimplify/saturating-add-sub.ll
index 25a35062e60b8..ead4c01535163 100644
--- a/llvm/test/Transforms/InstSimplify/saturating-add-sub.ll
+++ b/llvm/test/Transforms/InstSimplify/saturating-add-sub.ll
@@ -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

>From 69771ea82ce3a8247bc76571b315156e6f6f0d85 Mon Sep 17 00:00:00 2001
From: badumbatish <--show-origin>
Date: Thu, 3 Jul 2025 11:39:13 -0700
Subject: [PATCH 4/8] Fix naming nits from PR

---
 llvm/test/Transforms/InstSimplify/fold-intrinsics.ll | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll b/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
index cf0bf8c2d52a7..e60ea3af31d62 100644
--- a/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
+++ b/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
@@ -53,8 +53,8 @@ define i32 @test_ctpop_poison(i32 %a) {
   ret i32 %res
 }
 
-define void @pow_poison_i16(i16 %arg_int,float %arg_flt, ptr %P) {
-; CHECK-LABEL: @pow_poison_i16(
+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
@@ -63,19 +63,19 @@ define void @pow_poison_i16(i16 %arg_int,float %arg_flt, ptr %P) {
 ; CHECK-NEXT:    store volatile float poison, ptr [[P]], align 4
 ; CHECK-NEXT:    ret void
 ;
-  %2 = tail call float @llvm.powi.f32.i16(float poison, i16 %arg_int) nounwind
+  %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.f32.i16(float %arg_flt, i16 poison) nounwind
+  %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.f32.i16(float poison, i16 poison) nounwind
+  %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

>From 251bfa3618733727819aa46985ab64b5df19b472 Mon Sep 17 00:00:00 2001
From: badumbatish <--show-origin>
Date: Thu, 3 Jul 2025 11:42:01 -0700
Subject: [PATCH 5/8] Remove old one off cse of poison folding

---
 llvm/lib/Analysis/InstructionSimplify.cpp | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 108bdf9e642e0..90baa054eed4c 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -6673,13 +6673,7 @@ Value *llvm::simplifyBinaryIntrinsic(Intrinsic::ID IID, Type *ReturnType,
       if (auto *C1 = dyn_cast<Constant>(Op1))
         return simplifyRelativeLoad(C0, C1, Q.DL);
     break;
-  case Intrinsic::pow:
-    if (isa<PoisonValue>(Op0) || isa<PoisonValue>(Op1))
-      return PoisonValue::get(ReturnType);
-    break;
   case Intrinsic::powi:
-    if (isa<PoisonValue>(Op0) || isa<PoisonValue>(Op1))
-      return PoisonValue::get(ReturnType);
     if (auto *Power = dyn_cast<ConstantInt>(Op1)) {
       // powi(x, 0) -> 1.0
       if (Power->isZero())

>From e08eb3f6855f5b43f34146eadd83a9682222624c Mon Sep 17 00:00:00 2001
From: badumbatish <--show-origin>
Date: Thu, 3 Jul 2025 11:56:27 -0700
Subject: [PATCH 6/8] Added vector support for pow[i] poison

---
 llvm/test/Transforms/InstSimplify/fold-intrinsics.ll | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll b/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
index e60ea3af31d62..8578aa9fa84b3 100644
--- a/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
+++ b/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
@@ -61,6 +61,7 @@ define void @pow_poison(i16 %arg_int,float %arg_flt, ptr %P) {
 ; 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
@@ -80,5 +81,9 @@ define void @pow_poison(i16 %arg_int,float %arg_flt, 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
 }

>From d2244eb151f732d29a97969177ba1e09a6436e8a Mon Sep 17 00:00:00 2001
From: badumbatish <--show-origin>
Date: Thu, 3 Jul 2025 14:51:58 -0700
Subject: [PATCH 7/8] Update unittest for pow[i] poison

---
 llvm/unittests/Analysis/ValueTrackingTest.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp
index e283591843748..7a48105a1dc99 100644
--- a/llvm/unittests/Analysis/ValueTrackingTest.cpp
+++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp
@@ -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},

>From 413adc0cfb99744d4a674a5edfec79c0bb98981d Mon Sep 17 00:00:00 2001
From: badumbatish <--show-origin>
Date: Fri, 4 Jul 2025 10:22:06 -0700
Subject: [PATCH 8/8] Remove case comments for intrinsics poison

---
 llvm/lib/Analysis/ValueTracking.cpp | 43 -----------------------------
 1 file changed, 43 deletions(-)

diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 5ee8e3f571da0..09745ed6eac6a 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -7911,52 +7911,9 @@ bool llvm::intrinsicPropagatesPoison(Intrinsic::ID IID) {
   case Intrinsic::usub_sat:
   case Intrinsic::ushl_sat:
   case Intrinsic::smul_fix:
-  // case Intrinsic::umul_fix:
-  // case Intrinsic::umul_fix_sat:
   case Intrinsic::smul_fix_sat:
-  // case Intrinsic::asin:
-  // case Intrinsic::acos:
-  // case Intrinsic::atan:
-  // case Intrinsic::atan2:
-  // case Intrinsic::sin:
-  // case Intrinsic::cos:
-  // case Intrinsic::sincos:
-  // case Intrinsic::sincospi:
-  // case Intrinsic::tan:
-  // case Intrinsic::sinh:
-  // case Intrinsic::cosh:
-  // case Intrinsic::tanh:
-  // case Intrinsic::exp:
-  // case Intrinsic::exp10:
-  // case Intrinsic::exp2:
-  // case Intrinsic::log:
-  // case Intrinsic::log10:
-  // case Intrinsic::log2:
-  // case Intrinsic::fabs:
-  // case Intrinsic::minnum:
-  // case Intrinsic::maxnum:
-  // case Intrinsic::minimum:
-  // case Intrinsic::maximum:
-  // case Intrinsic::minimumnum:
-  // case Intrinsic::maximumnum:
-  // case Intrinsic::modf:
-  // case Intrinsic::copysign:
-  // case Intrinsic::floor:
-  // case Intrinsic::ceil:
-  // case Intrinsic::trunc:
-  // case Intrinsic::rint:
-  // case Intrinsic::nearbyint:
-  // case Intrinsic::round:
-  // case Intrinsic::roundeven:
   case Intrinsic::pow:
-  // case Intrinsic::fma:
-  // case Intrinsic::fmuladd:
-  // case Intrinsic::is_fpclass:
   case Intrinsic::powi:
-  // case Intrinsic::fptosi_sat:
-  // case Intrinsic::fptoui_sat:
-  // case Intrinsic::lrint:
-  // case Intrinsic::llrint:
   case Intrinsic::canonicalize:
   case Intrinsic::sqrt:
     return true;



More information about the llvm-commits mailing list