Skip to content

Commit 3cc1b7c

Browse files
authored
[SeparateConstOffsetFromGEP] Check if non-extracted indices may be negative when preserving inbounds (#159515)
If we know that the initial GEP was inbounds, and we change it to a sequence of GEPs from the same base pointer where every offset is non-negative, then the new GEPs are inbounds. So far, the implementation only checked if the extracted offsets are non-negative. In cases where non-extracted offsets can be negative, this would cause the inbounds flag to be wrongly preserved. Fixes an issue in #130617 found by nikic.
1 parent ebe7587 commit 3cc1b7c

File tree

4 files changed

+18
-17
lines changed

4 files changed

+18
-17
lines changed

llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,22 +1116,23 @@ bool SeparateConstOffsetFromGEP::splitGEP(GetElementPtrInst *GEP) {
11161116

11171117
// Splits this GEP index into a variadic part and a constant offset, and
11181118
// uses the variadic part as the new index.
1119-
Value *OldIdx = GEP->getOperand(I);
1119+
Value *Idx = GEP->getOperand(I);
11201120
User *UserChainTail;
11211121
bool PreservesNUW;
1122-
Value *NewIdx = ConstantOffsetExtractor::Extract(
1123-
OldIdx, GEP, UserChainTail, PreservesNUW);
1122+
Value *NewIdx = ConstantOffsetExtractor::Extract(Idx, GEP, UserChainTail,
1123+
PreservesNUW);
11241124
if (NewIdx != nullptr) {
11251125
// Switches to the index with the constant offset removed.
11261126
GEP->setOperand(I, NewIdx);
11271127
// After switching to the new index, we can garbage-collect UserChain
11281128
// and the old index if they are not used.
11291129
RecursivelyDeleteTriviallyDeadInstructions(UserChainTail);
1130-
RecursivelyDeleteTriviallyDeadInstructions(OldIdx);
1131-
AllOffsetsNonNegative =
1132-
AllOffsetsNonNegative && isKnownNonNegative(NewIdx, *DL);
1130+
RecursivelyDeleteTriviallyDeadInstructions(Idx);
1131+
Idx = NewIdx;
11331132
AllNUWPreserved &= PreservesNUW;
11341133
}
1134+
AllOffsetsNonNegative =
1135+
AllOffsetsNonNegative && isKnownNonNegative(Idx, *DL);
11351136
}
11361137
}
11371138
if (ExtractBase) {

llvm/test/Transforms/SeparateConstOffsetFromGEP/AMDGPU/reorder-gep-inbounds.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,8 @@ define void @addrspace3(ptr addrspace(3) %in.ptr, i64 %in.idx1) {
279279
; CHECK-NEXT: entry:
280280
; CHECK-NEXT: [[IN_IDX1_NNEG:%.*]] = and i64 [[IN_IDX1]], 9223372036854775807
281281
; CHECK-NEXT: [[IDXPROM:%.*]] = trunc i64 [[IN_IDX1_NNEG]] to i32
282-
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i128, ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]]
283-
; CHECK-NEXT: [[IDX11:%.*]] = getelementptr inbounds i8, ptr addrspace(3) [[TMP0]], i32 1024
282+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i128, ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]]
283+
; CHECK-NEXT: [[IDX11:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP0]], i32 1024
284284
; CHECK-NEXT: ret void
285285
;
286286
entry:
@@ -296,8 +296,8 @@ define void @addrspace7(ptr addrspace(7) %in.ptr, i64 %in.idx1) {
296296
; CHECK-NEXT: entry:
297297
; CHECK-NEXT: [[IN_IDX1_NNEG:%.*]] = and i64 [[IN_IDX1]], 9223372036854775807
298298
; CHECK-NEXT: [[IDXPROM:%.*]] = trunc i64 [[IN_IDX1_NNEG]] to i32
299-
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i128, ptr addrspace(7) [[IN_PTR]], i32 [[IDXPROM]]
300-
; CHECK-NEXT: [[IDX11:%.*]] = getelementptr inbounds i8, ptr addrspace(7) [[TMP0]], i32 1024
299+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i128, ptr addrspace(7) [[IN_PTR]], i32 [[IDXPROM]]
300+
; CHECK-NEXT: [[IDX11:%.*]] = getelementptr i8, ptr addrspace(7) [[TMP0]], i32 1024
301301
; CHECK-NEXT: ret void
302302
;
303303
entry:

llvm/test/Transforms/SeparateConstOffsetFromGEP/NVPTX/gep-chain.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ define i32 @more_interesting(ptr %ptr, i32 %offset1, i32 %offset2) {
2424
; CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[OFFSET1]] to i64
2525
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [[STRUCT_UCHAR4:%.*]], ptr [[PTR]], i64 [[IDXPROM]]
2626
; CHECK-NEXT: [[IDXPROM1:%.*]] = sext i32 [[OFFSET2]] to i64
27-
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT_UCHAR4]], ptr [[GEP1]], i64 [[IDXPROM1]]
28-
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 8
27+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_UCHAR4]], ptr [[GEP1]], i64 [[IDXPROM1]]
28+
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP1]], i64 8
2929
; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[TMP2]], align 4
3030
; CHECK-NEXT: [[IDXPROM2:%.*]] = sext i32 [[OFFSET2]] to i64
31-
; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[STRUCT_UCHAR4]], ptr [[TMP1]], i64 [[IDXPROM2]]
31+
; CHECK-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_UCHAR4]], ptr [[TMP1]], i64 [[IDXPROM2]]
3232
; CHECK-NEXT: [[V2:%.*]] = load i32, ptr [[TMP4]], align 4
3333
; CHECK-NEXT: [[R:%.*]] = add i32 [[V1]], [[V2]]
3434
; CHECK-NEXT: ret i32 [[R]]

llvm/test/Transforms/SeparateConstOffsetFromGEP/NVPTX/split-gep.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -372,8 +372,8 @@ define ptr @trunk_explicit(ptr %ptr, i64 %idx) {
372372
; CHECK-LABEL: define ptr @trunk_explicit(
373373
; CHECK-SAME: ptr [[PTR:%.*]], i64 [[IDX:%.*]]) {
374374
; CHECK-NEXT: entry:
375-
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT0:%.*]], ptr [[PTR]], i64 0, i32 3, i64 [[IDX]], i32 1
376-
; CHECK-NEXT: [[PTR21:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 3216
375+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr [[STRUCT0:%.*]], ptr [[PTR]], i64 0, i32 3, i64 [[IDX]], i32 1
376+
; CHECK-NEXT: [[PTR21:%.*]] = getelementptr i8, ptr [[TMP0]], i64 3216
377377
; CHECK-NEXT: ret ptr [[PTR21]]
378378
;
379379
entry:
@@ -389,8 +389,8 @@ define ptr @trunk_long_idx(ptr %ptr, i64 %idx) {
389389
; CHECK-LABEL: define ptr @trunk_long_idx(
390390
; CHECK-SAME: ptr [[PTR:%.*]], i64 [[IDX:%.*]]) {
391391
; CHECK-NEXT: entry:
392-
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT0:%.*]], ptr [[PTR]], i64 0, i32 3, i64 [[IDX]], i32 1
393-
; CHECK-NEXT: [[PTR21:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 3216
392+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr [[STRUCT0:%.*]], ptr [[PTR]], i64 0, i32 3, i64 [[IDX]], i32 1
393+
; CHECK-NEXT: [[PTR21:%.*]] = getelementptr i8, ptr [[TMP0]], i64 3216
394394
; CHECK-NEXT: ret ptr [[PTR21]]
395395
;
396396
entry:

0 commit comments

Comments
 (0)