Skip to content

Commit c45b338

Browse files
[CIR] Fix error in cir.label when using cir.br in entry block (#1939)
This PR fixes an error I found while working on `cir.indirectbr`. The issue occurs when a branching operator points to the entry block LLVM’s verifier does not allow this https://github.com/llvm/clangir/blob/10f2ee11fa61bb1550819ed54a5b0e111d9243aa/mlir/lib/IR/Verifier.cpp#L205-L208 Previously, in `cir.label`, when building a block, we only checked if the current block was not empty. Now, we also check if we are in the entry block. If we are, a new block is created instead. This change also helps emit IR that is closer to the classic code behavior.
1 parent 700e98e commit c45b338

File tree

3 files changed

+33
-14
lines changed

3 files changed

+33
-14
lines changed

clang/lib/CIR/CodeGen/CIRGenStmt.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,7 @@ mlir::LogicalResult CIRGenFunction::emitLabel(const LabelDecl *D) {
643643
// to this label.
644644
mlir::Block *currBlock = builder.getBlock();
645645
mlir::Block *labelBlock = currBlock;
646-
if (!currBlock->empty()) {
646+
if (!currBlock->empty() || currBlock->isEntryBlock()) {
647647
{
648648
mlir::OpBuilder::InsertionGuard guard(builder);
649649
labelBlock = builder.createBlock(builder.getBlock()->getParent());

clang/test/CIR/CodeGen/goto.cpp

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,15 @@ int g2() {
6868
// CHECK-NEXT: [[R]] : !s32i
6969
// CHECK-NEXT: }
7070

71+
void g3() {
72+
label:
73+
goto label;
74+
}
75+
76+
// CHECK: cir.func dso_local @_Z2g3v
77+
// CHECK: cir.br ^bb1
78+
// CHECK: ^bb1:
79+
// CHECK: cir.br ^bb1
7180

7281
int shouldNotGenBranchRet(int x) {
7382
if (x > 5)
@@ -189,7 +198,7 @@ int jumpFromLoop(int* ar) {
189198
if (!ar) {
190199
err:
191200
return -1;
192-
}
201+
}
193202

194203
while (ar) {
195204
if (*ar == 42)
@@ -200,14 +209,16 @@ int jumpFromLoop(int* ar) {
200209
return 0;
201210
}
202211
// CHECK: cir.func dso_local @_Z12jumpFromLoopPi
203-
// CHECK: cir.brcond {{.*}} ^bb[[#RETURN1:]], ^bb[[#BLK3:]]
212+
// CHECK: cir.brcond {{.*}} ^bb[[#LABELERR:]], ^bb[[#BLK4:]]
213+
// CHECK: ^bb[[#LABELERR]]:
214+
// CHECK: cir.br ^bb[[#RETURN1:]]
204215
// CHECK: ^bb[[#RETURN1]]:
205216
// CHECK: cir.return
206-
// CHECK: ^bb[[#BLK3]]:
207-
// CHECK: cir.br ^bb[[#BLK4:]]
208217
// CHECK: ^bb[[#BLK4]]:
209218
// CHECK: cir.br ^bb[[#BLK5:]]
210219
// CHECK: ^bb[[#BLK5]]:
220+
// CHECK: cir.br ^bb[[#BLK6:]]
221+
// CHECK: ^bb[[#BLK6]]:
211222
// CHECK: cir.br ^bb[[#COND:]]
212223
// CHECK: ^bb[[#COND]]:
213224
// CHECK: cir.brcond {{.*}} ^bb[[#BODY:]], ^bb[[#EXIT:]]
@@ -254,23 +265,27 @@ void flatLoopWithNoTerminatorInFront(int* ptr) {
254265
// CHECK: cir.br ^bb[[#BLK5:]]
255266
// CHECK: ^bb[[#BLK5]]:
256267
// CHECK: cir.br ^bb[[#BODY:]]
257-
// CHECK: ^bb[[#COND]]:
268+
// CHECK: ^bb[[#COND:]]:
258269
// CHECK: cir.brcond {{.*}} ^bb[[#BODY]], ^bb[[#EXIT:]]
259270
// CHECK: ^bb[[#BODY]]:
260271
// CHECK: cir.br ^bb[[#BLK8:]]
261272
// CHECK: ^bb[[#BLK8]]:
262-
// CHECK: cir.brcond {{.*}} ^bb[[#BLK9:]], ^bb[[#BLK10:]]
273+
// CHECK: cir.br ^bb[[#BLK9:]]
263274
// CHECK: ^bb[[#BLK9]]:
264-
// CHECK: cir.br ^bb[[#RETURN:]]
275+
// CHECK: cir.brcond {{.*}} ^bb[[#BLK10:]], ^bb[[#BLK11:]]
265276
// CHECK: ^bb[[#BLK10]]:
266-
// CHECK: cir.br ^bb[[#BLK11:]]
277+
// CHECK: cir.br ^bb[[#RETURN:]]
267278
// CHECK: ^bb[[#BLK11]]:
279+
// CHECK: cir.br ^bb[[#BLK12:]]
280+
// CHECK: ^bb[[#BLK12]]:
268281
// CHECK: cir.br ^bb[[#LABEL_LOOP]]
269282
// CHECK: ^bb[[#LABEL_LOOP]]:
270-
// CHECK: cir.br ^bb[[#COND]]
271-
// CHECK: ^bb[[#EXIT]]:
272283
// CHECK: cir.br ^bb[[#BLK14:]]
273284
// CHECK: ^bb[[#BLK14]]:
285+
// CHECK: cir.br ^bb[[#COND]]
286+
// CHECK: ^bb[[#EXIT]]:
287+
// CHECK: cir.br ^bb[[#BLK16:]]
288+
// CHECK: ^bb[[#BLK16]]:
274289
// CHECK: cir.br ^bb[[#RETURN]]
275290
// CHECK: ^bb[[#RETURN]]:
276291
// CHECK: cir.return
@@ -290,8 +305,10 @@ void foo() {
290305

291306
// NOFLAT: cir.func dso_local @_Z3foov()
292307
// NOFLAT: cir.scope {
293-
// NOFLAT: cir.label "label"
294308
// NOFLAT: %0 = cir.alloca !rec_S, !cir.ptr<!rec_S>, ["agg.tmp0"]
309+
// NOFLAT: cir.br ^bb1
310+
// NOFLAT: ^bb1:
311+
// NOFLAT: cir.label "label"
295312

296313
extern "C" void action1();
297314
extern "C" void action2();

clang/test/CIR/CodeGen/label-values.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,18 @@ void B(void) {
4141
}
4242

4343
// CIR: cir.func dso_local @B()
44-
// CIR: cir.label "B"
4544
// CIR: [[PTR:%.*]] = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["ptr", init] {alignment = 8 : i64}
45+
// CIR: cir.br ^bb1
46+
// CIR: ^bb1: // pred: ^bb0
47+
// CIR: cir.label "B"
4648
// CIR: [[BLOCK:%.*]] = cir.blockaddress <@B, "B"> -> !cir.ptr<!void>
4749
// CIR: cir.store align(8) [[BLOCK]], [[PTR]] : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
4850
// CIR: cir.return
4951

5052
// LLVM: define dso_local void @B
53+
// LLVM: %[[PTR:.*]] = alloca ptr, i64 1, align 8
5154
// LLVM: br label %[[B:.*]]
5255
// LLVM: [[B]]:
53-
// LLVM: %[[PTR:.*]] = alloca ptr, i64 1, align 8
5456
// LLVM: store ptr blockaddress(@B, %[[B]]), ptr %[[PTR]], align 8
5557
// LLVM: ret void
5658

0 commit comments

Comments
 (0)