aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Constants.cpp
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2024-03-20 10:59:45 +0100
committerGitHub <noreply@github.com>2024-03-20 10:59:45 +0100
commit0f46e31cfbf415fcd3d3ce121bef94e92c6ccfc8 (patch)
treef7480770f05cd77458340f1f23104275c9be1614 /llvm/lib/IR/Constants.cpp
parent1f63a56cede85bcd5f4fea3663bd3a47b801a396 (diff)
downloadllvm-0f46e31cfbf415fcd3d3ce121bef94e92c6ccfc8.zip
llvm-0f46e31cfbf415fcd3d3ce121bef94e92c6ccfc8.tar.gz
llvm-0f46e31cfbf415fcd3d3ce121bef94e92c6ccfc8.tar.bz2
[IR] Change representation of getelementptr inrange (#84341)
As part of the migration to ptradd (https://discourse.llvm.org/t/rfc-replacing-getelementptr-with-ptradd/68699), we need to change the representation of the `inrange` attribute, which is used for vtable splitting. Currently, inrange is specified as follows: ``` getelementptr inbounds ({ [4 x ptr], [4 x ptr] }, ptr @vt, i64 0, inrange i32 1, i64 2) ``` The `inrange` is placed on a GEP index, and all accesses must be "in range" of that index. The new representation is as follows: ``` getelementptr inbounds inrange(-16, 16) ({ [4 x ptr], [4 x ptr] }, ptr @vt, i64 0, i32 1, i64 2) ``` This specifies which offsets are "in range" of the GEP result. The new representation will continue working when canonicalizing to ptradd representation: ``` getelementptr inbounds inrange(-16, 16) (i8, ptr @vt, i64 48) ``` The inrange offsets are relative to the return value of the GEP. An alternative design could make them relative to the source pointer instead. The result-relative format was chosen on the off-chance that we want to extend support to non-constant GEPs in the future, in which case this variant is more expressive. This implementation "upgrades" the old inrange representation in bitcode by simply dropping it. This is a very niche feature, and I don't think trying to upgrade it is worthwhile. Let me know if you disagree.
Diffstat (limited to 'llvm/lib/IR/Constants.cpp')
-rw-r--r--llvm/lib/IR/Constants.cpp28
1 files changed, 16 insertions, 12 deletions
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index 07b5bce..c17419b 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -1568,7 +1568,7 @@ Constant *ConstantExpr::getWithOperands(ArrayRef<Constant *> Ops, Type *Ty,
assert(SrcTy || (Ops[0]->getType() == getOperand(0)->getType()));
return ConstantExpr::getGetElementPtr(
SrcTy ? SrcTy : GEPO->getSourceElementType(), Ops[0], Ops.slice(1),
- GEPO->isInBounds(), GEPO->getInRangeIndex(), OnlyIfReducedTy);
+ GEPO->isInBounds(), GEPO->getInRange(), OnlyIfReducedTy);
}
case Instruction::ICmp:
case Instruction::FCmp:
@@ -2349,17 +2349,16 @@ Constant *ConstantExpr::getCompare(unsigned short Predicate, Constant *C1,
Constant *ConstantExpr::getGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Value *> Idxs, bool InBounds,
- std::optional<unsigned> InRangeIndex,
+ std::optional<ConstantRange> InRange,
Type *OnlyIfReducedTy) {
assert(Ty && "Must specify element type");
assert(isSupportedGetElementPtr(Ty) && "Element type is unsupported!");
- if (Constant *FC =
- ConstantFoldGetElementPtr(Ty, C, InBounds, InRangeIndex, Idxs))
- return FC; // Fold a few common cases.
+ if (Constant *FC = ConstantFoldGetElementPtr(Ty, C, InBounds, InRange, Idxs))
+ return FC; // Fold a few common cases.
- assert(GetElementPtrInst::getIndexedType(Ty, Idxs) &&
- "GEP indices invalid!");;
+ assert(GetElementPtrInst::getIndexedType(Ty, Idxs) && "GEP indices invalid!");
+ ;
// Get the result type of the getelementptr!
Type *ReqTy = GetElementPtrInst::getGEPReturnType(C, Idxs);
@@ -2392,10 +2391,9 @@ Constant *ConstantExpr::getGetElementPtr(Type *Ty, Constant *C,
}
unsigned SubClassOptionalData = InBounds ? GEPOperator::IsInBounds : 0;
- if (InRangeIndex && *InRangeIndex < 63)
- SubClassOptionalData |= (*InRangeIndex + 1) << 1;
const ConstantExprKeyType Key(Instruction::GetElementPtr, ArgVec, 0,
- SubClassOptionalData, std::nullopt, Ty);
+ SubClassOptionalData, std::nullopt, Ty,
+ InRange);
LLVMContextImpl *pImpl = C->getContext().pImpl;
return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
@@ -2691,13 +2689,15 @@ const char *ConstantExpr::getOpcodeName() const {
}
GetElementPtrConstantExpr::GetElementPtrConstantExpr(
- Type *SrcElementTy, Constant *C, ArrayRef<Constant *> IdxList, Type *DestTy)
+ Type *SrcElementTy, Constant *C, ArrayRef<Constant *> IdxList, Type *DestTy,
+ std::optional<ConstantRange> InRange)
: ConstantExpr(DestTy, Instruction::GetElementPtr,
OperandTraits<GetElementPtrConstantExpr>::op_end(this) -
(IdxList.size() + 1),
IdxList.size() + 1),
SrcElementTy(SrcElementTy),
- ResElementTy(GetElementPtrInst::getIndexedType(SrcElementTy, IdxList)) {
+ ResElementTy(GetElementPtrInst::getIndexedType(SrcElementTy, IdxList)),
+ InRange(std::move(InRange)) {
Op<0>() = C;
Use *OperandList = getOperandList();
for (unsigned i = 0, E = IdxList.size(); i != E; ++i)
@@ -2712,6 +2712,10 @@ Type *GetElementPtrConstantExpr::getResultElementType() const {
return ResElementTy;
}
+std::optional<ConstantRange> GetElementPtrConstantExpr::getInRange() const {
+ return InRange;
+}
+
//===----------------------------------------------------------------------===//
// ConstantData* implementations