Skip to content

Commit 94f2aa7

Browse files
Fixed format, addressed reviews, and added more tests for better coverage
1 parent 1fe966e commit 94f2aa7

File tree

4 files changed

+204
-10
lines changed

4 files changed

+204
-10
lines changed

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -800,8 +800,8 @@ def CaseOp : CIR_Op<"case", [
800800
let hasVerifier = 1;
801801

802802
let skipDefaultBuilders = 1;
803-
let builders = [
804-
OpBuilder<(ins "mlir::ArrayAttr":$value,
803+
let builders = [
804+
OpBuilder<(ins "mlir::ArrayAttr":$value,
805805
"CaseOpKind":$kind,
806806
"mlir::OpBuilder::InsertPoint &":$insertPoint)>
807807
];

clang/lib/CIR/CodeGen/CIRGenStmt.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,11 @@ mlir::LogicalResult CIRGenFunction::emitSimpleStmt(const Stmt *s,
252252
// NullStmt doesn't need any handling, but we need to say we handled it.
253253
case Stmt::NullStmtClass:
254254
break;
255+
case Stmt::CaseStmtClass:
256+
// If we reached here, we must not handling a switch case in the top level.
257+
return emitSwitchCase(cast<SwitchCase>(*s),
258+
/*buildingTopLevelCase=*/false);
259+
break;
255260

256261
case Stmt::BreakStmtClass:
257262
return emitBreakStmt(cast<BreakStmt>(*s));

clang/lib/CIR/Dialect/IR/CIRDialect.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -842,22 +842,22 @@ static ParseResult parseSwitchOp(OpAsmParser &parser, mlir::Region &regions,
842842
cir::IntType intCondType;
843843

844844
if (parser.parseLParen())
845-
return ::mlir::failure();
845+
return mlir::failure();
846846

847847
if (parser.parseOperand(cond))
848-
return ::mlir::failure();
848+
return mlir::failure();
849849
if (parser.parseColon())
850-
return ::mlir::failure();
850+
return mlir::failure();
851851
if (parser.parseCustomTypeWithFallback(intCondType))
852-
return ::mlir::failure();
852+
return mlir::failure();
853853
condType = intCondType;
854854

855855
if (parser.parseRParen())
856-
return ::mlir::failure();
856+
return mlir::failure();
857857
if (parser.parseRegion(regions, /*arguments=*/{}, /*argTypes=*/{}))
858858
return failure();
859859

860-
return ::mlir::success();
860+
return mlir::success();
861861
}
862862

863863
static void printSwitchOp(OpAsmPrinter &p, cir::SwitchOp op,
@@ -910,8 +910,6 @@ void cir::SwitchOp::collectCases(llvm::SmallVector<CaseOp> &cases) {
910910
});
911911
}
912912

913-
// Check if the switch is in a simple form. If yes, collect the cases to \param
914-
// cases. This is an expensive and need to be used with caution.
915913
bool cir::SwitchOp::isSimpleForm(llvm::SmallVector<CaseOp> &cases) {
916914
collectCases(cases);
917915

clang/test/CIR/CodeGen/switch.cpp

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,194 @@ void sw2(int a) {
9090
// OGCG: br label %[[SW_EPILOG]]
9191
// OGCG: [[SW_EPILOG]]:
9292
// OGCG: ret void
93+
94+
void sw5(int a) {
95+
switch (a) {
96+
case 1:;
97+
}
98+
}
99+
100+
// CIR: cir.func @sw5
101+
// CIR: cir.switch (%1 : !s32i) {
102+
// CIR-NEXT: cir.case(equal, [#cir.int<1> : !s32i]) {
103+
// CIR-NEXT: cir.yield
104+
// CIR-NEXT: }
105+
// CIR-NEXT: cir.yield
106+
// CIR-NEXT: }
107+
108+
// OGCG: define dso_local void @_Z3sw5i
109+
// OGCG: entry:
110+
// OGCG: %[[A_ADDR:.*]] = alloca i32, align 4
111+
// OGCG: %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR]], align 4
112+
// OGCG: switch i32 %[[A_VAL]], label %[[SW_EPILOG:.*]] [
113+
// OGCG: i32 1, label %[[SW1:.*]]
114+
// OGCG: ]
115+
// OGCG: [[SW1]]:
116+
// OGCG: br label %[[SW_EPILOG]]
117+
// OGCG: [[SW_EPILOG]]:
118+
// OGCG: ret void
119+
120+
void sw12(int a) {
121+
switch (a)
122+
{
123+
case 3:
124+
return;
125+
break;
126+
}
127+
}
128+
129+
// CIR: cir.func @sw12
130+
// CIR: cir.scope {
131+
// CIR: cir.switch
132+
// CIR-NEXT: cir.case(equal, [#cir.int<3> : !s32i]) {
133+
// CIR-NEXT: cir.return
134+
// CIR-NEXT: ^bb1: // no predecessors
135+
// CIR-NEXT: cir.break
136+
// CIR-NEXT: }
137+
138+
// OGCG: define dso_local void @_Z4sw12i
139+
// OGCG: entry:
140+
// OGCG: %[[A_ADDR:.*]] = alloca i32, align 4
141+
// OGCG: %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR]], align 4
142+
// OGCG: switch i32 %[[A_VAL]], label %[[SW_DEFAULT:.*]] [
143+
// OGCG: i32 3, label %[[SW3:.*]]
144+
// OGCG: ]
145+
// OGCG: [[SW3]]:
146+
// OGCG: br label %[[SW_DEFAULT]]
147+
// OGCG: [[SW_DEFAULT]]:
148+
// OGCG: ret void
149+
150+
void sw13(int a, int b) {
151+
switch (a) {
152+
case 1:
153+
switch (b) {
154+
case 2:
155+
break;
156+
}
157+
}
158+
}
159+
160+
// CIR: cir.func @sw13
161+
// CIR: cir.scope {
162+
// CIR: cir.switch
163+
// CIR-NEXT: cir.case(equal, [#cir.int<1> : !s32i]) {
164+
// CIR-NEXT: cir.scope {
165+
// CIR: cir.switch
166+
// CIR-NEXT: cir.case(equal, [#cir.int<2> : !s32i]) {
167+
// CIR-NEXT: cir.break
168+
// CIR-NEXT: }
169+
// CIR-NEXT: cir.yield
170+
// CIR-NEXT: }
171+
// CIR-NEXT: }
172+
// CIR: cir.yield
173+
// CIR: }
174+
// CIR: cir.return
175+
176+
// OGCG: define dso_local void @_Z4sw13ii
177+
// OGCG: entry:
178+
// OGCG: %[[A_ADDR:.*]] = alloca i32, align 4
179+
// OGCG: %[[B_ADDR:.*]] = alloca i32, align 4
180+
// OGCG: %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR]], align 4
181+
// OGCG: switch i32 %[[A_VAL]], label %[[EPILOG2:.*]] [
182+
// OGCG: i32 1, label %[[SW1:.*]]
183+
// OGCG: ]
184+
// OGCG: [[SW1]]:
185+
// OGCG: %[[B_VAL:.*]] = load i32, ptr %[[B_ADDR]], align 4
186+
// OGCG: switch i32 %[[B_VAL]], label %[[EPILOG:.*]] [
187+
// OGCG: i32 2, label %[[SW12:.*]]
188+
// OGCG: ]
189+
// OGCG: [[SW12]]:
190+
// OGCG: br label %[[EPILOG]]
191+
// OGCG: [[EPILOG]]:
192+
// OGCG: br label %[[EPILOG2]]
193+
// OGCG: [[EPILOG2]]:
194+
// OGCG: ret void
195+
196+
int nested_switch(int a) {
197+
switch (int b = 1; a) {
198+
case 0:
199+
b = b + 1;
200+
case 1:
201+
return b;
202+
case 2: {
203+
b = b + 1;
204+
if (a > 1000) {
205+
case 9:
206+
b = a + b;
207+
}
208+
if (a > 500) {
209+
case 7:
210+
return a + b;
211+
}
212+
break;
213+
}
214+
}
215+
216+
return 0;
217+
}
218+
219+
// CIR: cir.switch (%6 : !s32i) {
220+
// CIR: cir.case(equal, [#cir.int<0> : !s32i]) {
221+
// CIR: cir.yield
222+
// CIR: }
223+
// CIR: cir.case(equal, [#cir.int<1> : !s32i]) {
224+
// CIR: cir.return
225+
// CIR: }
226+
// CIR: cir.case(equal, [#cir.int<2> : !s32i]) {
227+
// CIR: cir.scope {
228+
// CIR: cir.scope {
229+
// CIR: cir.if
230+
// CIR: cir.case(equal, [#cir.int<9> : !s32i]) {
231+
// CIR: cir.yield
232+
// CIR: cir.scope {
233+
// CIR: cir.if
234+
// CIR: cir.case(equal, [#cir.int<7> : !s32i]) {
235+
// CIR: cir.return
236+
237+
// OGCG: define dso_local noundef i32 @_Z13nested_switchi
238+
// OGCG: entry:
239+
// OGCG: %[[RETVAL:.*]] = alloca i32, align 4
240+
// OGCG: %[[A_ADDR:.*]] = alloca i32, align 4
241+
// OGCG: %[[B:.*]] = alloca i32, align 4
242+
// OGCG: %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR]], align 4
243+
// OGCG: switch i32 %[[A_VAL]], label %[[EPILOG:.*]] [
244+
// OGCG: i32 0, label %[[SW0:.*]]
245+
// OGCG: i32 1, label %[[SW1:.*]]
246+
// OGCG: i32 2, label %[[SW2:.*]]
247+
// OGCG: i32 9, label %[[SW4:.*]]
248+
// OGCG: i32 7, label %[[SW8:.*]]
249+
// OGCG: ]
250+
// OGCG: [[SW0]]:
251+
// OGCG: %[[B_VAL0:.*]] = load i32, ptr %[[B]], align 4
252+
// OGCG: %[[ADD0:.*]] = add nsw i32 %[[B_VAL0]], 1
253+
// OGCG: br label %[[SW1]]
254+
// OGCG: [[SW1]]:
255+
// OGCG: %[[B_VAL1:.*]] = load i32, ptr %[[B]], align 4
256+
// OGCG: br label %[[RETURN:.*]]
257+
// OGCG: [[SW2]]:
258+
// OGCG: %[[B_VAL2:.*]] = load i32, ptr %[[B]], align 4
259+
// OGCG: %[[ADD2:.*]] = add nsw i32 %[[B_VAL2]], 1
260+
// OGCG: %[[A_VAL2:.*]] = load i32, ptr %[[A_ADDR]], align 4
261+
// OGCG: %[[CMP1000:.*]] = icmp sgt i32 %[[A_VAL2]], 1000
262+
// OGCG: br i1 %[[CMP1000]], label %[[IFTHEN:.*]], label %[[IFEND:.*]]
263+
// OGCG: [[IFTHEN]]:
264+
// OGCG: br label %[[SW4]]
265+
// OGCG: [[SW4]]:
266+
// OGCG: %[[A_VAL4:.*]] = load i32, ptr %[[A_ADDR]], align 4
267+
// OGCG: %[[B_VAL4:.*]] = load i32, ptr %[[B]], align 4
268+
// OGCG: %[[ADD4:.*]] = add nsw i32 %[[A_VAL4]], %[[B_VAL4]]
269+
// OGCG: br label %[[IFEND]]
270+
// OGCG: [[IFEND]]:
271+
// OGCG: %[[A_VAL5:.*]] = load i32, ptr %[[A_ADDR]], align 4
272+
// OGCG: %[[CMP500:.*]] = icmp sgt i32 %[[A_VAL5]], 500
273+
// OGCG: br i1 %[[CMP500]], label %[[IFTHEN7:.*]], label %[[IFEND10:.*]]
274+
// OGCG: [[IFTHEN7]]:
275+
// OGCG: br label %[[SW8]]
276+
// OGCG: [[SW8]]:
277+
// OGCG: %[[A_VAL8:.*]] = load i32, ptr %[[A_ADDR]], align 4
278+
// OGCG: %[[B_VAL8:.*]] = load i32, ptr %[[B]], align 4
279+
// OGCG: %[[ADD8:.*]] = add nsw i32 %[[A_VAL8]], %[[B_VAL8]]
280+
// OGCG: br label %[[RETURN]]
281+
// OGCG: [[IFEND10]]:
282+
// OGCG: br label %[[EPILOG]]
283+
// OGCG: [[EPILOG]]:

0 commit comments

Comments
 (0)