aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Constants.cpp
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2022-07-04 16:26:51 +0200
committerNikita Popov <npopov@redhat.com>2022-07-06 10:11:34 +0200
commit11950efe06822590ff3ee4048df741136c5295bd (patch)
treea81c7cad3dd63bed750d3822e3e043684bd32fed /llvm/lib/IR/Constants.cpp
parent02b38ba8aa6ea32be5198849fff93929a117afe6 (diff)
downloadllvm-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.cpp90
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);
}