Skip to content

Commit d1497fe

Browse files
committed
[InstCombine] Preserve nuw in canonicalizeGEPOfConstGEPI8()
Proof: https://alive2.llvm.org/ce/z/vC239S
1 parent 740758a commit d1497fe

File tree

2 files changed

+83
-2
lines changed

2 files changed

+83
-2
lines changed

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2652,9 +2652,15 @@ static Instruction *canonicalizeGEPOfConstGEPI8(GetElementPtrInst &GEP,
26522652
APInt NewOffset = TypeSize * *C2 + *C1;
26532653
if (NewOffset.isZero() ||
26542654
(Src->hasOneUse() && GEP.getOperand(1)->hasOneUse())) {
2655+
GEPNoWrapFlags Flags = GEPNoWrapFlags::none();
2656+
if (GEP.hasNoUnsignedWrap() &&
2657+
cast<GEPOperator>(Src)->hasNoUnsignedWrap() &&
2658+
match(GEP.getOperand(1), m_NUWAddLike(m_Value(), m_Value())))
2659+
Flags |= GEPNoWrapFlags::noUnsignedWrap();
2660+
26552661
Value *GEPConst =
2656-
IC.Builder.CreatePtrAdd(Base, IC.Builder.getInt(NewOffset));
2657-
return GetElementPtrInst::Create(BaseType, GEPConst, VarIndex);
2662+
IC.Builder.CreatePtrAdd(Base, IC.Builder.getInt(NewOffset), "", Flags);
2663+
return GetElementPtrInst::Create(BaseType, GEPConst, VarIndex, Flags);
26582664
}
26592665

26602666
return nullptr;

llvm/test/Transforms/InstCombine/gepofconstgepi8.ll

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,3 +293,78 @@ entry:
293293
%p2 = getelementptr <vscale x 4 x i32>, ptr %p1, i64 %index
294294
ret ptr %p2
295295
}
296+
297+
define ptr @test_all_nuw(ptr %base, i64 %a) {
298+
; CHECK-LABEL: define ptr @test_all_nuw(
299+
; CHECK-SAME: ptr [[BASE:%.*]], i64 [[A:%.*]]) {
300+
; CHECK-NEXT: entry:
301+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr nuw i8, ptr [[BASE]], i64 9
302+
; CHECK-NEXT: [[P2:%.*]] = getelementptr nuw i32, ptr [[TMP0]], i64 [[A]]
303+
; CHECK-NEXT: ret ptr [[P2]]
304+
;
305+
entry:
306+
%p1 = getelementptr nuw i8, ptr %base, i64 1
307+
%index = add nuw i64 %a, 2
308+
%p2 = getelementptr nuw i32, ptr %p1, i64 %index
309+
ret ptr %p2
310+
}
311+
312+
define ptr @test_all_partial_nuw1(ptr %base, i64 %a) {
313+
; CHECK-LABEL: define ptr @test_all_partial_nuw1(
314+
; CHECK-SAME: ptr [[BASE:%.*]], i64 [[A:%.*]]) {
315+
; CHECK-NEXT: entry:
316+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[BASE]], i64 9
317+
; CHECK-NEXT: [[P2:%.*]] = getelementptr i32, ptr [[TMP0]], i64 [[A]]
318+
; CHECK-NEXT: ret ptr [[P2]]
319+
;
320+
entry:
321+
%p1 = getelementptr i8, ptr %base, i64 1
322+
%index = add nuw i64 %a, 2
323+
%p2 = getelementptr nuw i32, ptr %p1, i64 %index
324+
ret ptr %p2
325+
}
326+
327+
define ptr @test_all_partial_nuw2(ptr %base, i64 %a) {
328+
; CHECK-LABEL: define ptr @test_all_partial_nuw2(
329+
; CHECK-SAME: ptr [[BASE:%.*]], i64 [[A:%.*]]) {
330+
; CHECK-NEXT: entry:
331+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[BASE]], i64 9
332+
; CHECK-NEXT: [[P2:%.*]] = getelementptr i32, ptr [[TMP0]], i64 [[A]]
333+
; CHECK-NEXT: ret ptr [[P2]]
334+
;
335+
entry:
336+
%p1 = getelementptr nuw i8, ptr %base, i64 1
337+
%index = add i64 %a, 2
338+
%p2 = getelementptr nuw i32, ptr %p1, i64 %index
339+
ret ptr %p2
340+
}
341+
342+
define ptr @test_all_partial_nuw3(ptr %base, i64 %a) {
343+
; CHECK-LABEL: define ptr @test_all_partial_nuw3(
344+
; CHECK-SAME: ptr [[BASE:%.*]], i64 [[A:%.*]]) {
345+
; CHECK-NEXT: entry:
346+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[BASE]], i64 9
347+
; CHECK-NEXT: [[P2:%.*]] = getelementptr i32, ptr [[TMP0]], i64 [[A]]
348+
; CHECK-NEXT: ret ptr [[P2]]
349+
;
350+
entry:
351+
%p1 = getelementptr nuw i8, ptr %base, i64 1
352+
%index = add nuw i64 %a, 2
353+
%p2 = getelementptr i32, ptr %p1, i64 %index
354+
ret ptr %p2
355+
}
356+
357+
define ptr @test_all_nuw_disjoint(ptr %base, i64 %a) {
358+
; CHECK-LABEL: define ptr @test_all_nuw_disjoint(
359+
; CHECK-SAME: ptr [[BASE:%.*]], i64 [[A:%.*]]) {
360+
; CHECK-NEXT: entry:
361+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr nuw i8, ptr [[BASE]], i64 9
362+
; CHECK-NEXT: [[P2:%.*]] = getelementptr nuw i32, ptr [[TMP0]], i64 [[A]]
363+
; CHECK-NEXT: ret ptr [[P2]]
364+
;
365+
entry:
366+
%p1 = getelementptr nuw i8, ptr %base, i64 1
367+
%index = or disjoint i64 %a, 2
368+
%p2 = getelementptr nuw i32, ptr %p1, i64 %index
369+
ret ptr %p2
370+
}

0 commit comments

Comments
 (0)