Skip to content

Commit e41ffd3

Browse files
authored
[NaryReassociate] Fix crash from pointer width / index width confusion (#125923)
NaryReassociate would crash on expressions like the one in the added test that involved pointers where the size of the type was greater than the index width of the pointer, causing calls to SCEV's zext expression on types that didn't need to be zero-extended. This commit fixes the issue.
1 parent c32cd57 commit e41ffd3

File tree

2 files changed

+17
-5
lines changed

2 files changed

+17
-5
lines changed

llvm/lib/Transforms/Scalar/NaryReassociate.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -402,16 +402,17 @@ NaryReassociatePass::tryReassociateGEPAtIndex(GetElementPtrInst *GEP,
402402
IndexExprs.push_back(SE->getSCEV(Index));
403403
// Replace the I-th index with LHS.
404404
IndexExprs[I] = SE->getSCEV(LHS);
405+
Type *GEPArgType = SE->getEffectiveSCEVType(GEP->getOperand(I)->getType());
406+
Type *LHSType = SE->getEffectiveSCEVType(LHS->getType());
407+
size_t LHSSize = DL->getTypeSizeInBits(LHSType).getFixedValue();
408+
size_t GEPArgSize = DL->getTypeSizeInBits(GEPArgType).getFixedValue();
405409
if (isKnownNonNegative(LHS, SimplifyQuery(*DL, DT, AC, GEP)) &&
406-
DL->getTypeSizeInBits(LHS->getType()).getFixedValue() <
407-
DL->getTypeSizeInBits(GEP->getOperand(I)->getType())
408-
.getFixedValue()) {
410+
LHSSize < GEPArgSize) {
409411
// Zero-extend LHS if it is non-negative. InstCombine canonicalizes sext to
410412
// zext if the source operand is proved non-negative. We should do that
411413
// consistently so that CandidateExpr more likely appears before. See
412414
// @reassociate_gep_assume for an example of this canonicalization.
413-
IndexExprs[I] =
414-
SE->getZeroExtendExpr(IndexExprs[I], GEP->getOperand(I)->getType());
415+
IndexExprs[I] = SE->getZeroExtendExpr(IndexExprs[I], GEPArgType);
415416
}
416417
const SCEV *CandidateExpr = SE->getGEPExpr(cast<GEPOperator>(GEP),
417418
IndexExprs);

llvm/test/Transforms/NaryReassociate/nary-gep.ll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,17 @@ define void @no_sext_fat_pointer(ptr addrspace(2) %a, i32 %i, i32 %j) {
2121
ret void
2222
}
2323

24+
define ptr addrspace(2) @zext_fat_pointer_crash(ptr addrspace(2) %p, i32 %a) {
25+
; CHECK-LABEL: @zext_fat_pointer_crash(
26+
; CHECK-NEXT: [[C:%.*]] = add i32 [[A:%.*]], 1
27+
; CHECK-NEXT: [[Q:%.*]] = getelementptr double, ptr addrspace(2) [[P:%.*]], i32 [[C]]
28+
; CHECK-NEXT: ret ptr addrspace(2) [[Q]]
29+
;
30+
%c = add i32 %a, 1
31+
%q = getelementptr double, ptr addrspace(2) %p, i32 %c
32+
ret ptr addrspace(2) %q
33+
}
34+
2435
define void @or_disjoint(ptr addrspace(2) %a, i32 %i, i32 %j, i32 %k) {
2536
; CHECK-LABEL: @or_disjoint(
2637
; CHECK-NEXT: [[OR:%.*]] = or disjoint i32 [[I:%.*]], [[J:%.*]]

0 commit comments

Comments
 (0)