Skip to content

Commit 10f315d

Browse files
authored
[ConstantFolding] Infer getelementptr nuw flag (#119214)
Infer nuw from nusw and nneg. This is the constant expression variant of #111144. Proof: https://alive2.llvm.org/ce/z/ihztLy
1 parent 646d185 commit 10f315d

File tree

82 files changed

+462
-433
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

82 files changed

+462
-433
lines changed

clang/test/CodeGen/RISCV/riscv-inline-asm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,9 @@ extern int var, arr[2][2];
9090
struct Pair { int a, b; } pair;
9191

9292
// CHECK-LABEL: test_s(
93-
// CHECK: call void asm sideeffect "// $0 $1 $2", "s,s,s"(ptr nonnull @var, ptr nonnull getelementptr inbounds (i8, ptr @arr, {{.*}}), ptr nonnull @test_s)
93+
// CHECK: call void asm sideeffect "// $0 $1 $2", "s,s,s"(ptr nonnull @var, ptr nonnull getelementptr inbounds nuw (i8, ptr @arr, {{.*}}), ptr nonnull @test_s)
9494
// CHECK: call void asm sideeffect "// $0", "s"(ptr nonnull getelementptr inbounds nuw (i8, ptr @pair, {{.*}}))
95-
// CHECK: call void asm sideeffect "// $0 $1 $2", "S,S,S"(ptr nonnull @var, ptr nonnull getelementptr inbounds (i8, ptr @arr, {{.*}}), ptr nonnull @test_s)
95+
// CHECK: call void asm sideeffect "// $0 $1 $2", "S,S,S"(ptr nonnull @var, ptr nonnull getelementptr inbounds nuw (i8, ptr @arr, {{.*}}), ptr nonnull @test_s)
9696
void test_s(void) {
9797
asm("// %0 %1 %2" :: "s"(&var), "s"(&arr[1][1]), "s"(test_s));
9898
asm("// %0" :: "s"(&pair.b));

clang/test/CodeGenCXX/auto-var-init.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,7 +1338,7 @@ TEST_UNINIT(base, base);
13381338
// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_base_uninit.uninit{{.+}}), !annotation [[AUTO_INIT]]
13391339
// ZERO-LABEL: @test_base_uninit()
13401340
// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,{{.+}}), !annotation [[AUTO_INIT]]
1341-
// ZERO-O1: store ptr getelementptr inbounds inrange(-16, 16) (i8, ptr @_ZTV4base, i64 16), {{.*}}, align 8
1341+
// ZERO-O1: store ptr getelementptr inbounds nuw inrange(-16, 16) (i8, ptr @_ZTV4base, i64 16), {{.*}}, align 8
13421342
// ZERO-O1-NOT: !annotation
13431343

13441344
TEST_BRACES(base, base);
@@ -1359,7 +1359,7 @@ TEST_UNINIT(derived, derived);
13591359
// ZERO-LABEL: @test_derived_uninit()
13601360
// ZERO-O0: call void @llvm.memset{{.*}}, i8 0, {{.+}}), !annotation [[AUTO_INIT]]
13611361
// ZERO-O1: store i64 0, {{.*}} align 8, !annotation [[AUTO_INIT]]
1362-
// ZERO-O1: store ptr getelementptr inbounds inrange(-16, 16) (i8, ptr @_ZTV7derived, i64 16), {{.*}} align 8
1362+
// ZERO-O1: store ptr getelementptr inbounds nuw inrange(-16, 16) (i8, ptr @_ZTV7derived, i64 16), {{.*}} align 8
13631363

13641364
TEST_BRACES(derived, derived);
13651365
// CHECK-LABEL: @test_derived_braces()

llvm/lib/Analysis/ConstantFolding.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -952,7 +952,6 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
952952
}
953953

954954
// Try to infer inbounds for GEPs of globals.
955-
// TODO(gep_nowrap): Also infer nuw flag.
956955
if (!NW.isInBounds() && Offset.isNonNegative()) {
957956
bool CanBeNull, CanBeFreed;
958957
uint64_t DerefBytes =
@@ -961,6 +960,10 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
961960
NW |= GEPNoWrapFlags::inBounds();
962961
}
963962

963+
// nusw + nneg -> nuw
964+
if (NW.hasNoUnsignedSignedWrap() && Offset.isNonNegative())
965+
NW |= GEPNoWrapFlags::noUnsignedWrap();
966+
964967
// Otherwise canonicalize this to a single ptradd.
965968
LLVMContext &Ctx = Ptr->getContext();
966969
return ConstantExpr::getGetElementPtr(Type::getInt8Ty(Ctx), Ptr,

llvm/test/Other/constant-fold-gep.ll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,10 @@
106106

107107
; PLAIN: @Y = global ptr getelementptr inbounds ([3 x { i32, i32 }], ptr getelementptr inbounds ([3 x { i32, i32 }], ptr @ext, i64 1), i64 1)
108108
; PLAIN: @Z = global ptr getelementptr inbounds (i32, ptr getelementptr inbounds ([3 x { i32, i32 }], ptr @ext, i64 0, i64 1, i32 0), i64 1)
109-
; OPT: @Y = local_unnamed_addr global ptr getelementptr inbounds (i8, ptr @ext, i64 48)
110-
; OPT: @Z = local_unnamed_addr global ptr getelementptr inbounds (i8, ptr @ext, i64 12)
111-
; TO: @Y = local_unnamed_addr global ptr getelementptr inbounds (i8, ptr @ext, i64 48)
112-
; TO: @Z = local_unnamed_addr global ptr getelementptr inbounds (i8, ptr @ext, i64 12)
109+
; OPT: @Y = local_unnamed_addr global ptr getelementptr inbounds nuw (i8, ptr @ext, i64 48)
110+
; OPT: @Z = local_unnamed_addr global ptr getelementptr inbounds nuw (i8, ptr @ext, i64 12)
111+
; TO: @Y = local_unnamed_addr global ptr getelementptr inbounds nuw (i8, ptr @ext, i64 48)
112+
; TO: @Z = local_unnamed_addr global ptr getelementptr inbounds nuw (i8, ptr @ext, i64 12)
113113

114114
@ext = external global [3 x { i32, i32 }]
115115
@Y = global ptr getelementptr inbounds ([3 x { i32, i32 }], ptr getelementptr inbounds ([3 x { i32, i32 }], ptr @ext, i64 1), i64 1)
@@ -433,10 +433,10 @@ define ptr @fO() nounwind {
433433
; PLAIN: ret ptr %t
434434
; PLAIN: }
435435
; OPT: define ptr @fZ() local_unnamed_addr #0 {
436-
; OPT: ret ptr getelementptr inbounds (i8, ptr @ext, i64 12)
436+
; OPT: ret ptr getelementptr inbounds nuw (i8, ptr @ext, i64 12)
437437
; OPT: }
438438
; TO: define ptr @fZ() local_unnamed_addr #0 {
439-
; TO: ret ptr getelementptr inbounds (i8, ptr @ext, i64 12)
439+
; TO: ret ptr getelementptr inbounds nuw (i8, ptr @ext, i64 12)
440440
; TO: }
441441
; SCEV: Classifying expressions for: @fZ
442442
; SCEV: %t = bitcast ptr getelementptr inbounds (i32, ptr getelementptr inbounds ([3 x { i32, i32 }], ptr @ext, i64 0, i64 1, i32 0), i64 1) to ptr
@@ -457,14 +457,14 @@ define ptr @different_addrspace() nounwind noinline {
457457
%p = getelementptr inbounds i8, ptr addrspacecast (ptr addrspace(12) @p12 to ptr),
458458
i32 2
459459
ret ptr %p
460-
; OPT: ret ptr getelementptr inbounds (i8, ptr addrspacecast (ptr addrspace(12) @p12 to ptr), i64 2)
460+
; OPT: ret ptr getelementptr inbounds nuw (i8, ptr addrspacecast (ptr addrspace(12) @p12 to ptr), i64 2)
461461
}
462462

463463
define ptr @same_addrspace() nounwind noinline {
464464
; OPT: same_addrspace
465465
%p = getelementptr inbounds i8, ptr @p0, i32 2
466466
ret ptr %p
467-
; OPT: ret ptr getelementptr inbounds (i8, ptr @p0, i64 2)
467+
; OPT: ret ptr getelementptr inbounds nuw (i8, ptr @p0, i64 2)
468468
}
469469

470470
@gv1 = internal global i32 1

llvm/test/Other/optimize-inrange-gep.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ define void @foo(ptr %p) {
2020
;
2121
; CHECK-LABEL: define void @foo(
2222
; CHECK-SAME: ptr nocapture writeonly initializes((0, 8)) [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
23-
; CHECK-NEXT: store ptr getelementptr inbounds inrange(-24, 0) (i8, ptr @vtable, i64 24), ptr [[P]], align 8
23+
; CHECK-NEXT: store ptr getelementptr inbounds nuw inrange(-24, 0) (i8, ptr @vtable, i64 24), ptr [[P]], align 8
2424
; CHECK-NEXT: ret void
2525
;
2626
store ptr getelementptr inrange(-24, 0) ({ [3 x ptr], [3 x ptr] }, ptr @vtable, i32 0, i32 0, i32 3), ptr %p

llvm/test/Transforms/FunctionSpecialization/function-specialization-constant-expression.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@ define internal i64 @zoo(i1 %flag) {
3030
; CHECK-NEXT: entry:
3131
; CHECK-NEXT: br i1 [[FLAG:%.*]], label [[PLUS:%.*]], label [[MINUS:%.*]]
3232
; CHECK: plus:
33-
; CHECK-NEXT: [[TMP0:%.*]] = call i64 @func2.specialized.2(ptr getelementptr inbounds (i8, ptr @Global, i64 8))
33+
; CHECK-NEXT: [[TMP0:%.*]] = call i64 @func2.specialized.2(ptr getelementptr inbounds nuw (i8, ptr @Global, i64 8))
3434
; CHECK-NEXT: br label [[MERGE:%.*]]
3535
; CHECK: minus:
36-
; CHECK-NEXT: [[TMP1:%.*]] = call i64 @func2.specialized.1(ptr getelementptr inbounds (i8, ptr @Global, i64 16))
36+
; CHECK-NEXT: [[TMP1:%.*]] = call i64 @func2.specialized.1(ptr getelementptr inbounds nuw (i8, ptr @Global, i64 16))
3737
; CHECK-NEXT: br label [[MERGE]]
3838
; CHECK: merge:
39-
; CHECK-NEXT: [[TMP2:%.*]] = phi i64 [ ptrtoint (ptr getelementptr inbounds (i8, ptr @Global, i64 8) to i64), [[PLUS]] ], [ ptrtoint (ptr getelementptr inbounds (i8, ptr @Global, i64 16) to i64), [[MINUS]] ]
39+
; CHECK-NEXT: [[TMP2:%.*]] = phi i64 [ ptrtoint (ptr getelementptr inbounds nuw (i8, ptr @Global, i64 8) to i64), [[PLUS]] ], [ ptrtoint (ptr getelementptr inbounds nuw (i8, ptr @Global, i64 16) to i64), [[MINUS]] ]
4040
; CHECK-NEXT: ret i64 [[TMP2]]
4141
;
4242
entry:

llvm/test/Transforms/GVN/PRE/load-pre-licm.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ target triple = "i386-apple-darwin11.0.0"
88
define void @Bubble() nounwind noinline {
99
; CHECK-LABEL: @Bubble(
1010
; CHECK-NEXT: entry:
11-
; CHECK-NEXT: [[TMP7_PRE:%.*]] = load i32, ptr getelementptr inbounds (i8, ptr @sortlist, i32 4), align 4
11+
; CHECK-NEXT: [[TMP7_PRE:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @sortlist, i32 4), align 4
1212
; CHECK-NEXT: br label [[WHILE_BODY5:%.*]]
1313
; CHECK: while.body5:
1414
; CHECK-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP7_PRE]], [[ENTRY:%.*]] ], [ [[TMP71:%.*]], [[IF_END:%.*]] ]

llvm/test/Transforms/GVN/PRE/phi-translate-2.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ define void @test2(i64 %i) {
6363
; CHECK: if.then:
6464
; CHECK-NEXT: [[CALL:%.*]] = tail call i64 (...) @goo()
6565
; CHECK-NEXT: store i64 [[CALL]], ptr @g2, align 8
66-
; CHECK-NEXT: [[T2_PRE:%.*]] = load i64, ptr getelementptr inbounds (i8, ptr @a, i64 24), align 8
67-
; CHECK-NEXT: [[T3_PRE:%.*]] = load i64, ptr getelementptr inbounds (i8, ptr @b, i64 24), align 8
66+
; CHECK-NEXT: [[T2_PRE:%.*]] = load i64, ptr getelementptr inbounds nuw (i8, ptr @a, i64 24), align 8
67+
; CHECK-NEXT: [[T3_PRE:%.*]] = load i64, ptr getelementptr inbounds nuw (i8, ptr @b, i64 24), align 8
6868
; CHECK-NEXT: [[DOTPRE:%.*]] = mul nsw i64 [[T3_PRE]], [[T2_PRE]]
6969
; CHECK-NEXT: br label [[IF_END]]
7070
; CHECK: if.end:
@@ -272,7 +272,7 @@ define void @test6(ptr %ptr, i1 %arg) {
272272
; CHECK-NEXT: br label [[IF_END]]
273273
; CHECK: if.end:
274274
; CHECK-NEXT: [[TMP2]] = phi i32 [ [[TMP0]], [[IF_THEN]] ], [ [[TMP1]], [[WHILE]] ]
275-
; CHECK-NEXT: br i1 %arg, label [[WHILE_END:%.*]], label [[WHILE]]
275+
; CHECK-NEXT: br i1 [[ARG:%.*]], label [[WHILE_END:%.*]], label [[WHILE]]
276276
; CHECK: while.end:
277277
; CHECK-NEXT: ret void
278278
;

llvm/test/Transforms/IndVarSimplify/eliminate-exit-no-dl.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ define void @foo() {
1414
; CHECK-NEXT: bb:
1515
; CHECK-NEXT: br label [[BB3:%.*]]
1616
; CHECK: bb3:
17-
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr getelementptr inbounds (i8, ptr @global, i64 1), align 1
17+
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr getelementptr inbounds nuw (i8, ptr @global, i64 1), align 1
1818
; CHECK-NEXT: br i1 false, label [[BB7:%.*]], label [[BB11:%.*]]
1919
; CHECK: bb7:
2020
; CHECK-NEXT: [[TMP8:%.*]] = zext i8 [[TMP6]] to i64

llvm/test/Transforms/IndVarSimplify/floating-point-small-iv.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ define void @uitofp_fptoui_range_with_negative() {
357357
; CHECK-NEXT: entry:
358358
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
359359
; CHECK: for.body:
360-
; CHECK-NEXT: store i32 100, ptr getelementptr inbounds (i8, ptr @array, i64 400), align 4
360+
; CHECK-NEXT: store i32 100, ptr getelementptr inbounds nuw (i8, ptr @array, i64 400), align 4
361361
; CHECK-NEXT: br i1 false, label [[FOR_BODY]], label [[CLEANUP:%.*]]
362362
; CHECK: cleanup:
363363
; CHECK-NEXT: ret void
@@ -418,7 +418,7 @@ define void @uitofp_fptosi_range_with_negative () {
418418
; CHECK-NEXT: entry:
419419
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
420420
; CHECK: for.body:
421-
; CHECK-NEXT: store i32 100, ptr getelementptr inbounds (i8, ptr @array, i64 400), align 4
421+
; CHECK-NEXT: store i32 100, ptr getelementptr inbounds nuw (i8, ptr @array, i64 400), align 4
422422
; CHECK-NEXT: br i1 false, label [[FOR_BODY]], label [[CLEANUP:%.*]]
423423
; CHECK: cleanup:
424424
; CHECK-NEXT: ret void

0 commit comments

Comments
 (0)