diff options
author | Nikita Popov <npopov@redhat.com> | 2022-06-17 11:21:54 +0200 |
---|---|---|
committer | Nikita Popov <npopov@redhat.com> | 2022-06-17 11:25:11 +0200 |
commit | daf897d559fcc4fdc88812941aba83ab05463e11 (patch) | |
tree | 0c1b0459f4d8b22e507f6b6eef602040c824ce6e /llvm/lib/IR/Constants.cpp | |
parent | 610139d2d9ce6746b3c617fb3e2f7886272d26ff (diff) | |
download | llvm-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.cpp | 15 |
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(); } } |