aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Constants.cpp
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2022-06-17 11:21:54 +0200
committerNikita Popov <npopov@redhat.com>2022-06-17 11:25:11 +0200
commitdaf897d559fcc4fdc88812941aba83ab05463e11 (patch)
tree0c1b0459f4d8b22e507f6b6eef602040c824ce6e /llvm/lib/IR/Constants.cpp
parent610139d2d9ce6746b3c617fb3e2f7886272d26ff (diff)
downloadllvm-daf897d559fcc4fdc88812941aba83ab05463e11.zip
llvm-daf897d559fcc4fdc88812941aba83ab05463e11.tar.gz
llvm-daf897d559fcc4fdc88812941aba83ab05463e11.tar.bz2
[IR] Check for SignedMin/-1 division in canTrap() (PR56038)
In addition to division by zero, signed division also traps for SignedMin / -1. This was handled in isSafeToSpeculativelyExecute(), but not in Constant::canTrap().
Diffstat (limited to 'llvm/lib/IR/Constants.cpp')
-rw-r--r--llvm/lib/IR/Constants.cpp15
1 files changed, 10 insertions, 5 deletions
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index 139ff53..ef39d65 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -587,14 +587,19 @@ static bool canTrapImpl(const Constant *C,
switch (CE->getOpcode()) {
default:
return false;
- case Instruction::UDiv:
case Instruction::SDiv:
- case Instruction::URem:
case Instruction::SRem:
- // Div and rem can trap if the RHS is not known to be non-zero.
- if (!isa<ConstantInt>(CE->getOperand(1)) ||CE->getOperand(1)->isNullValue())
+ // Signed div/rem can trap for SignedMin / -1.
+ if (!CE->getOperand(0)->isNotMinSignedValue() &&
+ (!isa<ConstantInt>(CE->getOperand(1)) ||
+ CE->getOperand(1)->isAllOnesValue()))
return true;
- return false;
+ LLVM_FALLTHROUGH;
+ case Instruction::UDiv:
+ case Instruction::URem:
+ // Div and rem can trap if the RHS is not known to be non-zero.
+ return !isa<ConstantInt>(CE->getOperand(1)) ||
+ CE->getOperand(1)->isNullValue();
}
}