Skip to content

Commit 478c159

Browse files
fangyi-zhoulanza
authored andcommitted
[CIR] Fix offset calculation for global view (llvm#1627)
This commit attempts to un-xfail `globals-ref-globals` test (llvm#1497), which was causing a crash in addition to GEP changes. The crash was caused by incorrect offsets being calculated for global view indices. The original calculation did not take paddings into consideration, hence triggering a crash. This commit adds type alignment when calculating the offset, which will take care of paddings. Further modification to `globals-ref-globals` test includes fixing some struct names that got changed, as well as replacing the expects with constant folded GEP.
1 parent 3df6a22 commit 478c159

File tree

2 files changed

+16
-22
lines changed

2 files changed

+16
-22
lines changed

clang/lib/CIR/CodeGen/CIRGenBuilder.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ uint64_t CIRGenBuilderTy::computeOffsetFromGlobalViewIndices(
128128
for (int64_t idx : indexes) {
129129
if (auto sTy = dyn_cast<cir::RecordType>(typ)) {
130130
offset += sTy.getElementOffset(layout.layout, idx);
131+
// Align the offset to the type alignment. This is needed for getting
132+
// paddings correctly.
133+
const llvm::Align tyAlign = llvm::Align(
134+
sTy.getPacked() ? 1 : layout.layout.getTypeABIAlignment(typ));
135+
offset = llvm::alignTo(offset, tyAlign);
131136
assert(idx < (int64_t)sTy.getMembers().size());
132137
typ = sTy.getMembers()[idx];
133138
} else if (auto arTy = dyn_cast<cir::ArrayType>(typ)) {

clang/test/CIR/CodeGen/globals-ref-globals.c

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// RUN: FileCheck --input-file=%t.cir %s
33
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll
44
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
5-
// XFAIL: *
65

76
typedef struct {
87
int f0 : 24;
@@ -22,7 +21,7 @@ static int **g8 = &g7[1];
2221

2322
// CHECK-DAG: !rec_anon_struct = !cir.record<struct {!u8i, !u8i, !u8i, !u8i, !s32i, !s32i}>
2423
// CHECK-DAG: !rec_anon_struct1 = !cir.record<struct {!s8i, !cir.array<!u8i x 3>, !s32i}>
25-
// CHECK-DAG: !rec_anon_struct2 = !cir.record<struct {!u8i, !u8i, !u8i, !u8i, !u8i, !u8i, !u8i, !u8i, !rec_S4_}>
24+
// CHECK-DAG: !rec_anon_struct2 = !cir.record<struct {!u8i, !u8i, !u8i, !u8i, !u8i, !u8i, !u8i, !u8i, !rec_S4}>
2625
// CHECK-DAG: !rec_anon_struct3 = !cir.record<struct {!s16i, !cir.array<!u8i x 2>, !s32i, !s8i, !cir.array<!u8i x 3>}>
2726

2827
// CHECK-DAG: g1 = #cir.const_record<{#cir.int<239> : !u8i, #cir.int<10> : !u8i, #cir.int<0> : !u8i, #cir.zero : !u8i, #cir.int<9> : !s32i, #cir.int<123> : !s32i}> : !rec_anon_struct
@@ -35,18 +34,13 @@ static int **g8 = &g7[1];
3534
// CHECK-DAG: g8 = #cir.global_view<@g7, [1 : i32]> : !cir.ptr<!cir.ptr<!s32i>>
3635

3736
// LLVM-DAG: @g1 = internal global { i8, i8, i8, i8, i32, i32 } { i8 -17, i8 10, i8 0, i8 0, i32 9, i32 123 }, align 4
38-
// LLVM-DAG: @g2 = internal global [4 x ptr] [ptr getelementptr inbounds ({ i8, i8, i8, i8, i32, i32 }, ptr @g1, i32 0, i32 4), ptr getelementptr inbounds ({ i8, i8, i8, i8, i32, i32 }, ptr @g1, i32 0, i32 4), ptr getelementptr inbounds ({ i8, i8, i8, i8, i32, i32 }, ptr @g1, i32 0, i32 4), ptr getelementptr inbounds ({ i8, i8, i8, i8, i32, i32 }, ptr @g1, i32 0, i32 4)], align 16
39-
// LLVM-DAG: @g3 = internal global ptr getelementptr inbounds ([4 x ptr], ptr @g2, i32 0, i32 1), align 8
37+
// LLVM-DAG: @g2 = internal global [4 x ptr] [ptr getelementptr inbounds nuw (i8, ptr @g1, i64 4), ptr getelementptr inbounds nuw (i8, ptr @g1, i64 4), ptr getelementptr inbounds nuw (i8, ptr @g1, i64 4), ptr getelementptr inbounds nuw (i8, ptr @g1, i64 4)], align 16
38+
// LLVM-DAG: @g3 = internal global ptr getelementptr inbounds nuw (i8, ptr @g2, i64 8), align 8
4039
// LLVM-DAG: @g4 = internal global ptr @g3, align 8
4140
// LLVM-DAG: @g5 = internal global ptr @g4, align 8
4241
// LLVM-DAG: @g6 = internal global [2 x { i8, i8, i8, i8, i32, i32 }] [{ i8, i8, i8, i8, i32, i32 } { i8 -17, i8 10, i8 0, i8 0, i32 9, i32 123 }, { i8, i8, i8, i8, i32, i32 } { i8 -17, i8 10, i8 0, i8 0, i32 9, i32 123 }], align 16
43-
// LLVM-DAG: @g7 = internal global [2 x ptr] [ptr getelementptr inbounds ([2 x { i8, i8, i8, i8, i32, i32 }], ptr @g6, i32 0, i32 0, i32 5), ptr getelementptr inbounds ([2 x { i8, i8, i8, i8, i32, i32 }], ptr @g6, i32 0, i32 1, i32 5)], align 16
44-
// LLVM-DAG: @g8 = internal global ptr getelementptr inbounds ([2 x ptr], ptr @g7, i32 0, i32 1), align 8
45-
46-
// FIXME: LLVM output should be: @g2 = internal global [4 x ptr] [ptr getelementptr (i8, ptr @g1, i64 4), ptr getelementptr (i8, ptr @g1, i64 4), ptr getelementptr (i8, ptr @g1, i64 4), ptr getelementptr (i8, ptr @g1, i64 4)], align 16
47-
// FIXME: LLVM output should be: @g3 = internal global ptr getelementptr (i8, ptr @g2, i64 8), align 8
48-
// FIXME: LLVM output should be: @g7 = internal global [2 x ptr] [ptr getelementptr (i8, ptr @g6, i64 8), ptr getelementptr (i8, ptr @g6, i64 20)], align 16
49-
// FIXME: LLVM output should be: @g8 = internal global ptr getelementptr (i8, ptr @g7, i64 8), align 8
42+
// LLVM-DAG: @g7 = internal global [2 x ptr] [ptr getelementptr inbounds nuw (i8, ptr @g6, i64 8), ptr getelementptr inbounds nuw (i8, ptr @g6, i64 20)], align 16
43+
// LLVM-DAG: @g8 = internal global ptr getelementptr inbounds nuw (i8, ptr @g7, i64 8), align 8
5044

5145
typedef struct {
5246
char f1;
@@ -69,16 +63,13 @@ int* g12 = &g11.f6;
6963

7064
// CHECK-DAG: g9 = #cir.const_record<{#cir.int<1> : !s8i, #cir.const_array<[#cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i]> : !cir.array<!u8i x 3>, #cir.int<42> : !s32i}> : !rec_anon_struct1 {alignment = 4 : i64}
7165
// CHECK-DAG: g10 = #cir.global_view<@g9, [2 : i32]> : !cir.ptr<!s32i> {alignment = 8 : i64}
72-
// CHECK-DAG: g11 = #cir.const_record<{#cir.int<1> : !s8i, #cir.int<42> : !s32i}> : !rec_S2_ {alignment = 1 : i64}
66+
// CHECK-DAG: g11 = #cir.const_record<{#cir.int<1> : !s8i, #cir.int<42> : !s32i}> : !rec_S2 {alignment = 1 : i64}
7367
// CHECK-DAG: g12 = #cir.global_view<@g11, [1 : i32]> : !cir.ptr<!s32i> {alignment = 8 : i64}
7468

7569
// LLVM-DAG: @g9 = global { i8, [3 x i8], i32 } { i8 1, [3 x i8] zeroinitializer, i32 42 }, align 4
76-
// LLVM-DAG: @g10 = global ptr getelementptr inbounds ({ i8, [3 x i8], i32 }, ptr @g9, i32 0, i32 2), align 8
70+
// LLVM-DAG: @g10 = global ptr getelementptr inbounds nuw (i8, ptr @g9, i64 4), align 8
7771
// LLVM-DAG: @g11 = global %struct.S2 <{ i8 1, i32 42 }>, align 1
78-
// LLVM-DAG: @g12 = global ptr getelementptr inbounds (%struct.S2, ptr @g11, i32 0, i32 1), align 8
79-
80-
// FIXME: LLVM output should be: @g10 = dso_local global ptr getelementptr (i8, ptr @g9, i64 4), align 8
81-
// FIXME: LLVM output should be: @g12 = dso_local global ptr getelementptr (i8, ptr @g11, i64 1), align 8
72+
// LLVM-DAG: @g12 = global ptr getelementptr inbounds nuw (i8, ptr @g11, i64 1), align 8
8273

8374

8475
typedef struct {
@@ -91,7 +82,7 @@ static S3 g13 = {-1L,0L,1L};
9182
static S3* g14[2][2] = {{0, &g13}, {&g13, &g13}};
9283

9384
// CHECK-DAG: g13 = #cir.const_record<{#cir.int<-1> : !s16i, #cir.const_array<[#cir.zero : !u8i, #cir.zero : !u8i]> : !cir.array<!u8i x 2>, #cir.int<0> : !s32i, #cir.int<1> : !s8i, #cir.const_array<[#cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i]> : !cir.array<!u8i x 3>}> : !rec_anon_struct3
94-
// CHECK-DAG: g14 = #cir.const_array<[#cir.const_array<[#cir.ptr<null> : !cir.ptr<!rec_S3_>, #cir.global_view<@g13> : !cir.ptr<!rec_S3_>]> : !cir.array<!cir.ptr<!rec_S3_> x 2>, #cir.const_array<[#cir.global_view<@g13> : !cir.ptr<!rec_S3_>, #cir.global_view<@g13> : !cir.ptr<!rec_S3_>]> : !cir.array<!cir.ptr<!rec_S3_> x 2>]> : !cir.array<!cir.array<!cir.ptr<!rec_S3_> x 2> x 2>
85+
// CHECK-DAG: g14 = #cir.const_array<[#cir.const_array<[#cir.ptr<null> : !cir.ptr<!rec_S3>, #cir.global_view<@g13> : !cir.ptr<!rec_S3>]> : !cir.array<!cir.ptr<!rec_S3> x 2>, #cir.const_array<[#cir.global_view<@g13> : !cir.ptr<!rec_S3>, #cir.global_view<@g13> : !cir.ptr<!rec_S3>]> : !cir.array<!cir.ptr<!rec_S3> x 2>]> : !cir.array<!cir.array<!cir.ptr<!rec_S3> x 2> x 2>
9586

9687
typedef struct {
9788
int f0;
@@ -109,13 +100,11 @@ static S5 g15 = {187,1,442,{123,321}};
109100

110101
int* g16 = &g15.f3.f1;
111102

112-
// CHECK-DAG: g15 = #cir.const_record<{#cir.int<187> : !u8i, #cir.int<0> : !u8i, #cir.int<2> : !u8i, #cir.zero : !u8i, #cir.int<186> : !u8i, #cir.int<1> : !u8i, #cir.int<0> : !u8i, #cir.zero : !u8i, #cir.const_record<{#cir.int<123> : !s32i, #cir.int<321> : !s32i}> : !rec_S4_}> : !rec_anon_struct2 {alignment = 4 : i64}
103+
// CHECK-DAG: g15 = #cir.const_record<{#cir.int<187> : !u8i, #cir.int<0> : !u8i, #cir.int<2> : !u8i, #cir.zero : !u8i, #cir.int<186> : !u8i, #cir.int<1> : !u8i, #cir.int<0> : !u8i, #cir.zero : !u8i, #cir.const_record<{#cir.int<123> : !s32i, #cir.int<321> : !s32i}> : !rec_S4}> : !rec_anon_struct2 {alignment = 4 : i64}
113104
// CHECK-DAG: g16 = #cir.global_view<@g15, [8, 1]> : !cir.ptr<!rec_anon_struct2> {alignment = 8 : i64}
114105

115106
// LLVM-DAG: @g15 = internal global { i8, i8, i8, i8, i8, i8, i8, i8, %struct.S4 } { i8 -69, i8 0, i8 2, i8 0, i8 -70, i8 1, i8 0, i8 0, %struct.S4 { i32 123, i32 321 } }, align 4
116-
// LLVM-DAG: @g16 = global ptr getelementptr inbounds ({ i8, i8, i8, i8, i8, i8, i8, i8, %struct.S4 }, ptr @g15, i32 0, i32 8, i32 1), align 8
117-
118-
// FIXME: LLVM output should be: @g16 = dso_local global ptr getelementptr (i8, ptr @g15, i64 12), align 8
107+
// LLVM-DAG: @g16 = global ptr getelementptr inbounds nuw (i8, ptr @g15, i64 12), align 8
119108

120109
void use() {
121110
int a = **g3;

0 commit comments

Comments
 (0)