Skip to content

Commit a42534e

Browse files
tommymcmxlauko
andauthored
[CIR] Extend CIR canonicalize to rewrite ptr_stride and array_to_ptrdecay to get_element when possible (#1761)
Extended the `CIRCanonicalizePass` with new rewrite rules: - Rewrite `ptr_stride (cast array_to_ptrdecay %base), %index` to `get_element %base[%index]` - Rewrite `ptr_stride (get_element %base[%index]), %stride` to `get_element %base[%index + %stride]` - Rewrite `cast array_to_ptrdecay %base, ptr<T>` to `get_element %base[0], ptr<T>` if it is only used by `load %ptr : T`, `store %val : T, %ptr`, or `get_member %ptr[field] : ptr<T> -> U` Updated CodeGen tests, and extended CIR-to-CIR test. --------- Co-authored-by: Henrich Lauko <[email protected]>
1 parent 83da585 commit a42534e

File tree

14 files changed

+186
-93
lines changed

14 files changed

+186
-93
lines changed

clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "mlir/IR/Region.h"
1515
#include "mlir/Support/LogicalResult.h"
1616
#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
17+
#include "clang/CIR/Dialect/IR/CIRDataLayout.h"
1718
#include "clang/CIR/Dialect/IR/CIRDialect.h"
1819
#include "clang/CIR/Dialect/Passes.h"
1920

@@ -138,6 +139,77 @@ struct SimplifyCallOp : public OpRewritePattern<CallOp> {
138139
}
139140
};
140141

142+
struct SimplifyPtrStrideOp : public OpRewritePattern<PtrStrideOp> {
143+
using OpRewritePattern<PtrStrideOp>::OpRewritePattern;
144+
LogicalResult matchAndRewrite(PtrStrideOp op,
145+
PatternRewriter &rewriter) const override {
146+
mlir::Value base = op.getBase(), index = op.getStride();
147+
if (auto castOp = base.getDefiningOp<cir::CastOp>()) {
148+
// REWRITE ptr_stride(cast array_to_ptrdecay %base), %index)
149+
// => get_element %base[%index]
150+
if (castOp.getKind() != cir::CastKind::array_to_ptrdecay)
151+
return mlir::failure();
152+
153+
base = castOp.getOperand();
154+
155+
} else if (auto getElemOp = base.getDefiningOp<cir::GetElementOp>()) {
156+
// REWRITE ptr_stride(get_element %base[%index]), %stride)
157+
// => get_element %base[%index + %stride]
158+
auto elemIndex = getElemOp.getIndex();
159+
if (elemIndex.getType() != index.getType())
160+
return mlir::failure();
161+
162+
base = getElemOp.getBase();
163+
index = rewriter.create<cir::BinOp>(op->getLoc(), cir::BinOpKind::Add,
164+
elemIndex, index);
165+
166+
} else {
167+
return mlir::failure();
168+
}
169+
rewriter.replaceOpWithNewOp<cir::GetElementOp>(op, op.getType(), base,
170+
index);
171+
return mlir::success();
172+
}
173+
};
174+
175+
struct SimplifyCastOp : public OpRewritePattern<cir::CastOp> {
176+
using OpRewritePattern<cir::CastOp>::OpRewritePattern;
177+
LogicalResult matchAndRewrite(cir::CastOp op,
178+
PatternRewriter &rewriter) const override {
179+
if (op.getKind() != cir::CastKind::array_to_ptrdecay)
180+
return mlir::failure();
181+
182+
auto elemTy = cast<cir::PointerType>(op.getType()).getPointee();
183+
for (auto *user : op->getUsers()) {
184+
if (auto loadOp = dyn_cast<cir::LoadOp>(user)) {
185+
if (elemTy != loadOp.getType())
186+
return mlir::failure();
187+
} else if (auto storeOp = dyn_cast<cir::StoreOp>(user)) {
188+
if (storeOp.getAddr() != op.getResult() ||
189+
elemTy != storeOp.getValue().getType())
190+
return mlir::failure();
191+
} else if (isa<cir::GetMemberOp>(user)) {
192+
continue;
193+
} else {
194+
return mlir::failure();
195+
}
196+
}
197+
198+
// REWRITE cast array_to_ptrdecay %base
199+
// => get_element %base[0]
200+
auto *context = elemTy.getContext();
201+
CIRDataLayout dataLayout(op->getParentOfType<ModuleOp>());
202+
auto intType = cast<cir::IntType>(dataLayout.getIntType(context));
203+
auto zeroAttr = rewriter.getAttr<cir::IntAttr>(
204+
intType, llvm::APInt(intType.getWidth(), 0));
205+
auto index = rewriter.create<cir::ConstantOp>(op->getLoc(), zeroAttr);
206+
207+
rewriter.replaceOpWithNewOp<cir::GetElementOp>(op, op.getType(),
208+
op.getOperand(), index);
209+
return mlir::success();
210+
}
211+
};
212+
141213
//===----------------------------------------------------------------------===//
142214
// CIRCanonicalizePass
143215
//===----------------------------------------------------------------------===//
@@ -163,7 +235,9 @@ void populateCIRCanonicalizePatterns(RewritePatternSet &patterns) {
163235
RemoveEmptyScope,
164236
RemoveEmptySwitch,
165237
RemoveTrivialTry,
166-
SimplifyCallOp
238+
SimplifyCallOp,
239+
SimplifyPtrStrideOp,
240+
SimplifyCastOp
167241
>(patterns.getContext());
168242
// clang-format on
169243
}
@@ -181,7 +255,7 @@ void CIRCanonicalizePass::runOnOperation() {
181255
if (isa<BrOp, BrCondOp, ScopeOp, SwitchOp, CastOp, TryOp, UnaryOp, SelectOp,
182256
ComplexCreateOp, ComplexRealOp, ComplexImagOp, CallOp, VecCmpOp,
183257
VecCreateOp, VecExtractOp, VecShuffleOp, VecShuffleDynamicOp,
184-
VecTernaryOp>(op))
258+
VecTernaryOp, PtrStrideOp>(op))
185259
ops.push_back(op);
186260
});
187261

clang/test/CIR/CodeGen/OpenCL/array-decay.cl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ kernel void func1(global int *data) {
1919
// LLVM: @func2
2020
kernel void func2(global int *data) {
2121
private int arr[32] = {data[2]};
22-
// CIR: %{{[0-9]+}} = cir.cast(array_to_ptrdecay, %{{[0-9]+}} : !cir.ptr<!cir.array<!s32i x 32>, addrspace(offload_private)>), !cir.ptr<!s32i, addrspace(offload_private)>
22+
// CIR: %{{[0-9]+}} = cir.get_element %{{[0-9]+}}[%{{[0-9]+}}] : (!cir.ptr<!cir.array<!s32i x 32>, addrspace(offload_private)>, !s32i) -> !cir.ptr<!s32i, addrspace(offload_private)>
2323

24-
// LLVM: %{{[0-9]+}} = getelementptr i32, ptr %3, i32 0
24+
// LLVM: %{{[0-9]+}} = getelementptr [32 x i32], ptr %3, i32 0, i64 0
2525
}

clang/test/CIR/CodeGen/array-init.c

Lines changed: 52 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,30 @@ typedef struct {
1010
} T;
1111

1212
void buz(int x) {
13-
T arr[] = { {0, x}, {0, 0} };
13+
T arr[] = { {x, x}, {0, 0} };
1414
}
1515
// CIR: cir.func dso_local @buz
1616
// CIR-NEXT: [[X_ALLOCA:%.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init] {alignment = 4 : i64}
1717
// CIR-NEXT: [[ARR:%.*]] = cir.alloca !cir.array<!rec_T x 2>, !cir.ptr<!cir.array<!rec_T x 2>>, ["arr", init] {alignment = 16 : i64}
1818
// CIR-NEXT: cir.store{{.*}} %arg0, [[X_ALLOCA]] : !s32i, !cir.ptr<!s32i>
19-
// CIR-NEXT: [[ARR_INIT:%.*]] = cir.const #cir.zero : !cir.array<!rec_T x 2>
20-
// CIR-NEXT: cir.store{{.*}} [[ARR_INIT]], [[ARR]] : !cir.array<!rec_T x 2>, !cir.ptr<!cir.array<!rec_T x 2>>
21-
// CIR-NEXT: [[FI_EL:%.*]] = cir.cast(array_to_ptrdecay, [[ARR]] : !cir.ptr<!cir.array<!rec_T x 2>>), !cir.ptr<!rec_T>
19+
// CIR-NEXT: [[ZERO:%.*]] = cir.const #cir.int<0> : !s32i
20+
// CIR-NEXT: [[FI_EL:%.*]] = cir.get_element [[ARR]][[[ZERO]]] : (!cir.ptr<!cir.array<!rec_T x 2>>, !s32i) -> !cir.ptr<!rec_T>
2221
// CIR-NEXT: [[A_STORAGE0:%.*]] = cir.get_member [[FI_EL]][0] {name = "a"} : !cir.ptr<!rec_T> -> !cir.ptr<!s32i>
22+
// CIR-NEXT: [[XA_VAL:%.*]] = cir.load{{.*}} [[X_ALLOCA]] : !cir.ptr<!s32i>, !s32i
23+
// CIR-NEXT: cir.store{{.*}} [[XA_VAL]], [[A_STORAGE0]] : !s32i, !cir.ptr<!s32i>
2324
// CIR-NEXT: [[B_STORAGE0:%.*]] = cir.get_member [[FI_EL]][1] {name = "b"} : !cir.ptr<!rec_T> -> !cir.ptr<!s64i>
24-
// CIR-NEXT: [[X_VAL:%.*]] = cir.load{{.*}} [[X_ALLOCA]] : !cir.ptr<!s32i>, !s32i
25-
// CIR-NEXT: [[X_CASTED:%.*]] = cir.cast(integral, [[X_VAL]] : !s32i), !s64i
26-
// CIR-NEXT: cir.store{{.*}} [[X_CASTED]], [[B_STORAGE0]] : !s64i, !cir.ptr<!s64i>
25+
// CIR-NEXT: [[XB_VAL:%.*]] = cir.load{{.*}} [[X_ALLOCA]] : !cir.ptr<!s32i>, !s32i
26+
// CIR-NEXT: [[XB_CASTED:%.*]] = cir.cast(integral, [[XB_VAL]] : !s32i), !s64i
27+
// CIR-NEXT: cir.store{{.*}} [[XB_CASTED]], [[B_STORAGE0]] : !s64i, !cir.ptr<!s64i>
2728
// CIR-NEXT: [[ONE:%.*]] = cir.const #cir.int<1> : !s64i
28-
// CIR-NEXT: [[SE_EL:%.*]] = cir.ptr_stride([[FI_EL]] : !cir.ptr<!rec_T>, [[ONE]] : !s64i), !cir.ptr<!rec_T>
29+
// CIR-NEXT: [[SE_EL:%.*]] = cir.get_element [[ARR]][[[ONE]]] : (!cir.ptr<!cir.array<!rec_T x 2>>, !s64i) -> !cir.ptr<!rec_T>
2930
// CIR-NEXT: [[A_STORAGE1:%.*]] = cir.get_member [[SE_EL]][0] {name = "a"} : !cir.ptr<!rec_T> -> !cir.ptr<!s32i>
31+
// CIR-NEXT: [[A1_ZERO:%.*]] = cir.const #cir.int<0> : !s32i
32+
// CIR-NEXT: cir.store{{.*}} [[A1_ZERO]], [[A_STORAGE1]] : !s32i, !cir.ptr<!s32i>
3033
// CIR-NEXT: [[B_STORAGE1:%.*]] = cir.get_member [[SE_EL]][1] {name = "b"} : !cir.ptr<!rec_T> -> !cir.ptr<!s64i>
34+
// CIR-NEXT: [[B1_ZERO:%.*]] = cir.const #cir.int<0> : !s32i
35+
// CIR-NEXT: [[B1_CASTED:%.*]] = cir.cast(integral, [[B1_ZERO]] : !s32i), !s64i
36+
// CIR-NEXT: cir.store{{.*}} [[B1_CASTED]], [[B_STORAGE1]] : !s64i, !cir.ptr<!s64i>
3137
// CIR-NEXT: cir.return
3238

3339
void foo() {
@@ -46,34 +52,36 @@ void bar(int a, int b, int c) {
4652
// CIR-NEXT: cir.store{{.*}} %arg0, [[A:%.*]] : !s32i, !cir.ptr<!s32i>
4753
// CIR-NEXT: cir.store{{.*}} %arg1, [[B:%.*]] : !s32i, !cir.ptr<!s32i>
4854
// CIR-NEXT: cir.store{{.*}} %arg2, [[C:%.*]] : !s32i, !cir.ptr<!s32i>
49-
// CIR-NEXT: [[FI_EL:%.*]] = cir.cast(array_to_ptrdecay, [[ARR]] : !cir.ptr<!cir.array<!s32i x 3>>), !cir.ptr<!s32i>
55+
// CIR-NEXT: [[ZERO:%.*]] = cir.const #cir.int<0> : !s32i
56+
// CIR-NEXT: [[ELEM0:%.*]] = cir.get_element [[ARR]][[[ZERO]]] : (!cir.ptr<!cir.array<!s32i x 3>>, !s32i) -> !cir.ptr<!s32i>
5057
// CIR-NEXT: [[LOAD_A:%.*]] = cir.load{{.*}} [[A]] : !cir.ptr<!s32i>, !s32i
51-
// CIR-NEXT: cir.store{{.*}} [[LOAD_A]], [[FI_EL]] : !s32i, !cir.ptr<!s32i>
58+
// CIR-NEXT: cir.store{{.*}} [[LOAD_A]], [[ELEM0]] : !s32i, !cir.ptr<!s32i>
5259
// CIR-NEXT: [[ONE:%.*]] = cir.const #cir.int<1> : !s64i
53-
// CIR-NEXT: [[SE_EL:%.*]] = cir.ptr_stride(%4 : !cir.ptr<!s32i>, [[ONE]] : !s64i), !cir.ptr<!s32i>
60+
// CIR-NEXT: [[ELEM1:%.*]] = cir.get_element [[ARR]][[[ONE]]] : (!cir.ptr<!cir.array<!s32i x 3>>, !s64i) -> !cir.ptr<!s32i>
5461
// CIR-NEXT: [[LOAD_B:%.*]] = cir.load{{.*}} [[B]] : !cir.ptr<!s32i>, !s32i
55-
// CIR-NEXT: cir.store{{.*}} [[LOAD_B]], [[SE_EL]] : !s32i, !cir.ptr<!s32i>
62+
// CIR-NEXT: cir.store{{.*}} [[LOAD_B]], [[ELEM1]] : !s32i, !cir.ptr<!s32i>
5663
// CIR-NEXT: [[TWO:%.*]] = cir.const #cir.int<2> : !s64i
57-
// CIR-NEXT: [[TH_EL:%.*]] = cir.ptr_stride(%4 : !cir.ptr<!s32i>, [[TWO]] : !s64i), !cir.ptr<!s32i>
64+
// CIR-NEXT: [[ELEM2:%.*]] = cir.get_element [[ARR]][[[TWO]]] : (!cir.ptr<!cir.array<!s32i x 3>>, !s64i) -> !cir.ptr<!s32i>
5865
// CIR-NEXT: [[LOAD_C:%.*]] = cir.load{{.*}} [[C]] : !cir.ptr<!s32i>, !s32i
59-
// CIR-NEXT: cir.store{{.*}} [[LOAD_C]], [[TH_EL]] : !s32i, !cir.ptr<!s32i>
66+
// CIR-NEXT: cir.store{{.*}} [[LOAD_C]], [[ELEM2]] : !s32i, !cir.ptr<!s32i>
6067

6168
void zero_init(int x) {
6269
int arr[3] = {x};
6370
}
6471
// CIR: cir.func dso_local @zero_init
6572
// CIR: [[VAR_ALLOC:%.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init] {alignment = 4 : i64}
66-
// CIR: %1 = cir.alloca !cir.array<!s32i x 3>, !cir.ptr<!cir.array<!s32i x 3>>, ["arr", init] {alignment = 4 : i64}
73+
// CIR: [[ARR:%.*]] = cir.alloca !cir.array<!s32i x 3>, !cir.ptr<!cir.array<!s32i x 3>>, ["arr", init] {alignment = 4 : i64}
6774
// CIR: [[TEMP:%.*]] = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["arrayinit.temp", init] {alignment = 8 : i64}
6875
// CIR: cir.store{{.*}} %arg0, [[VAR_ALLOC]] : !s32i, !cir.ptr<!s32i>
69-
// CIR: [[BEGIN:%.*]] = cir.cast(array_to_ptrdecay, %1 : !cir.ptr<!cir.array<!s32i x 3>>), !cir.ptr<!s32i>
76+
// CIR: [[ZERO:%.*]] = cir.const #cir.int<0> : !s32i
77+
// CIR: [[BEGIN:%.*]] = cir.get_element [[ARR]][[[ZERO]]] : (!cir.ptr<!cir.array<!s32i x 3>>, !s32i) -> !cir.ptr<!s32i>
7078
// CIR: [[VAR:%.*]] = cir.load{{.*}} [[VAR_ALLOC]] : !cir.ptr<!s32i>, !s32i
7179
// CIR: cir.store{{.*}} [[VAR]], [[BEGIN]] : !s32i, !cir.ptr<!s32i>
7280
// CIR: [[ONE:%.*]] = cir.const #cir.int<1> : !s64i
73-
// CIR: [[ZERO_INIT_START:%.*]] = cir.ptr_stride([[BEGIN]] : !cir.ptr<!s32i>, [[ONE]] : !s64i), !cir.ptr<!s32i>
81+
// CIR: [[ZERO_INIT_START:%.*]] = cir.get_element [[ARR]][[[ONE]]] : (!cir.ptr<!cir.array<!s32i x 3>>, !s64i) -> !cir.ptr<!s32i>
7482
// CIR: cir.store{{.*}} [[ZERO_INIT_START]], [[TEMP]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
7583
// CIR: [[SIZE:%.*]] = cir.const #cir.int<3> : !s64i
76-
// CIR: [[END:%.*]] = cir.ptr_stride([[BEGIN]] : !cir.ptr<!s32i>, [[SIZE]] : !s64i), !cir.ptr<!s32i>
84+
// CIR: [[END:%.*]] = cir.get_element [[ARR]][[[SIZE]]] : (!cir.ptr<!cir.array<!s32i x 3>>, !s64i) -> !cir.ptr<!s32i>
7785
// CIR: cir.do {
7886
// CIR: [[CUR:%.*]] = cir.load{{.*}} [[TEMP]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
7987
// CIR: [[FILLER:%.*]] = cir.const #cir.int<0> : !s32i
@@ -99,26 +107,28 @@ void aggr_init() {
99107
// CIR: [[TEMP:%.*]] = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["arrayinit.temp", init] {alignment = 8 : i64}
100108
// CIR: %3 = cir.const #cir.int<5> : !s32i
101109
// CIR: cir.store{{.*}} %3, [[VAR_ALLOC]] : !s32i, !cir.ptr<!s32i>
102-
// CIR: [[BEGIN:%.*]] = cir.cast(array_to_ptrdecay, %1 : !cir.ptr<!cir.array<!s32i x 5>>), !cir.ptr<!s32i>
103-
// CIR: %5 = cir.const #cir.int<1> : !s32i
104-
// CIR: cir.store{{.*}} %5, [[BEGIN]] : !s32i, !cir.ptr<!s32i>
105-
// CIR: [[ONE:%.*]] = cir.const #cir.int<1> : !s64i
106-
// CIR: %7 = cir.ptr_stride([[BEGIN]] : !cir.ptr<!s32i>, [[ONE]] : !s64i), !cir.ptr<!s32i>
107-
// CIR: %8 = cir.const #cir.int<2> : !s32i
108-
// CIR: cir.store{{.*}} %8, %7 : !s32i, !cir.ptr<!s32i>
109-
// CIR: [[TWO:%.*]] = cir.const #cir.int<2> : !s64i
110-
// CIR: %10 = cir.ptr_stride([[BEGIN]] : !cir.ptr<!s32i>, [[TWO]] : !s64i), !cir.ptr<!s32i>
111-
// CIR: %11 = cir.const #cir.int<3> : !s32i
112-
// CIR: cir.store{{.*}} %11, %10 : !s32i, !cir.ptr<!s32i>
113-
// CIR: [[THREE:%.*]] = cir.const #cir.int<3> : !s64i
114-
// CIR: %13 = cir.ptr_stride([[BEGIN]] : !cir.ptr<!s32i>, [[THREE]] : !s64i), !cir.ptr<!s32i>
110+
// CIR: [[OFFSET0:%.*]] = cir.const #cir.int<0> : !s32i
111+
// CIR: [[BEGIN:%.*]] = cir.get_element %1[[[OFFSET0]]] : (!cir.ptr<!cir.array<!s32i x 5>>, !s32i) -> !cir.ptr<!s32i>
112+
// CIR: [[ONE:%.*]] = cir.const #cir.int<1> : !s32i
113+
// CIR: cir.store{{.*}} [[ONE]], [[BEGIN]] : !s32i, !cir.ptr<!s32i>
114+
// CIR: [[OFFSET1:%.*]] = cir.const #cir.int<1> : !s64i
115+
// CIR: [[ELEM1:%.*]] = cir.get_element %1[[[OFFSET1]]] : (!cir.ptr<!cir.array<!s32i x 5>>, !s64i) -> !cir.ptr<!s32i>
116+
// CIR: [[TWO:%.*]] = cir.const #cir.int<2> : !s32i
117+
// CIR: cir.store{{.*}} [[TWO]], [[ELEM1]] : !s32i, !cir.ptr<!s32i>
118+
// CIR: [[OFFSET2:%.*]] = cir.const #cir.int<2> : !s64i
119+
// CIR: [[ELEM2:%.*]] = cir.get_element %1[[[OFFSET2]]] : (!cir.ptr<!cir.array<!s32i x 5>>, !s64i) -> !cir.ptr<!s32i>
120+
// CIR: [[THREE:%.*]] = cir.const #cir.int<3> : !s32i
121+
// CIR: cir.store{{.*}} [[THREE]], [[ELEM2]] : !s32i, !cir.ptr<!s32i>
122+
// CIR: [[OFFSET3:%.*]] = cir.const #cir.int<3> : !s64i
123+
// CIR: [[ELEM3:%.*]] = cir.get_element %1[[[OFFSET3]]] : (!cir.ptr<!cir.array<!s32i x 5>>, !s64i) -> !cir.ptr<!s32i>
115124
// CIR: [[VAR:%.*]] = cir.load{{.*}} [[VAR_ALLOC]] : !cir.ptr<!s32i>, !s32i
116-
// CIR: cir.store{{.*}} [[VAR]], %13 : !s32i, !cir.ptr<!s32i>
125+
// CIR: cir.store{{.*}} [[VAR]], [[ELEM3]] : !s32i, !cir.ptr<!s32i>
117126
// CIR: [[ONE_VAR:%.*]] = cir.const #cir.int<1> : !s64i
118-
// CIR: %16 = cir.ptr_stride(%13 : !cir.ptr<!s32i>, [[ONE_VAR]] : !s64i), !cir.ptr<!s32i>
119-
// CIR: cir.store{{.*}} %16, [[TEMP]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
127+
// CIR: [[OFFSET4:%.*]] = cir.binop(add, [[OFFSET3]], [[ONE_VAR]]) : !s64i
128+
// CIR: [[LAST:%.*]] = cir.get_element %1[[[OFFSET4]]] : (!cir.ptr<!cir.array<!s32i x 5>>, !s64i) -> !cir.ptr<!s32i>
129+
// CIR: cir.store{{.*}} [[LAST]], [[TEMP]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
120130
// CIR: [[SIZE:%.*]] = cir.const #cir.int<5> : !s64i
121-
// CIR: [[END:%.*]] = cir.ptr_stride([[BEGIN]] : !cir.ptr<!s32i>, [[SIZE]] : !s64i), !cir.ptr<!s32i>
131+
// CIR: [[END:%.*]] = cir.get_element %1[[[SIZE]]] : (!cir.ptr<!cir.array<!s32i x 5>>, !s64i) -> !cir.ptr<!s32i>
122132
// CIR: cir.do {
123133
// CIR: [[CUR:%.*]] = cir.load{{.*}} [[TEMP]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
124134
// CIR: [[FILLER:%.*]] = cir.const #cir.int<0> : !s32i
@@ -139,18 +149,18 @@ void aggr_init() {
139149
// LLVM: %2 = alloca [5 x i32], i64 1, align 16
140150
// LLVM: [[TEMP:%.*]] = alloca ptr, i64 1, align 8
141151
// LLVM: store i32 5, ptr [[VAR_ALLOC]], align 4
142-
// LLVM: [[BEGIN:%.*]] = getelementptr i32, ptr %2, i32 0
152+
// LLVM: [[BEGIN:%.*]] = getelementptr [5 x i32], ptr %2, i32 0, i64 0
143153
// LLVM: store i32 1, ptr [[BEGIN]], align 4
144-
// LLVM: [[ONE:%.*]] = getelementptr i32, ptr [[BEGIN]], i64 1
154+
// LLVM: [[ONE:%.*]] = getelementptr [5 x i32], ptr %2, i32 0, i64 1
145155
// LLVM: store i32 2, ptr [[ONE]], align 4
146-
// LLVM: [[TWO:%.*]] = getelementptr i32, ptr [[BEGIN]], i64 2
156+
// LLVM: [[TWO:%.*]] = getelementptr [5 x i32], ptr %2, i32 0, i64 2
147157
// LLVM: store i32 3, ptr [[TWO]], align 4
148-
// LLVM: [[THREE:%.*]] = getelementptr i32, ptr [[BEGIN]], i64 3
158+
// LLVM: [[THREE:%.*]] = getelementptr [5 x i32], ptr %2, i32 0, i64 3
149159
// LLVM: [[VAR:%.*]] = load i32, ptr [[VAR_ALLOC]], align 4
150160
// LLVM: store i32 [[VAR]], ptr [[THREE]], align 4
151-
// LLVM: %9 = getelementptr i32, ptr [[THREE]], i64 1
152-
// LLVM: store ptr %9, ptr [[TEMP]], align 8
153-
// LLVM: [[END:%.*]] = getelementptr i32, ptr [[BEGIN]], i64 5
161+
// LLVM: [[LAST:%.*]] = getelementptr [5 x i32], ptr %2, i32 0, i64 4
162+
// LLVM: store ptr [[LAST]], ptr [[TEMP]], align 8
163+
// LLVM: [[END:%.*]] = getelementptr [5 x i32], ptr %2, i32 0, i64 5
154164
// LLVM: br label %14
155165
//
156166
// LLVM: 11: ; preds = %14

clang/test/CIR/CodeGen/array-init.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ void foo() {
2222
// CHECK: %[[VAL_5:.*]] = cir.cast(array_to_ptrdecay, %[[VAL_4]] : !cir.ptr<!cir.array<!s32i x 2>>), !cir.ptr<!s32i>
2323
// CHECK: cir.store{{.*}} %[[VAL_5]], %[[VAL_1]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
2424
// CHECK: %[[VAL_6:.*]] = cir.const #cir.int<2> : !s64i
25-
// CHECK: %[[VAL_7:.*]] = cir.ptr_stride(%[[VAL_5]] : !cir.ptr<!s32i>, %[[VAL_6]] : !s64i), !cir.ptr<!s32i>
25+
// CHECK: %[[VAL_7:.*]] = cir.get_element %[[VAL_4]][%[[VAL_6]]] : (!cir.ptr<!cir.array<!s32i x 2>>, !s64i) -> !cir.ptr<!s32i>
2626
// CHECK: cir.do {
2727
// CHECK: %[[VAL_8:.*]] = cir.load{{.*}} %[[VAL_1]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
2828
// CHECK: %[[VAL_9:.*]] = cir.const #cir.int<0> : !s32i

clang/test/CIR/CodeGen/array.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,20 +70,24 @@ struct S {
7070

7171
void testPointerDecaySubscriptAccess(int arr[]) {
7272
// CHECK: cir.func dso_local @{{.+}}testPointerDecaySubscriptAccess
73-
arr[1];
73+
arr[1] = 2;
74+
// CHECK: %[[#TWO:]] = cir.const #cir.int<2> : !s32i
7475
// CHECK: %[[#BASE:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
7576
// CHECK: %[[#DIM1:]] = cir.const #cir.int<1> : !s32i
76-
// CHECK: cir.ptr_stride(%[[#BASE]] : !cir.ptr<!s32i>, %[[#DIM1]] : !s32i), !cir.ptr<!s32i>
77+
// CHECK: %[[#ELEM:]] = cir.ptr_stride(%[[#BASE]] : !cir.ptr<!s32i>, %[[#DIM1]] : !s32i), !cir.ptr<!s32i>
78+
// CHECK: cir.store{{.*}} %[[#TWO]], %[[#ELEM]] : !s32i, !cir.ptr<!s32i>
7779
}
7880

7981
void testPointerDecayedArrayMultiDimSubscriptAccess(int arr[][3]) {
8082
// CHECK: cir.func dso_local @{{.+}}testPointerDecayedArrayMultiDimSubscriptAccess
81-
arr[1][2];
83+
arr[1][2] = 3;
84+
// CHECK: %[[#THREE:]] = cir.const #cir.int<3> : !s32i
8285
// CHECK: %[[#ARRAY:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!cir.array<!s32i x 3>>>, !cir.ptr<!cir.array<!s32i x 3>>
8386
// CHECK: %[[#ONE:]] = cir.const #cir.int<1> : !s32i
8487
// CHECK: %[[#OUTER:]] = cir.ptr_stride(%[[#ARRAY]] : !cir.ptr<!cir.array<!s32i x 3>>, %[[#ONE]] : !s32i), !cir.ptr<!cir.array<!s32i x 3>>
8588
// CHECK: %[[#TWO:]] = cir.const #cir.int<2> : !s32i
8689
// CHECK: %[[#INNER:]] = cir.get_element %[[#OUTER]][%[[#TWO]]] : (!cir.ptr<!cir.array<!s32i x 3>>, !s32i) -> !cir.ptr<!s32i>
90+
// CHECK: cir.store{{.*}} %[[#THREE]], %[[#INNER]] : !s32i, !cir.ptr<!s32i>
8791
}
8892

8993
void testArrayOfComplexType() { int _Complex a[4]; }

clang/test/CIR/CodeGen/clear_cache.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@ char buffer[32] = "This is a largely unused buffer";
1313
// CIR: %[[VAL_2:.*]] = cir.cast(array_to_ptrdecay, %[[VAL_1]] : !cir.ptr<!cir.array<!s8i x 32>>), !cir.ptr<!s8i>
1414
// CIR: %[[VAL_3:.*]] = cir.cast(bitcast, %[[VAL_2]] : !cir.ptr<!s8i>), !cir.ptr<!void>
1515
// CIR: %[[VAL_4:.*]] = cir.get_global @buffer : !cir.ptr<!cir.array<!s8i x 32>>
16-
// CIR: %[[VAL_5:.*]] = cir.cast(array_to_ptrdecay, %[[VAL_4]] : !cir.ptr<!cir.array<!s8i x 32>>), !cir.ptr<!s8i>
1716
// CIR: %[[VAL_6:.*]] = cir.const #cir.int<32> : !s32i
18-
// CIR: %[[VAL_7:.*]] = cir.ptr_stride(%[[VAL_5]] : !cir.ptr<!s8i>, %[[VAL_6]] : !s32i), !cir.ptr<!s8i>
17+
// CIR: %[[VAL_7:.*]] = cir.get_element %[[VAL_4]][%[[VAL_6]]] : (!cir.ptr<!cir.array<!s8i x 32>>, !s32i) -> !cir.ptr<!s8i>
1918
// CIR: %[[VAL_8:.*]] = cir.cast(bitcast, %[[VAL_7]] : !cir.ptr<!s8i>), !cir.ptr<!void>
2019
// CIR: cir.clear_cache %[[VAL_3]] : !cir.ptr<!void>, %[[VAL_8]],
2120

0 commit comments

Comments
 (0)