aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ConstantFolding.cpp
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2025-07-04 09:16:28 +0200
committerGitHub <noreply@github.com>2025-07-04 09:16:28 +0200
commit1d5d1256487c1574e5a8addcf27983fd569966e5 (patch)
tree03f18119640464d423a78cfec310e70ed0eaa472 /llvm/lib/Analysis/ConstantFolding.cpp
parent25bf90eaede41156e45f974c772e320758cbb3c8 (diff)
downloadllvm-1d5d1256487c1574e5a8addcf27983fd569966e5.zip
llvm-1d5d1256487c1574e5a8addcf27983fd569966e5.tar.gz
llvm-1d5d1256487c1574e5a8addcf27983fd569966e5.tar.bz2
[ConstantFolding] Consolidate poison propagation for intrinsics (#146878)
This consolidates the "fold poison arg to poison result" constant folding logic for intrinsics, based on a common intrinsicPropagatesPoison() helper, which is also used for poison propagation reasoning in ValueTracking. This ensures that the set of supported intrinsics is consistent. This add ucmp, scmp, smul.fix, smul.fix.sat, canonicalize and sqrt to the intrinsicPropagatesPoison list, as these were handled by ConstantFolding but not ValueTracking. The ctpop test is an example of the converse, where it was handled by ValueTracking but not ConstantFolding.
Diffstat (limited to 'llvm/lib/Analysis/ConstantFolding.cpp')
-rw-r--r--llvm/lib/Analysis/ConstantFolding.cpp39
1 files changed, 5 insertions, 34 deletions
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 9e3c271..af955f2 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -2229,17 +2229,6 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
return nullptr;
}
- if (isa<PoisonValue>(Operands[0])) {
- // TODO: All of these operations should probably propagate poison.
- switch (IntrinsicID) {
- case Intrinsic::canonicalize:
- case Intrinsic::sqrt:
- return PoisonValue::get(Ty);
- default:
- break;
- }
- }
-
if (isa<UndefValue>(Operands[0])) {
// cosine(arg) is between -1 and 1. cosine(invalid arg) is NaN.
// ctpop() is between 0 and bitwidth, pick 0 for undef.
@@ -3228,11 +3217,6 @@ static Constant *ConstantFoldIntrinsicCall2(Intrinsic::ID IntrinsicID, Type *Ty,
case Intrinsic::smin:
case Intrinsic::umax:
case Intrinsic::umin:
- // This is the same as for binary ops - poison propagates.
- // TODO: Poison handling should be consolidated.
- if (isa<PoisonValue>(Operands[0]) || isa<PoisonValue>(Operands[1]))
- return PoisonValue::get(Ty);
-
if (!C0 && !C1)
return UndefValue::get(Ty);
if (!C0 || !C1)
@@ -3245,9 +3229,6 @@ static Constant *ConstantFoldIntrinsicCall2(Intrinsic::ID IntrinsicID, Type *Ty,
case Intrinsic::scmp:
case Intrinsic::ucmp:
- if (isa<PoisonValue>(Operands[0]) || isa<PoisonValue>(Operands[1]))
- return PoisonValue::get(Ty);
-
if (!C0 || !C1)
return ConstantInt::get(Ty, 0);
@@ -3314,11 +3295,6 @@ static Constant *ConstantFoldIntrinsicCall2(Intrinsic::ID IntrinsicID, Type *Ty,
}
case Intrinsic::uadd_sat:
case Intrinsic::sadd_sat:
- // This is the same as for binary ops - poison propagates.
- // TODO: Poison handling should be consolidated.
- if (isa<PoisonValue>(Operands[0]) || isa<PoisonValue>(Operands[1]))
- return PoisonValue::get(Ty);
-
if (!C0 && !C1)
return UndefValue::get(Ty);
if (!C0 || !C1)
@@ -3329,11 +3305,6 @@ static Constant *ConstantFoldIntrinsicCall2(Intrinsic::ID IntrinsicID, Type *Ty,
return ConstantInt::get(Ty, C0->sadd_sat(*C1));
case Intrinsic::usub_sat:
case Intrinsic::ssub_sat:
- // This is the same as for binary ops - poison propagates.
- // TODO: Poison handling should be consolidated.
- if (isa<PoisonValue>(Operands[0]) || isa<PoisonValue>(Operands[1]))
- return PoisonValue::get(Ty);
-
if (!C0 && !C1)
return UndefValue::get(Ty);
if (!C0 || !C1)
@@ -3592,11 +3563,6 @@ static Constant *ConstantFoldScalarCall3(StringRef Name,
if (IntrinsicID == Intrinsic::smul_fix ||
IntrinsicID == Intrinsic::smul_fix_sat) {
- // poison * C -> poison
- // C * poison -> poison
- if (isa<PoisonValue>(Operands[0]) || isa<PoisonValue>(Operands[1]))
- return PoisonValue::get(Ty);
-
const APInt *C0, *C1;
if (!getConstIntOrUndef(Operands[0], C0) ||
!getConstIntOrUndef(Operands[1], C1))
@@ -3670,6 +3636,11 @@ static Constant *ConstantFoldScalarCall(StringRef Name,
ArrayRef<Constant *> Operands,
const TargetLibraryInfo *TLI,
const CallBase *Call) {
+ if (IntrinsicID != Intrinsic::not_intrinsic &&
+ any_of(Operands, IsaPred<PoisonValue>) &&
+ intrinsicPropagatesPoison(IntrinsicID))
+ return PoisonValue::get(Ty);
+
if (Operands.size() == 1)
return ConstantFoldScalarCall1(Name, IntrinsicID, Ty, Operands, TLI, Call);