diff options
author | Nikita Popov <npopov@redhat.com> | 2022-07-04 16:26:51 +0200 |
---|---|---|
committer | Nikita Popov <npopov@redhat.com> | 2022-07-06 10:11:34 +0200 |
commit | 11950efe06822590ff3ee4048df741136c5295bd (patch) | |
tree | a81c7cad3dd63bed750d3822e3e043684bd32fed /llvm/lib/IR/Constants.cpp | |
parent | 02b38ba8aa6ea32be5198849fff93929a117afe6 (diff) | |
download | llvm-11950efe06822590ff3ee4048df741136c5295bd.zip llvm-11950efe06822590ff3ee4048df741136c5295bd.tar.gz llvm-11950efe06822590ff3ee4048df741136c5295bd.tar.bz2 |
[ConstExpr] Remove div/rem constant expressions
D128820 stopped creating div/rem constant expressions by default;
this patch removes support for them entirely.
The getUDiv(), getExactUDiv(), getSDiv(), getExactSDiv(), getURem()
and getSRem() on ConstantExpr are removed, and ConstantExpr::get()
now only accepts binary operators for which
ConstantExpr::isSupportedBinOp() returns true. Uses of these methods
may be replaced either by corresponding IRBuilder methods, or
ConstantFoldBinaryOpOperands (if a constant result is required).
On the C API side, LLVMConstUDiv, LLVMConstExactUDiv, LLVMConstSDiv,
LLVMConstExactSDiv, LLVMConstURem and LLVMConstSRem are removed and
corresponding LLVMBuild methods should be used.
Importantly, this also means that constant expressions can no longer
trap! This patch still keeps the canTrap() method to minimize diff --
I plan to drop it in a separate NFC patch.
Differential Revision: https://reviews.llvm.org/D129148
Diffstat (limited to 'llvm/lib/IR/Constants.cpp')
-rw-r--r-- | llvm/lib/IR/Constants.cpp | 90 |
1 files changed, 30 insertions, 60 deletions
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp index f6b745d..0fb0db3 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -559,49 +559,8 @@ void llvm::deleteConstant(Constant *C) { } } -static bool canTrapImpl(const Constant *C, - SmallPtrSetImpl<const Constant *> &NonTrappingOps) { - assert(C->getType()->isFirstClassType() && - "Cannot evaluate non-first-class types!"); - // ConstantExpr or ConstantAggregate trap if any operands can trap. - if (isa<ConstantExpr>(C) || isa<ConstantAggregate>(C)) { - for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) { - const Constant *Op = cast<Constant>(C->getOperand(i)); - if (isa<ConstantExpr>(Op) || isa<ConstantAggregate>(Op)) { - if (NonTrappingOps.insert(Op).second && canTrapImpl(Op, NonTrappingOps)) - return true; - } - } - } - - // The only leafs that can trap are constant expressions. - const ConstantExpr *CE = dyn_cast<ConstantExpr>(C); - if (!CE) - return false; - - // Otherwise, only specific operations can trap. - switch (CE->getOpcode()) { - default: - return false; - case Instruction::SDiv: - case Instruction::SRem: - // Signed div/rem can trap for SignedMin / -1. - if (!CE->getOperand(0)->isNotMinSignedValue() && - (!isa<ConstantInt>(CE->getOperand(1)) || - CE->getOperand(1)->isAllOnesValue())) - return true; - 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(); - } -} - bool Constant::canTrap() const { - SmallPtrSet<const Constant *, 4> NonTrappingOps; - return canTrapImpl(this, NonTrappingOps); + return false; } /// Check if C contains a GlobalValue for which Predicate is true. @@ -2311,6 +2270,8 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2, // Check the operands for consistency first. assert(Instruction::isBinaryOp(Opcode) && "Invalid opcode in binary constant expression"); + assert(isSupportedBinOp(Opcode) && + "Binop not supported as constant expression"); assert(C1->getType() == C2->getType() && "Operand types in binary constant expression should match"); @@ -2392,6 +2353,33 @@ bool ConstantExpr::isDesirableBinOp(unsigned Opcode) { } } +bool ConstantExpr::isSupportedBinOp(unsigned Opcode) { + switch (Opcode) { + case Instruction::UDiv: + case Instruction::SDiv: + case Instruction::URem: + case Instruction::SRem: + return false; + case Instruction::Add: + case Instruction::Sub: + case Instruction::Mul: + case Instruction::Shl: + case Instruction::LShr: + case Instruction::AShr: + case Instruction::And: + case Instruction::Or: + case Instruction::Xor: + case Instruction::FAdd: + case Instruction::FSub: + case Instruction::FMul: + case Instruction::FDiv: + case Instruction::FRem: + return true; + default: + llvm_unreachable("Argument must be binop opcode"); + } +} + Constant *ConstantExpr::getSizeOf(Type* Ty) { // sizeof is implemented as: (i64) gep (Ty*)null, 1 // Note that a non-inbounds gep is used, as null isn't within any object. @@ -2710,28 +2698,10 @@ Constant *ConstantExpr::getFMul(Constant *C1, Constant *C2) { return get(Instruction::FMul, C1, C2); } -Constant *ConstantExpr::getUDiv(Constant *C1, Constant *C2, bool isExact) { - return get(Instruction::UDiv, C1, C2, - isExact ? PossiblyExactOperator::IsExact : 0); -} - -Constant *ConstantExpr::getSDiv(Constant *C1, Constant *C2, bool isExact) { - return get(Instruction::SDiv, C1, C2, - isExact ? PossiblyExactOperator::IsExact : 0); -} - Constant *ConstantExpr::getFDiv(Constant *C1, Constant *C2) { return get(Instruction::FDiv, C1, C2); } -Constant *ConstantExpr::getURem(Constant *C1, Constant *C2) { - return get(Instruction::URem, C1, C2); -} - -Constant *ConstantExpr::getSRem(Constant *C1, Constant *C2) { - return get(Instruction::SRem, C1, C2); -} - Constant *ConstantExpr::getFRem(Constant *C1, Constant *C2) { return get(Instruction::FRem, C1, C2); } |