Skip to content

Commit 359bc5c

Browse files
committed
[ConstraintElim] Bail out for GEPs when index size > 64 bits.
Limit pointer decomposition to pointers with index sizes of at most 64 bits. int64_t is used for coefficients, so as long as the index size <= 64 bits we should be able to represent all pointer offsets. Pointer decomposition is limited to inbounds GEPs, so if a index computation would overflow the result is poison, so it doesn't matter that the coefficient overflows. This allows replacing MulOverflow with regular multiplications.
1 parent 440ce05 commit 359bc5c

File tree

2 files changed

+37
-30
lines changed

2 files changed

+37
-30
lines changed

llvm/lib/Transforms/Scalar/ConstraintElimination.cpp

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -193,67 +193,74 @@ static SmallVector<DecompEntry, 4>
193193
decomposeGEP(GetElementPtrInst &GEP,
194194
SmallVector<PreconditionTy, 4> &Preconditions, bool IsSigned,
195195
const DataLayout &DL) {
196+
// Do not reason about pointers where the index size is larger than 64 bits,
197+
// as the coefficients used to encode constraints are 64 bit integers.
198+
unsigned AS =
199+
cast<PointerType>(GEP.getPointerOperand()->getType())->getAddressSpace();
200+
if (DL.getIndexSizeInBits(AS) > 64)
201+
return {};
202+
196203
auto GTI = gep_type_begin(GEP);
197204
if (GEP.getNumOperands() != 2 || !GEP.isInBounds() ||
198205
isa<ScalableVectorType>(GTI.getIndexedType()))
199206
return {{0, nullptr}, {1, &GEP}};
200207

201208
int64_t Scale = static_cast<int64_t>(
202209
DL.getTypeAllocSize(GTI.getIndexedType()).getFixedSize());
203-
int64_t MulRes;
204210
// Handle the (gep (gep ....), C) case by incrementing the constant
205211
// coefficient of the inner GEP, if C is a constant.
206212
auto *InnerGEP = dyn_cast<GetElementPtrInst>(GEP.getPointerOperand());
207213
if (InnerGEP && InnerGEP->getNumOperands() == 2 &&
208214
isa<ConstantInt>(GEP.getOperand(1))) {
209215
APInt Offset = cast<ConstantInt>(GEP.getOperand(1))->getValue();
210216
auto Result = decompose(InnerGEP, Preconditions, IsSigned, DL);
211-
if (!MulOverflow(Scale, Offset.getSExtValue(), MulRes)) {
212-
Result[0].Coefficient += MulRes;
213-
if (Offset.isNegative()) {
214-
// Add pre-condition ensuring the GEP is increasing monotonically and
215-
// can be de-composed.
216-
Preconditions.emplace_back(
217-
CmpInst::ICMP_SGE, InnerGEP->getOperand(1),
218-
ConstantInt::get(InnerGEP->getOperand(1)->getType(),
219-
-1 * Offset.getSExtValue()));
220-
}
221-
return Result;
217+
Result[0].Coefficient += Scale * Offset.getSExtValue();
218+
if (Offset.isNegative()) {
219+
// Add pre-condition ensuring the GEP is increasing monotonically and
220+
// can be de-composed.
221+
Preconditions.emplace_back(
222+
CmpInst::ICMP_SGE, InnerGEP->getOperand(1),
223+
ConstantInt::get(InnerGEP->getOperand(1)->getType(),
224+
-1 * Offset.getSExtValue()));
222225
}
226+
return Result;
223227
}
224228

225229
Value *Op0, *Op1;
226230
ConstantInt *CI;
227231
// If the index is zero-extended, it is guaranteed to be positive.
228232
if (match(GEP.getOperand(GEP.getNumOperands() - 1), m_ZExt(m_Value(Op0)))) {
229-
if (match(Op0, m_NUWShl(m_Value(Op1), m_ConstantInt(CI))) &&
230-
canUseSExt(CI) &&
231-
!MulOverflow(Scale, int64_t(std::pow(int64_t(2), CI->getSExtValue())),
232-
MulRes))
233-
return {{0, nullptr}, {1, GEP.getPointerOperand()}, {MulRes, Op1}};
233+
if (match(Op0, m_NUWShl(m_Value(Op1), m_ConstantInt(CI))) && canUseSExt(CI))
234+
return {{0, nullptr},
235+
{1, GEP.getPointerOperand()},
236+
{Scale * int64_t(std::pow(int64_t(2), CI->getSExtValue())), Op1}};
234237
if (match(Op0, m_NSWAdd(m_Value(Op1), m_ConstantInt(CI))) &&
235-
canUseSExt(CI) && match(Op0, m_NUWAdd(m_Value(), m_Value())) &&
236-
!MulOverflow(Scale, CI->getSExtValue(), MulRes))
237-
return {{MulRes, nullptr}, {1, GEP.getPointerOperand()}, {Scale, Op1}};
238+
canUseSExt(CI) && match(Op0, m_NUWAdd(m_Value(), m_Value())))
239+
return {{Scale * CI->getSExtValue(), nullptr},
240+
{1, GEP.getPointerOperand()},
241+
{Scale, Op1}};
242+
238243
return {{0, nullptr}, {1, GEP.getPointerOperand()}, {Scale, Op0, true}};
239244
}
240245

241246
if (match(GEP.getOperand(GEP.getNumOperands() - 1), m_ConstantInt(CI)) &&
242-
!CI->isNegative() && canUseSExt(CI) &&
243-
!MulOverflow(Scale, CI->getSExtValue(), MulRes))
244-
return {{MulRes, nullptr}, {1, GEP.getPointerOperand()}};
247+
!CI->isNegative() && canUseSExt(CI))
248+
return {{Scale * CI->getSExtValue(), nullptr},
249+
{1, GEP.getPointerOperand()}};
245250

246251
SmallVector<DecompEntry, 4> Result;
247252
if (match(GEP.getOperand(GEP.getNumOperands() - 1),
248253
m_NSWShl(m_Value(Op0), m_ConstantInt(CI))) &&
249-
canUseSExt(CI) &&
250-
!MulOverflow(Scale, int64_t(std::pow(int64_t(2), CI->getSExtValue())),
251-
MulRes))
252-
Result = {{0, nullptr}, {1, GEP.getPointerOperand()}, {MulRes, Op0}};
254+
canUseSExt(CI))
255+
Result = {{0, nullptr},
256+
{1, GEP.getPointerOperand()},
257+
{Scale * int64_t(std::pow(int64_t(2), CI->getSExtValue())), Op0}};
253258
else if (match(GEP.getOperand(GEP.getNumOperands() - 1),
254259
m_NSWAdd(m_Value(Op0), m_ConstantInt(CI))) &&
255-
canUseSExt(CI) && !MulOverflow(Scale, CI->getSExtValue(), MulRes))
256-
Result = {{MulRes, nullptr}, {1, GEP.getPointerOperand()}, {Scale, Op0}};
260+
canUseSExt(CI))
261+
Result = {{Scale * CI->getSExtValue(), nullptr},
262+
{1, GEP.getPointerOperand()},
263+
{Scale, Op0}};
257264
else {
258265
Op0 = GEP.getOperand(GEP.getNumOperands() - 1);
259266
Result = {{0, nullptr}, {1, GEP.getPointerOperand()}, {Scale, Op0}};

llvm/test/Transforms/ConstraintElimination/large-constant-ints.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ define i1 @gep_decomp_large_index_63_bits(ptr %a) {
336336
; CHECK-NEXT: call void @llvm.assume(i1 [[NE]])
337337
; CHECK-NEXT: [[CMP_ULE:%.*]] = icmp ule ptr [[GEP_1]], [[GEP_2]]
338338
; CHECK-NEXT: [[CMP_UGE:%.*]] = icmp uge ptr [[GEP_1]], [[GEP_2]]
339-
; CHECK-NEXT: [[RES:%.*]] = xor i1 [[CMP_ULE]], [[CMP_ULE]]
339+
; CHECK-NEXT: [[RES:%.*]] = xor i1 true, true
340340
; CHECK-NEXT: ret i1 [[RES]]
341341
;
342342
entry:

0 commit comments

Comments
 (0)