Skip to content

Commit 8216e94

Browse files
committed
[CIR][CIRGen] Implement "if constexpr" code generation
1 parent 257a5b0 commit 8216e94

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

clang/lib/CIR/CodeGen/CIRGenStmt.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,14 @@ mlir::LogicalResult CIRGenFunction::buildIfStmt(const IfStmt &S) {
374374
if (S.isConsteval()) {
375375
llvm_unreachable("consteval nyi");
376376
}
377+
// Handle "if constexpr" explicitly here to avoid generating some
378+
// ill-formed code since in CIR the "if" are no longer simplified in
379+
// this function like in Clang but postponed to other MLIR passes.
380+
if (auto ndc = S.getNondiscardedCase(getContext())) {
381+
// Replace the "if constexpr" by its non-discarded branch in a new
382+
// scope
383+
return buildStmt(ndc.value(), /*useCurrentScope=*/false);
384+
}
377385
mlir::LogicalResult res = mlir::success();
378386

379387
// C99 6.8.4.1: The first substatement is executed if the expression
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir-enable -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s
3+
4+
void if0() {
5+
int x = 0;
6+
if constexpr (0 == 0) {
7+
// Declare a variable with same name to be sure we handle the scope
8+
int x = 2;
9+
} else {
10+
int x = 3;
11+
}
12+
if constexpr (0 == 1) {
13+
int x = 4;
14+
} else {
15+
int x = 5;
16+
}
17+
}
18+
19+
// CHECK: cir.func @_Z3if0v() {{.*}}
20+
// CHECK: cir.store %1, %0 : !s32i, cir.ptr <!s32i> loc({{.*}})
21+
// CHECK-NEXT: cir.scope {
22+
// CHECK-NEXT: %2 = cir.alloca !s32i, cir.ptr <!s32i>, ["x", init] {alignment = 4 : i64} loc({{.*}})
23+
// CHECK-NEXT: %3 = cir.const(#cir.int<2> : !s32i) : !s32i loc({{.*}})
24+
// CHECK-NEXT: cir.store %3, %2 : !s32i, cir.ptr <!s32i> loc({{.*}})
25+
// CHECK-NEXT: } loc({{.*}})
26+
// CHECK-NEXT: cir.scope {
27+
// CHECK-NEXT: %2 = cir.alloca !s32i, cir.ptr <!s32i>, ["x", init] {alignment = 4 : i64} loc({{.*}})
28+
// CHECK-NEXT: %3 = cir.const(#cir.int<5> : !s32i) : !s32i loc({{.*}})
29+
// CHECK-NEXT: cir.store %3, %2 : !s32i, cir.ptr <!s32i> loc({{.*}})
30+
// CHECK-NEXT: } loc({{.*}})
31+
// CHECK-NEXT: cir.return loc({{.*}})

0 commit comments

Comments
 (0)