aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp50
1 files changed, 29 insertions, 21 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index a975f1c..8fe98b5 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5197,6 +5197,31 @@ bool llvm::isOverflowIntrinsicNoWrap(const WithOverflowInst *WO,
return llvm::any_of(GuardingBranches, AllUsesGuardedByBranch);
}
+/// Shifts return poison if shiftwidth is larger than the bitwidth.
+static bool shiftAmountKnownInRange(const Value *ShiftAmount) {
+ auto *C = dyn_cast<Constant>(ShiftAmount);
+ if (!C)
+ return false;
+
+ // Shifts return poison if shiftwidth is larger than the bitwidth.
+ SmallVector<const Constant *, 4> ShiftAmounts;
+ if (auto *FVTy = dyn_cast<FixedVectorType>(C->getType())) {
+ unsigned NumElts = FVTy->getNumElements();
+ for (unsigned i = 0; i < NumElts; ++i)
+ ShiftAmounts.push_back(C->getAggregateElement(i));
+ } else if (isa<ScalableVectorType>(C->getType()))
+ return false; // Can't tell, just return false to be safe
+ else
+ ShiftAmounts.push_back(C);
+
+ bool Safe = llvm::all_of(ShiftAmounts, [](const Constant *C) {
+ auto *CI = dyn_cast_or_null<ConstantInt>(C);
+ return CI && CI->getValue().ult(C->getType()->getIntegerBitWidth());
+ });
+
+ return Safe;
+}
+
static bool canCreateUndefOrPoison(const Operator *Op, bool PoisonOnly,
bool ConsiderFlags) {
@@ -5209,27 +5234,8 @@ static bool canCreateUndefOrPoison(const Operator *Op, bool PoisonOnly,
switch (Opcode) {
case Instruction::Shl:
case Instruction::AShr:
- case Instruction::LShr: {
- // Shifts return poison if shiftwidth is larger than the bitwidth.
- if (auto *C = dyn_cast<Constant>(Op->getOperand(1))) {
- SmallVector<Constant *, 4> ShiftAmounts;
- if (auto *FVTy = dyn_cast<FixedVectorType>(C->getType())) {
- unsigned NumElts = FVTy->getNumElements();
- for (unsigned i = 0; i < NumElts; ++i)
- ShiftAmounts.push_back(C->getAggregateElement(i));
- } else if (isa<ScalableVectorType>(C->getType()))
- return true; // Can't tell, just return true to be safe
- else
- ShiftAmounts.push_back(C);
-
- bool Safe = llvm::all_of(ShiftAmounts, [](Constant *C) {
- auto *CI = dyn_cast_or_null<ConstantInt>(C);
- return CI && CI->getValue().ult(C->getType()->getIntegerBitWidth());
- });
- return !Safe;
- }
- return true;
- }
+ case Instruction::LShr:
+ return !shiftAmountKnownInRange(Op->getOperand(1));
case Instruction::FPToSI:
case Instruction::FPToUI:
// fptosi/ui yields poison if the resulting value does not fit in the
@@ -5267,8 +5273,10 @@ static bool canCreateUndefOrPoison(const Operator *Op, bool PoisonOnly,
case Intrinsic::uadd_sat:
case Intrinsic::ssub_sat:
case Intrinsic::usub_sat:
+ return false;
case Intrinsic::sshl_sat:
case Intrinsic::ushl_sat:
+ return !shiftAmountKnownInRange(II->getArgOperand(1));
case Intrinsic::fma:
case Intrinsic::fmuladd:
case Intrinsic::sqrt: