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 2, 2024
1 parent 00b21e0 commit 712d320
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 0 deletions.
10 changes: 10 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,16 @@ mlir::LogicalResult CIRGenFunction::buildIfStmt(const IfStmt &S) {
if (buildStmt(S.getInit(), /*useCurrentScope=*/true).failed())
return mlir::failure();

// Handle "if constexpr" explicitly here to avoid generating some
// ill-formed code since in CIR the "if" are no longer simplified
// in this lambda like in Clang but postponed to other MLIR
// passes.
if (S.isConstexpr())
if (auto ndc = S.getNondiscardedCase(getContext())) {
// Replace the "if constexpr" by its non-discarded branch
return buildStmt(ndc.value(), /*useCurrentScope=*/true);
}

if (S.getConditionVariable())
buildDecl(*S.getConditionVariable());

Expand Down
60 changes: 60 additions & 0 deletions clang/test/CIR/CodeGen/if-constexpr.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// 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
// scopes correctly
int x = 2;
} else {
int x = 3;
}
if constexpr (0 == 1) {
int x = 4;
} else {
int x = 5;
}
if constexpr (int x = 7; 8 == 8) {
int y = x;
} else {
int y = 2*x;
}
if constexpr (int x = 9; 8 == 10) {
int y = x;
} else {
int y = 3*x;
}
}

// 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] {{.*}}
// 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] {{.*}}
// 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.scope {
// CHECK-NEXT: %2 = cir.alloca !s32i, cir.ptr <!s32i>, ["x", init] {{.*}}
// CHECK-NEXT: %3 = cir.alloca !s32i, cir.ptr <!s32i>, ["y", init] {{.*}}
// CHECK-NEXT: %4 = cir.const(#cir.int<7> : !s32i) : !s32i loc({{.*}})
// CHECK-NEXT: cir.store %4, %2 : !s32i, cir.ptr <!s32i> loc({{.*}})
// CHECK-NEXT: %5 = cir.load %2 : cir.ptr <!s32i>, !s32i loc({{.*}})
// CHECK-NEXT: cir.store %5, %3 : !s32i, cir.ptr <!s32i> loc({{.*}})
// CHECK-NEXT: } loc({{.*}})
// CHECK-NEXT: cir.scope {
// CHECK-NEXT: %2 = cir.alloca !s32i, cir.ptr <!s32i>, ["x", init] {{.*}}
// CHECK-NEXT: %3 = cir.alloca !s32i, cir.ptr <!s32i>, ["y", init] {{.*}}
// CHECK-NEXT: %4 = cir.const(#cir.int<9> : !s32i) : !s32i loc({{.*}})
// CHECK-NEXT: cir.store %4, %2 : !s32i, cir.ptr <!s32i> loc({{.*}})
// CHECK-NEXT: %5 = cir.const(#cir.int<3> : !s32i) : !s32i loc({{.*}})
// CHECK-NEXT: %6 = cir.load %2 : cir.ptr <!s32i>, !s32i loc({{.*}})
// CHECK-NEXT: %7 = cir.binop(mul, %5, %6) : !s32i loc({{.*}})
// CHECK-NEXT: cir.store %7, %3 : !s32i, cir.ptr <!s32i> loc({{.*}})
// CHECK-NEXT: } loc({{.*}})
// CHECK-NEXT: cir.return loc({{.*}})

0 comments on commit 712d320

Please sign in to comment.