Skip to content

Commit

Permalink
[ConstantFolding] Canonicalize constexpr GEPs to i8 (#89872)
Browse files Browse the repository at this point in the history
This patch canonicalizes constant expression GEPs to use i8 source
element type, aka ptradd. This is the ConstantFolding equivalent of the
InstCombine canonicalization introduced in #68882.

I believe all our optimizations working on constant expression GEPs
(like GlobalOpt etc) have already been switched to work on offsets, so I
don't expect any significant fallout from this change.

This is part of:
https://discourse.llvm.org/t/rfc-replacing-getelementptr-with-ptradd/68699
  • Loading branch information
nikic authored May 20, 2024
1 parent 2217d17 commit 8e8d259
Show file tree
Hide file tree
Showing 98 changed files with 561 additions and 585 deletions.
6 changes: 3 additions & 3 deletions clang/test/CodeGen/RISCV/riscv-inline-asm.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ extern int var, arr[2][2];
struct Pair { int a, b; } pair;

// CHECK-LABEL: test_s(
// CHECK: call void asm sideeffect "// $0 $1 $2", "s,s,s"(ptr nonnull @var, ptr nonnull getelementptr inbounds ([2 x [2 x i32]], ptr @arr, {{.*}}), ptr nonnull @test_s)
// CHECK: call void asm sideeffect "// $0", "s"(ptr nonnull getelementptr inbounds (%struct.Pair, ptr @pair, {{.*}}))
// CHECK: call void asm sideeffect "// $0 $1 $2", "S,S,S"(ptr nonnull @var, ptr nonnull getelementptr inbounds ([2 x [2 x i32]], ptr @arr, {{.*}}), ptr nonnull @test_s)
// 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)
// CHECK: call void asm sideeffect "// $0", "s"(ptr nonnull getelementptr inbounds (i8, ptr @pair, {{.*}}))
// 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)
void test_s(void) {
asm("// %0 %1 %2" :: "s"(&var), "s"(&arr[1][1]), "s"(test_s));
asm("// %0" :: "s"(&pair.b));
Expand Down
12 changes: 6 additions & 6 deletions clang/test/CodeGen/attr-counted-by.c
Original file line number Diff line number Diff line change
Expand Up @@ -1098,7 +1098,7 @@ int test12_a, test12_b;
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB20:[0-9]+]], i64 0) #[[ATTR10]], !nosanitize [[META2]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
// SANITIZE-WITH-ATTR: handler.type_mismatch6:
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr nonnull @[[GLOB21:[0-9]+]], i64 ptrtoint (ptr getelementptr inbounds ([[STRUCT_ANON_5:%.*]], ptr @test12_foo, i64 1, i32 0, i32 0, i32 0) to i64)) #[[ATTR10]], !nosanitize [[META2]]
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr nonnull @[[GLOB21:[0-9]+]], i64 ptrtoint (ptr getelementptr inbounds (i8, ptr @test12_foo, i64 4) to i64)) #[[ATTR10]], !nosanitize [[META2]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i32 @test12(
Expand All @@ -1111,7 +1111,7 @@ int test12_a, test12_b;
// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [6 x i32], ptr [[BAZ]], i64 0, i64 [[IDXPROM]]
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]]
// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[TMP0]], ptr @test12_b, align 4, !tbaa [[TBAA2]]
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr getelementptr inbounds ([[STRUCT_ANON_5:%.*]], ptr @test12_foo, i64 1, i32 0, i32 0, i32 0), align 4, !tbaa [[TBAA2]]
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr getelementptr inbounds (i8, ptr @test12_foo, i64 4), align 4, !tbaa [[TBAA2]]
// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[TMP1]], ptr @test12_a, align 4, !tbaa [[TBAA2]]
// NO-SANITIZE-WITH-ATTR-NEXT: br label [[FOR_COND:%.*]]
// NO-SANITIZE-WITH-ATTR: for.cond:
Expand Down Expand Up @@ -1140,7 +1140,7 @@ int test12_a, test12_b;
// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 0) #[[ATTR8]], !nosanitize [[META9]]
// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]]
// SANITIZE-WITHOUT-ATTR: handler.type_mismatch6:
// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 ptrtoint (ptr getelementptr inbounds ([[STRUCT_ANON_5:%.*]], ptr @test12_foo, i64 1, i32 0, i32 0, i32 0) to i64)) #[[ATTR8]], !nosanitize [[META9]]
// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 ptrtoint (ptr getelementptr inbounds (i8, ptr @test12_foo, i64 4) to i64)) #[[ATTR8]], !nosanitize [[META9]]
// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]]
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i32 @test12(
Expand All @@ -1153,7 +1153,7 @@ int test12_a, test12_b;
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [6 x i32], ptr [[BAZ]], i64 0, i64 [[IDXPROM]]
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]]
// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[TMP0]], ptr @test12_b, align 4, !tbaa [[TBAA2]]
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr getelementptr inbounds ([[STRUCT_ANON_5:%.*]], ptr @test12_foo, i64 1, i32 0, i32 0, i32 0), align 4, !tbaa [[TBAA2]]
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr getelementptr inbounds (i8, ptr @test12_foo, i64 4), align 4, !tbaa [[TBAA2]]
// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[TMP1]], ptr @test12_a, align 4, !tbaa [[TBAA2]]
// NO-SANITIZE-WITHOUT-ATTR-NEXT: br label [[FOR_COND:%.*]]
// NO-SANITIZE-WITHOUT-ATTR: for.cond:
Expand Down Expand Up @@ -1315,7 +1315,7 @@ int test14(int idx) {
// NO-SANITIZE-WITH-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR4]] {
// NO-SANITIZE-WITH-ATTR-NEXT: entry:
// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64
// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr getelementptr inbounds ([[STRUCT_ANON_8:%.*]], ptr @__const.test15.foo, i64 1, i32 0), i64 0, i64 [[IDXPROM]]
// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr getelementptr inbounds (i8, ptr @__const.test15.foo, i64 8), i64 0, i64 [[IDXPROM]]
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]]
// NO-SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP0]]
//
Expand All @@ -1336,7 +1336,7 @@ int test14(int idx) {
// NO-SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR1]] {
// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry:
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr getelementptr inbounds ([[STRUCT_ANON_8:%.*]], ptr @__const.test15.foo, i64 1, i32 0), i64 0, i64 [[IDXPROM]]
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr getelementptr inbounds (i8, ptr @__const.test15.foo, i64 8), i64 0, i64 [[IDXPROM]]
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]]
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP0]]
//
Expand Down
4 changes: 2 additions & 2 deletions clang/test/CodeGenCXX/atomicinit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ namespace PR18097 {
};
// CHECK-LABEL: define {{.*}} @__cxx_global_var_init
// CHECK: call void @_ZN7PR180977dynamic1XC1Ei(ptr {{[^,]*}} @_ZN7PR180977dynamic1yE, i32 noundef 4)
// CHECK: store i32 5, ptr getelementptr inbounds ({{.*}}, ptr @_ZN7PR180977dynamic1yE, i32 0, i32 1)
// CHECK: store i32 5, ptr getelementptr inbounds (i8, ptr @_ZN7PR180977dynamic1yE, i32 4)
Y y = { X(4), 5 };
}

Expand All @@ -110,7 +110,7 @@ namespace PR18097 {
// CHECK-LABEL: define {{.*}} @__cxx_global_var_init
// CHECK: tail call void @llvm.memcpy.p0.p0.i32(ptr{{.*}} @_ZN7PR180978constant2y2E, ptr{{.*}} @_ZN7PR180978constantL1xE, i32 3, i1 false)
// CHECK: %0 = load i32, ptr @_ZN7PR180978constant1zE
// CHECK: store i32 %0, ptr getelementptr inbounds (%"struct.PR18097::constant::Y", ptr @_ZN7PR180978constant2y2E, i32 0, i32 1)
// CHECK: store i32 %0, ptr getelementptr inbounds (i8, ptr @_ZN7PR180978constant2y2E, i32 4)
int z;
constexpr X x{1};
Y y2 = { x, z };
Expand Down
4 changes: 2 additions & 2 deletions clang/test/CodeGenCXX/auto-var-init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1346,7 +1346,7 @@ TEST_UNINIT(base, base);
// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_base_uninit.uninit{{.+}}), !annotation [[AUTO_INIT]]
// ZERO-LABEL: @test_base_uninit()
// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,{{.+}}), !annotation [[AUTO_INIT]]
// ZERO-O1: store ptr getelementptr inbounds inrange(-16, 16) ({ [4 x ptr] }, ptr @_ZTV4base, i64 0, i32 0, i64 2), {{.*}}, align 8
// ZERO-O1: store ptr getelementptr inbounds inrange(-16, 16) (i8, ptr @_ZTV4base, i64 16), {{.*}}, align 8
// ZERO-O1-NOT: !annotation

TEST_BRACES(base, base);
Expand All @@ -1367,7 +1367,7 @@ TEST_UNINIT(derived, derived);
// ZERO-LABEL: @test_derived_uninit()
// ZERO-O0: call void @llvm.memset{{.*}}, i8 0, {{.+}}), !annotation [[AUTO_INIT]]
// ZERO-O1: store i64 0, {{.*}} align 8, !annotation [[AUTO_INIT]]
// ZERO-O1: store ptr getelementptr inbounds inrange(-16, 16) ({ [4 x ptr] }, ptr @_ZTV7derived, i64 0, i32 0, i64 2), {{.*}} align 8
// ZERO-O1: store ptr getelementptr inbounds inrange(-16, 16) (i8, ptr @_ZTV7derived, i64 16), {{.*}} align 8

TEST_BRACES(derived, derived);
// CHECK-LABEL: @test_derived_braces()
Expand Down
4 changes: 2 additions & 2 deletions clang/test/Profile/c-unreachable-after-switch.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
// CHECK-LABEL: @foo()
// CHECK: store {{.*}} @[[C]]
void foo(void) {
// CHECK: store {{.*}} @[[C]], i64 0, i64 2
// CHECK: store {{.*}} @[[C]], i64 16)
switch (0) {
default:
return;
}
// We shouldn't emit the unreachable counter. This used to crash in GlobalDCE.
// CHECK-NOT: store {{.*}} @[[C]], i64 0, i64 1}
// CHECK-NOT: store {{.*}} @[[C]], i64 8)
}
20 changes: 10 additions & 10 deletions compiler-rt/test/profile/Linux/counter_promo_for.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,29 @@ __attribute__((noinline)) void bar(int i) { g += i; }

__attribute__((noinline)) void foo(int n, int N) {
// PROMO-LABEL: @foo
// PROMO: load{{.*}}@__profc_foo{{.*}} 3){{.*}}
// PROMO: load{{.*}}@__profc_foo{{.*}} 24){{.*}}
// PROMO-NEXT: add
// PROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 3){{.*}}
// PROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 24){{.*}}
// PROMO: load{{.*}}@__profc_foo, align
// PROMO-NEXT: add
// PROMO-NEXT: store{{.*}}@__profc_foo, align
// PROMO-NEXT: load{{.*}}@__profc_foo{{.*}} 1){{.*}}
// PROMO-NEXT: load{{.*}}@__profc_foo{{.*}} 8){{.*}}
// PROMO-NEXT: add
// PROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 1){{.*}}
// PROMO: load{{.*}}@__profc_foo{{.*}} 2){{.*}}
// PROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 8){{.*}}
// PROMO: load{{.*}}@__profc_foo{{.*}} 16){{.*}}
// PROMO-NEXT: add
// PROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 2){{.*}}
// PROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 16){{.*}}
//
// NOPROMO-LABEL: @foo
// NOPROMO: load{{.*}}@__profc_foo, align
// NOPROMO-NEXT: add
// NOPROMO-NEXT: store{{.*}}@__profc_foo, align
// NOPROMO: load{{.*}}@__profc_foo{{.*}} 1){{.*}}
// NOPROMO: load{{.*}}@__profc_foo{{.*}} 8){{.*}}
// NOPROMO-NEXT: add
// NOPROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 1){{.*}}
// NOPROMO: load{{.*}}@__profc_foo{{.*}} 2){{.*}}
// NOPROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 8){{.*}}
// NOPROMO: load{{.*}}@__profc_foo{{.*}} 16){{.*}}
// NOPROMO-NEXT: add
// NOPROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 2){{.*}}
// NOPROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 16){{.*}}
int i;
for (i = 0; i < N; i++) {
if (i < n + 1)
Expand Down
16 changes: 8 additions & 8 deletions compiler-rt/test/profile/Linux/counter_promo_while.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,23 @@ __attribute__((noinline)) void foo(int n, int N) {
// PROMO: load{{.*}}@__profc_foo, align
// PROMO-NEXT: add
// PROMO-NEXT: store{{.*}}@__profc_foo, align
// PROMO-NEXT: load{{.*}}@__profc_foo{{.*}} 1){{.*}}
// PROMO-NEXT: load{{.*}}@__profc_foo{{.*}} 8){{.*}}
// PROMO-NEXT: add
// PROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 1){{.*}}
// PROMO-NEXT: load{{.*}}@__profc_foo{{.*}} 2){{.*}}
// PROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 8){{.*}}
// PROMO-NEXT: load{{.*}}@__profc_foo{{.*}} 16){{.*}}
// PROMO-NEXT: add
// PROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 2){{.*}}
// PROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 16){{.*}}
//
// NOPROMO-LABEL: @foo
// NOPROMO: load{{.*}}@__profc_foo, align
// NOPROMO-NEXT: add
// NOPROMO-NEXT: store{{.*}}@__profc_foo, align
// NOPROMO: load{{.*}}@__profc_foo{{.*}} 1){{.*}}
// NOPROMO: load{{.*}}@__profc_foo{{.*}} 8){{.*}}
// NOPROMO-NEXT: add
// NOPROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 1){{.*}}
// NOPROMO: load{{.*}}@__profc_foo{{.*}} 2){{.*}}
// NOPROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 8){{.*}}
// NOPROMO: load{{.*}}@__profc_foo{{.*}} 16){{.*}}
// NOPROMO-NEXT: add
// NOPROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 2){{.*}}
// NOPROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 16){{.*}}
int i = 0;
while (i < N) {
if (i < n + 1)
Expand Down
46 changes: 10 additions & 36 deletions llvm/lib/Analysis/ConstantFolding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -869,7 +869,6 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
bool InBounds = GEP->isInBounds();

Type *SrcElemTy = GEP->getSourceElementType();
Type *ResElemTy = GEP->getResultElementType();
Type *ResTy = GEP->getType();
if (!SrcElemTy->isSized() || isa<ScalableVectorType>(SrcElemTy))
return nullptr;
Expand Down Expand Up @@ -944,43 +943,18 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
return ConstantExpr::getIntToPtr(C, ResTy);
}

// Otherwise form a regular getelementptr. Recompute the indices so that
// we eliminate over-indexing of the notional static type array bounds.
// This makes it easy to determine if the getelementptr is "inbounds".

// For GEPs of GlobalValues, use the value type, otherwise use an i8 GEP.
if (auto *GV = dyn_cast<GlobalValue>(Ptr))
SrcElemTy = GV->getValueType();
else
SrcElemTy = Type::getInt8Ty(Ptr->getContext());

if (!SrcElemTy->isSized())
return nullptr;

Type *ElemTy = SrcElemTy;
SmallVector<APInt> Indices = DL.getGEPIndicesForOffset(ElemTy, Offset);
if (Offset != 0)
return nullptr;

// Try to add additional zero indices to reach the desired result element
// type.
// TODO: Should we avoid extra zero indices if ResElemTy can't be reached and
// we'll have to insert a bitcast anyway?
while (ElemTy != ResElemTy) {
Type *NextTy = GetElementPtrInst::getTypeAtIndex(ElemTy, (uint64_t)0);
if (!NextTy)
break;

Indices.push_back(APInt::getZero(isa<StructType>(ElemTy) ? 32 : BitWidth));
ElemTy = NextTy;
// Try to infer inbounds for GEPs of globals.
if (!InBounds && Offset.isNonNegative()) {
bool CanBeNull, CanBeFreed;
uint64_t DerefBytes =
Ptr->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed);
InBounds = DerefBytes != 0 && !CanBeNull && Offset.sle(DerefBytes);
}

SmallVector<Constant *, 32> NewIdxs;
for (const APInt &Index : Indices)
NewIdxs.push_back(ConstantInt::get(
Type::getIntNTy(Ptr->getContext(), Index.getBitWidth()), Index));

return ConstantExpr::getGetElementPtr(SrcElemTy, Ptr, NewIdxs, InBounds,
// Otherwise canonicalize this to a single ptradd.
LLVMContext &Ctx = Ptr->getContext();
return ConstantExpr::getGetElementPtr(Type::getInt8Ty(Ctx), Ptr,
ConstantInt::get(Ctx, Offset), InBounds,
InRange);
}

Expand Down
14 changes: 7 additions & 7 deletions llvm/test/Other/constant-fold-gep.ll
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,10 @@

; PLAIN: @Y = global ptr getelementptr inbounds ([3 x { i32, i32 }], ptr @ext, i64 2)
; PLAIN: @Z = global ptr getelementptr inbounds (i32, ptr getelementptr inbounds ([3 x { i32, i32 }], ptr @ext, i64 0, i64 1, i32 0), i64 1)
; OPT: @Y = local_unnamed_addr global ptr getelementptr inbounds ([3 x { i32, i32 }], ptr @ext, i64 2)
; OPT: @Z = local_unnamed_addr global ptr getelementptr inbounds ([3 x { i32, i32 }], ptr @ext, i64 0, i64 1, i32 1)
; TO: @Y = local_unnamed_addr global ptr getelementptr inbounds ([3 x { i32, i32 }], ptr @ext, i64 2)
; TO: @Z = local_unnamed_addr global ptr getelementptr inbounds ([3 x { i32, i32 }], ptr @ext, i64 0, i64 1, i32 1)
; OPT: @Y = local_unnamed_addr global ptr getelementptr inbounds (i8, ptr @ext, i64 48)
; OPT: @Z = local_unnamed_addr global ptr getelementptr inbounds (i8, ptr @ext, i64 12)
; TO: @Y = local_unnamed_addr global ptr getelementptr inbounds (i8, ptr @ext, i64 48)
; TO: @Z = local_unnamed_addr global ptr getelementptr inbounds (i8, ptr @ext, i64 12)

@ext = external global [3 x { i32, i32 }]
@Y = global ptr getelementptr inbounds ([3 x { i32, i32 }], ptr getelementptr inbounds ([3 x { i32, i32 }], ptr @ext, i64 1), i64 1)
Expand Down Expand Up @@ -433,10 +433,10 @@ define ptr @fO() nounwind {
; PLAIN: ret ptr %t
; PLAIN: }
; OPT: define ptr @fZ() local_unnamed_addr #0 {
; OPT: ret ptr getelementptr inbounds ([3 x { i32, i32 }], ptr @ext, i64 0, i64 1, i32 1)
; OPT: ret ptr getelementptr inbounds (i8, ptr @ext, i64 12)
; OPT: }
; TO: define ptr @fZ() local_unnamed_addr #0 {
; TO: ret ptr getelementptr inbounds ([3 x { i32, i32 }], ptr @ext, i64 0, i64 1, i32 1)
; TO: ret ptr getelementptr inbounds (i8, ptr @ext, i64 12)
; TO: }
; SCEV: Classifying expressions for: @fZ
; 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
Expand Down Expand Up @@ -464,7 +464,7 @@ define ptr @same_addrspace() nounwind noinline {
; OPT: same_addrspace
%p = getelementptr inbounds i8, ptr @p0, i32 2
ret ptr %p
; OPT: ret ptr getelementptr inbounds ([4 x i8], ptr @p0, i64 0, i64 2)
; OPT: ret ptr getelementptr inbounds (i8, ptr @p0, i64 2)
}

@gv1 = internal global i32 1
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Other/optimize-inrange-gep.ll
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ define void @foo(ptr %p) {
;
; CHECK-LABEL: define void @foo(
; CHECK-SAME: ptr nocapture writeonly [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: store ptr getelementptr inbounds inrange(-24, 0) ({ [3 x ptr] }, ptr @vtable, i64 1, i32 0, i64 0), ptr [[P]], align 8
; CHECK-NEXT: store ptr getelementptr inbounds inrange(-24, 0) (i8, ptr @vtable, i64 24), ptr [[P]], align 8
; CHECK-NEXT: ret void
;
store ptr getelementptr inrange(-24, 0) ({ [3 x ptr], [3 x ptr] }, ptr @vtable, i32 0, i32 0, i32 3), ptr %p
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ define internal i64 @zoo(i1 %flag) {
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[FLAG:%.*]], label [[PLUS:%.*]], label [[MINUS:%.*]]
; CHECK: plus:
; CHECK-NEXT: [[TMP0:%.*]] = call i64 @func2.specialized.2(ptr getelementptr inbounds ([[STRUCT:%.*]], ptr @Global, i64 0, i32 3))
; CHECK-NEXT: [[TMP0:%.*]] = call i64 @func2.specialized.2(ptr getelementptr inbounds (i8, ptr @Global, i64 8))
; CHECK-NEXT: br label [[MERGE:%.*]]
; CHECK: minus:
; CHECK-NEXT: [[TMP1:%.*]] = call i64 @func2.specialized.1(ptr getelementptr inbounds ([[STRUCT]], ptr @Global, i64 0, i32 4))
; CHECK-NEXT: [[TMP1:%.*]] = call i64 @func2.specialized.1(ptr getelementptr inbounds (i8, ptr @Global, i64 16))
; CHECK-NEXT: br label [[MERGE]]
; CHECK: merge:
; CHECK-NEXT: [[TMP2:%.*]] = phi i64 [ ptrtoint (ptr getelementptr inbounds ([[STRUCT]], ptr @Global, i64 0, i32 3) to i64), [[PLUS]] ], [ ptrtoint (ptr getelementptr inbounds ([[STRUCT]], ptr @Global, i64 0, i32 4) to i64), [[MINUS]] ]
; 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]] ]
; CHECK-NEXT: ret i64 [[TMP2]]
;
entry:
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/GVN/PRE/load-pre-licm.ll
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ target triple = "i386-apple-darwin11.0.0"
define void @Bubble() nounwind noinline {
; CHECK-LABEL: @Bubble(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP7_PRE:%.*]] = load i32, ptr getelementptr inbounds ([5001 x i32], ptr @sortlist, i32 0, i32 1), align 4
; CHECK-NEXT: [[TMP7_PRE:%.*]] = load i32, ptr getelementptr inbounds (i8, ptr @sortlist, i32 4), align 4
; CHECK-NEXT: br label [[WHILE_BODY5:%.*]]
; CHECK: while.body5:
; CHECK-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP7_PRE]], [[ENTRY:%.*]] ], [ [[TMP71:%.*]], [[IF_END:%.*]] ]
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/Transforms/GVN/PRE/phi-translate-2.ll
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ define void @test2(i64 %i) {
; CHECK: if.then:
; CHECK-NEXT: [[CALL:%.*]] = tail call i64 (...) @goo()
; CHECK-NEXT: store i64 [[CALL]], ptr @g2, align 8
; CHECK-NEXT: [[T2_PRE:%.*]] = load i64, ptr getelementptr inbounds ([100 x i64], ptr @a, i64 0, i64 3), align 8
; CHECK-NEXT: [[T3_PRE:%.*]] = load i64, ptr getelementptr inbounds ([100 x i64], ptr @b, i64 0, i64 3), align 8
; CHECK-NEXT: [[T2_PRE:%.*]] = load i64, ptr getelementptr inbounds (i8, ptr @a, i64 24), align 8
; CHECK-NEXT: [[T3_PRE:%.*]] = load i64, ptr getelementptr inbounds (i8, ptr @b, i64 24), align 8
; CHECK-NEXT: [[DOTPRE:%.*]] = mul nsw i64 [[T3_PRE]], [[T2_PRE]]
; CHECK-NEXT: br label [[IF_END]]
; CHECK: if.end:
Expand Down
Loading

0 comments on commit 8e8d259

Please sign in to comment.