Skip to content

Commit cd9de81

Browse files
sitio-coutolanza
authored andcommitted
[CIR][CIRGen] Fix zero-offset global view access
Instead of ignoring global view access with zero offset, we should properly dereference the global type to prevent type-matching errors. This patch also fixes other two issues: - An extra index was wrongly added to the global view access. E.g. for an access like `a[0]` would generate a GV with 2 zero indexes. The indexes, however, do not take the pointer wrapping the global type into account. - When assigning the address of a complete type to an incomplete one the complete type would override the incomplete destination type, causing inconsistencies during CodeGen. For example, given `int a[3];` and `int (*ptr_a)[] = &a;`, despite `ptr_a`, in CIR it would be considered complete. Fixes llvm#329
1 parent bbf37b0 commit cd9de81

File tree

3 files changed

+56
-14
lines changed

3 files changed

+56
-14
lines changed

clang/lib/CIR/CodeGen/CIRGenExprConst.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,22 +1066,27 @@ class ConstantLValueEmitter
10661066
Indices.push_back(Attr);
10671067
}
10681068

1069+
if (Indices.empty())
1070+
return {};
10691071
return CGM.getBuilder().getArrayAttr(Indices);
10701072
}
10711073

10721074
// TODO(cir): create a proper interface to absctract CIR constant values.
10731075

10741076
/// Apply the value offset to the given constant.
10751077
ConstantLValue applyOffset(ConstantLValue &C) {
1076-
if (!hasNonZeroOffset())
1077-
return C;
10781078

1079-
if (auto Attr = C.Value.dyn_cast<mlir::Attribute>()) {
1080-
auto GV = cast<mlir::cir::GlobalViewAttr>(Attr);
1081-
assert(!GV.getIndices());
1082-
1083-
return mlir::cir::GlobalViewAttr::get(
1084-
GV.getType(), GV.getSymbol(), getOffset(GV.getType()));
1079+
// Handle attribute constant LValues.
1080+
if (auto Attr =
1081+
C.Value.dyn_cast<mlir::Attribute>()) {
1082+
if (auto GV = Attr.dyn_cast<mlir::cir::GlobalViewAttr>()) {
1083+
auto baseTy = GV.getType().cast<mlir::cir::PointerType>().getPointee();
1084+
auto destTy = CGM.getTypes().convertTypeForMem(DestType);
1085+
assert(!GV.getIndices() && "Global view is already indexed");
1086+
return mlir::cir::GlobalViewAttr::get(destTy, GV.getSymbol(),
1087+
getOffset(baseTy));
1088+
}
1089+
llvm_unreachable("Unsupported attribute type to offset");
10851090
}
10861091

10871092
// TODO(cir): use ptr_stride, or something...

clang/test/CIR/CodeGen/array.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,25 @@ struct S {
88
// CHECK: cir.global external @arr = #cir.const_array<[#cir.const_struct<{#cir.int<1> : !s32i}> : !ty_22S22, #cir.zero : !ty_22S22, #cir.zero : !ty_22S22]> : !cir.array<!ty_22S22 x 3>
99

1010
int a[4];
11-
int (*ptr_a)[] = &a;
1211
// CHECK: cir.global external @a = #cir.zero : !cir.array<!s32i x 4>
13-
// CHECK: cir.global external @ptr_a = #cir.global_view<@a> : !cir.ptr<!cir.array<!s32i x 4>>
1412

13+
// Should create a pointer to a complete array.
14+
int (*complete_ptr_a)[4] = &a;
15+
// CHECK: cir.global external @complete_ptr_a = #cir.global_view<@a> : !cir.ptr<!cir.array<!s32i x 4>>
16+
17+
// Should create a pointer to an incomplete array.
18+
int (*incomplete_ptr_a)[] = &a;
19+
// CHECK: cir.global external @incomplete_ptr_a = #cir.global_view<@a> : !cir.ptr<!cir.array<!s32i x 0>>
20+
21+
// Should access incomplete array if external.
1522
extern int foo[];
1623
// CHECK: cir.global "private" external @foo : !cir.array<!s32i x 0>
17-
1824
void useFoo(int i) {
1925
foo[i] = 42;
20-
}
26+
}
27+
// CHECK: @useFoo
28+
// CHECK: %[[#V2:]] = cir.get_global @foo : cir.ptr <!cir.array<!s32i x 0>>
29+
// CHECK: %[[#V3:]] = cir.load %{{.+}} : cir.ptr <!s32i>, !s32i
30+
// CHECK: %[[#V4:]] = cir.cast(array_to_ptrdecay, %[[#V2]] : !cir.ptr<!cir.array<!s32i x 0>>), !cir.ptr<!s32i>
31+
// CHECK: %[[#V5:]] = cir.ptr_stride(%[[#V4]] : !cir.ptr<!s32i>, %[[#V3]] : !s32i), !cir.ptr<!s32i>
32+
// CHECK: cir.store %{{.+}}, %[[#V5]] : !s32i, cir.ptr <!s32i>

clang/test/CIR/CodeGen/globals.c

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
// bit different from the C++ version. This test ensures that these differences
44
// are accounted for.
55

6-
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-cir %s -o - | FileCheck %s
6+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-cir %s -o %t.cir
7+
// RUN: FileCheck --input-file=%t.cir %s
78

89
char string[] = "whatnow";
910
// CHECK: cir.global external @string = #cir.const_array<"whatnow\00" : !cir.array<!s8i x 8>> : !cir.array<!s8i x 8>
@@ -48,7 +49,31 @@ struct {
4849
// CHECK: cir.global external @nestedStringPtr = #cir.const_struct<{#cir.global_view<@".str"> : !cir.ptr<!s8i>}>
4950

5051
int *globalPtr = &nestedString.y[1];
51-
// CHECK: cir.global external @globalPtr = #cir.global_view<@nestedString, [0 : i32, 1 : i32, 1 : i32]>
52+
// CHECK: cir.global external @globalPtr = #cir.global_view<@nestedString, [1 : i32, 1 : i32]> : !cir.ptr<!s32i>
53+
54+
const int i = 12;
55+
int i2 = i;
56+
struct { int i; } i3 = {i};
57+
// CHECK: cir.global external @i2 = #cir.int<12> : !s32i
58+
// CHECK: cir.global external @i3 = #cir.const_struct<{#cir.int<12> : !s32i}> : !ty_22anon2E722
59+
60+
int a[10][10][10];
61+
int *a2 = &a[3][0][8];
62+
struct { int *p; } a3 = {&a[3][0][8]};
63+
// CHECK: cir.global external @a2 = #cir.global_view<@a, [3 : i32, 0 : i32, 8 : i32]> : !cir.ptr<!s32i>
64+
// CHECK: cir.global external @a3 = #cir.const_struct<{#cir.global_view<@a, [3 : i32, 0 : i32, 8 : i32]> : !cir.ptr<!s32i>}> : !ty_22anon2E922
65+
66+
int p[10];
67+
int *p1 = &p[0];
68+
struct { int *x; } p2 = {&p[0]};
69+
// CHECK: cir.global external @p1 = #cir.global_view<@p> : !cir.ptr<!s32i>
70+
// CHECK: cir.global external @p2 = #cir.const_struct<{#cir.global_view<@p> : !cir.ptr<!s32i>}> : !ty_22anon2E1122
71+
72+
int q[10];
73+
int *q1 = q;
74+
struct { int *x; } q2 = {q};
75+
// CHECK: cir.global external @q1 = #cir.global_view<@q> : !cir.ptr<!s32i>
76+
// CHECK: cir.global external @q2 = #cir.const_struct<{#cir.global_view<@q> : !cir.ptr<!s32i>}> : !ty_22anon2E1322
5277

5378
// TODO: test tentatives with internal linkage.
5479

0 commit comments

Comments
 (0)