Skip to content

Commit

Permalink
[CIR][CIRGen] Implement "if constexpr" code generation
Browse files Browse the repository at this point in the history
  • Loading branch information
keryell committed Feb 1, 2024
1 parent 257a5b0 commit 8216e94
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 0 deletions.
8 changes: 8 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,14 @@ mlir::LogicalResult CIRGenFunction::buildIfStmt(const IfStmt &S) {
if (S.isConsteval()) {
llvm_unreachable("consteval nyi");
}
// Handle "if constexpr" explicitly here to avoid generating some
// ill-formed code since in CIR the "if" are no longer simplified in
// this function like in Clang but postponed to other MLIR passes.
if (auto ndc = S.getNondiscardedCase(getContext())) {
// Replace the "if constexpr" by its non-discarded branch in a new
// scope
return buildStmt(ndc.value(), /*useCurrentScope=*/false);
}
mlir::LogicalResult res = mlir::success();

// C99 6.8.4.1: The first substatement is executed if the expression
Expand Down
31 changes: 31 additions & 0 deletions clang/test/CIR/CodeGen/if-constexpr.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir-enable -emit-cir %s -o %t.cir
// RUN: FileCheck --input-file=%t.cir %s

void if0() {
int x = 0;
if constexpr (0 == 0) {
// Declare a variable with same name to be sure we handle the scope
int x = 2;
} else {
int x = 3;
}
if constexpr (0 == 1) {
int x = 4;
} else {
int x = 5;
}
}

// CHECK: cir.func @_Z3if0v() {{.*}}
// CHECK: cir.store %1, %0 : !s32i, cir.ptr <!s32i> loc({{.*}})
// CHECK-NEXT: cir.scope {
// CHECK-NEXT: %2 = cir.alloca !s32i, cir.ptr <!s32i>, ["x", init] {alignment = 4 : i64} loc({{.*}})
// CHECK-NEXT: %3 = cir.const(#cir.int<2> : !s32i) : !s32i loc({{.*}})
// CHECK-NEXT: cir.store %3, %2 : !s32i, cir.ptr <!s32i> loc({{.*}})
// CHECK-NEXT: } loc({{.*}})
// CHECK-NEXT: cir.scope {
// CHECK-NEXT: %2 = cir.alloca !s32i, cir.ptr <!s32i>, ["x", init] {alignment = 4 : i64} loc({{.*}})
// CHECK-NEXT: %3 = cir.const(#cir.int<5> : !s32i) : !s32i loc({{.*}})
// CHECK-NEXT: cir.store %3, %2 : !s32i, cir.ptr <!s32i> loc({{.*}})
// CHECK-NEXT: } loc({{.*}})
// CHECK-NEXT: cir.return loc({{.*}})

0 comments on commit 8216e94

Please sign in to comment.