[clang] 2c1c2dd - [CIR][OpenMP] Implement lowering for the 'if' clause for 'parallel' d… (#204999)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 24 03:09:27 PDT 2026
Author: Pedro da Rosa Pinheiro
Date: 2026-09-24T11:09:20+01:00
New Revision: 2c1c2ddaca27dffb99b70dad233ca2b39520a0a7
URL: https://github.com/llvm/llvm-project/commit/2c1c2ddaca27dffb99b70dad233ca2b39520a0a7
DIFF: https://github.com/llvm/llvm-project/commit/2c1c2ddaca27dffb99b70dad233ca2b39520a0a7.diff
LOG: [CIR][OpenMP] Implement lowering for the 'if' clause for 'parallel' d… (#204999)
Implementing the lowering of the `if` clause for the `#pragma omp
parallel` directive. The clause simply accepts the condition from
`OMPIfClause` and lowers it to an `I1` to allow for emission.
Followed the same approach as the one in my other PR #202466 and based
myself off of PR #172501 that implements the lowering for the
`proc_bind` clause.
### Evidence:
Output of: `python3 build/bin/llvm-lit -sv
clang/test/CIR/CodeGenOpenMP/parallel.c`
```
llvm-lit: /home/pedro/dev/projects/my-llvm-project/llvm/utils/lit/lit/llvm/config.py:569: note: using clang: /home/pedro/dev/projects/my-llvm-project/build/bin/clang
Testing Time: 0.10s
Total Discovered Tests: 1
Passed: 1 (100.00%)
```
Added:
Modified:
clang/lib/CIR/CodeGen/CIRGenOpenMPClause.cpp
clang/lib/CIR/CodeGen/CIRGenOpenMPClause.h
clang/lib/CIR/CodeGen/CIRGenStmtOpenMP.cpp
clang/test/CIR/CodeGenOpenMP/not-yet-implemented.c
clang/test/CIR/CodeGenOpenMP/parallel.c
Removed:
################################################################################
diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenMPClause.cpp b/clang/lib/CIR/CodeGen/CIRGenOpenMPClause.cpp
index 16ac4440660b5..2f6395486939f 100644
--- a/clang/lib/CIR/CodeGen/CIRGenOpenMPClause.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenOpenMPClause.cpp
@@ -93,6 +93,34 @@ bool OpenMPClauseEmitter::emitProcBind(
return false;
}
+bool OpenMPClauseEmitter::emitIf(mlir::omp::IfClauseOps &result,
+ llvm::omp::Directive directiveName) const {
+ for (const OMPClause *clause : clauses) {
+ const auto *ic = dyn_cast<OMPIfClause>(clause);
+ if (!ic)
+ continue;
+
+ if (!(ic->getNameModifier() == llvm::omp::Directive::OMPD_unknown) &&
+ ic->getNameModifier() != directiveName)
+ continue;
+
+ Expr *ifCondition = ic->getCondition();
+ mlir::Value ifBoolValue = cgf.evaluateExprAsBool(ifCondition); // !cir.bool
+
+ mlir::Type uIntType = builder.getUIntNTy(1);
+ mlir::Value ifUIntValue =
+ builder.createBoolToInt(ifBoolValue, uIntType); // u1
+
+ mlir::Type intType = builder.getI1Type();
+ mlir::Value ifExpr =
+ builder.createBuiltinIntCast(ifUIntValue, intType); // i1
+
+ result.ifExpr = ifExpr;
+ return true;
+ }
+ return false;
+}
+
bool OpenMPClauseEmitter::emitMap(
mlir::omp::MapClauseOps &result,
llvm::SmallVectorImpl<const VarDecl *> *mapSyms) const {
diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenMPClause.h b/clang/lib/CIR/CodeGen/CIRGenOpenMPClause.h
index 54c7366b1d769..aa6c6653bc540 100644
--- a/clang/lib/CIR/CodeGen/CIRGenOpenMPClause.h
+++ b/clang/lib/CIR/CodeGen/CIRGenOpenMPClause.h
@@ -42,6 +42,9 @@ class OpenMPClauseEmitter {
bool emitProcBind(mlir::omp::ProcBindClauseOps &result) const;
+ bool emitIf(mlir::omp::IfClauseOps &result,
+ llvm::omp::Directive directiveName) const;
+
/// Emit map clauses. The optional \p mapSyms parameter collects the
/// VarDecls corresponding to each map operand.
bool emitMap(mlir::omp::MapClauseOps &result,
diff --git a/clang/lib/CIR/CodeGen/CIRGenStmtOpenMP.cpp b/clang/lib/CIR/CodeGen/CIRGenStmtOpenMP.cpp
index 721d95c04655b..73afa76d94394 100644
--- a/clang/lib/CIR/CodeGen/CIRGenStmtOpenMP.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenStmtOpenMP.cpp
@@ -38,12 +38,13 @@ CIRGenFunction::emitOMPParallelDirective(const OMPParallelDirective &s) {
mlir::omp::ParallelOperands clauseOps;
OpenMPClauseEmitter ce(*this, getCIRGenModule(), builder, begin, s.clauses());
+ ce.emitIf(clauseOps, llvm::omp::Directive::OMPD_parallel);
ce.emitProcBind(clauseOps);
- ce.emitNYI</*supported=*/OMPProcBindClause>(
- /*nyi=*/OpenMPNYIClauseList<
- OMPAllocateClause, OMPCopyinClause, OMPDefaultClause,
- OMPFirstprivateClause, OMPIfClause, OMPNumThreadsClause,
- OMPPrivateClause, OMPReductionClause, OMPSharedClause>{},
+ ce.emitNYI</*supported=*/OMPIfClause, OMPProcBindClause>(
+ /*nyi=*/OpenMPNYIClauseList<OMPAllocateClause, OMPCopyinClause,
+ OMPDefaultClause, OMPFirstprivateClause,
+ OMPNumThreadsClause, OMPPrivateClause,
+ OMPReductionClause, OMPSharedClause>{},
llvm::omp::Directive::OMPD_parallel);
auto parallelOp = mlir::omp::ParallelOp::create(builder, begin, clauseOps);
diff --git a/clang/test/CIR/CodeGenOpenMP/not-yet-implemented.c b/clang/test/CIR/CodeGenOpenMP/not-yet-implemented.c
index ed4240727ff64..93a17494ad605 100644
--- a/clang/test/CIR/CodeGenOpenMP/not-yet-implemented.c
+++ b/clang/test/CIR/CodeGenOpenMP/not-yet-implemented.c
@@ -8,9 +8,4 @@ void do_things() {
// expected-error at +1{{ClangIR code gen Not Yet Implemented: OpenMP OMPSingleDirective}}
#pragma omp single
{}
-
- int i;
- // expected-error at +1{{ClangIR code gen Not Yet Implemented: OpenMP PARALLEL 'if' clause}}
-#pragma omp parallel if(i)
- {}
}
diff --git a/clang/test/CIR/CodeGenOpenMP/parallel.c b/clang/test/CIR/CodeGenOpenMP/parallel.c
index 4fb7997ab6635..68b78ed1ce7ee 100644
--- a/clang/test/CIR/CodeGenOpenMP/parallel.c
+++ b/clang/test/CIR/CodeGenOpenMP/parallel.c
@@ -84,3 +84,75 @@ void proc_bind_parallel() {
// CHECK-NEXT: omp.terminator
// CHECK-NEXT: }
}
+
+void if_parallel() {
+ // CHECK: cir.func{{.*}}@if_parallel
+
+ int validCondition = 10;
+ int invalidCondition = 0;
+ void *nullPtr = ((void *)0);
+
+ // CHECK-NEXT: %[[VALID_CONDITION_ADDR:.*]] = cir.alloca "validCondition"
+ // CHECK-NEXT: %[[INVALID_CONDITION_ADDR:.*]] = cir.alloca "invalidCondition"
+ // CHECK-NEXT: %[[NULL_ADDR:.*]] = cir.alloca "nullPtr"
+
+ #pragma omp parallel if (1)
+ {}
+ // CHECK: %[[ONE_CONST:.*]] = cir.const #cir.int<1>
+ // CHECK-NEXT: %[[ONE_BOOL:.*]] = cir.cast int_to_bool %[[ONE_CONST]]
+ // CHECK-NEXT: %[[ONE_U1:.*]] = cir.cast bool_to_int %[[ONE_BOOL]]
+ // CHECK-NEXT: %[[ONE_I1:.*]] = cir.builtin_int_cast %[[ONE_U1]]
+ // CHECK-NEXT: omp.parallel if(%[[ONE_I1]]) {
+ // CHECK-NEXT: omp.terminator
+ // CHECK-NEXT: }
+
+#pragma omp parallel if (validCondition)
+ {}
+ // CHECK-NEXT: %[[VALID_CONDITION_PTR:.*]] = cir.load align(4) %[[VALID_CONDITION_ADDR]]
+ // CHECK-NEXT: %[[VALID_CONDITION_BOOL:.*]] = cir.cast int_to_bool %[[VALID_CONDITION_PTR]]
+ // CHECK-NEXT: %[[VALID_CONDITION_U1:.*]] = cir.cast bool_to_int %[[VALID_CONDITION_BOOL]]
+ // CHECK-NEXT: %[[VALID_CONDITION_I1:.*]] = cir.builtin_int_cast %[[VALID_CONDITION_U1]]
+ // CHECK-NEXT: omp.parallel if(%[[VALID_CONDITION_I1]]) {
+ // CHECK-NEXT: omp.terminator
+ // CHECK-NEXT: }
+
+#pragma omp parallel if (nullPtr)
+ {}
+ // CHECK-NEXT: %[[NULL_PTR:.*]] = cir.load align(8) %[[NULL_ADDR]]
+ // CHECK-NEXT: %[[NULL_BOOL:.*]] = cir.cast ptr_to_bool %[[NULL_PTR]]
+ // CHECK-NEXT: %[[NULL_U1:.*]] = cir.cast bool_to_int %[[NULL_BOOL]]
+ // CHECK-NEXT: %[[NULL_I1:.*]] = cir.builtin_int_cast %[[NULL_U1]]
+ // CHECK-NEXT: omp.parallel if(%[[NULL_I1]]) {
+ // CHECK-NEXT: omp.terminator
+ // CHECK-NEXT: }
+
+#pragma omp parallel if (invalidCondition)
+ {}
+ // CHECK-NEXT: %[[INVALID_CONDITION_PTR:.*]] = cir.load align(4) %[[INVALID_CONDITION_ADDR]]
+ // CHECK-NEXT: %[[INVALID_CONDITION_BOOL:.*]] = cir.cast int_to_bool %[[INVALID_CONDITION_PTR]]
+ // CHECK-NEXT: %[[INVALID_CONDITION_U1:.*]] = cir.cast bool_to_int %[[INVALID_CONDITION_BOOL]]
+ // CHECK-NEXT: %[[INVALID_CONDITION_I1:.*]] = cir.builtin_int_cast %[[INVALID_CONDITION_U1]]
+ // CHECK-NEXT: omp.parallel if(%[[INVALID_CONDITION_I1]]) {
+ // CHECK-NEXT: omp.terminator
+ // CHECK-NEXT: }
+
+#pragma omp parallel if (parallel: validCondition)
+ {}
+ // CHECK-NEXT: %[[VALID_CONDITION_DIRECTIVE_PTR:.*]] = cir.load align(4) %[[VALID_CONDITION_ADDR]]
+ // CHECK-NEXT: %[[VALID_CONDITION_DIRECTIVE_BOOL:.*]] = cir.cast int_to_bool %[[VALID_CONDITION_DIRECTIVE_PTR]]
+ // CHECK-NEXT: %[[VALID_CONDITION_DIRECTIVE_U1:.*]] = cir.cast bool_to_int %[[VALID_CONDITION_DIRECTIVE_BOOL]]
+ // CHECK-NEXT: %[[VALID_CONDITION_DIRECTIVE_I1:.*]] = cir.builtin_int_cast %[[VALID_CONDITION_DIRECTIVE_U1]]
+ // CHECK-NEXT: omp.parallel if(%[[VALID_CONDITION_DIRECTIVE_I1]]) {
+ // CHECK-NEXT: omp.terminator
+ // CHECK-NEXT: }
+
+#pragma omp parallel if (parallel: invalidCondition)
+ {}
+ // CHECK-NEXT: %[[INVALID_CONDITION_DIRECTIVE_PTR:.*]] = cir.load align(4) %[[INVALID_CONDITION_ADDR]]
+ // CHECK-NEXT: %[[INVALID_CONDITION_DIRECTIVE_BOOL:.*]] = cir.cast int_to_bool %[[INVALID_CONDITION_DIRECTIVE_PTR]]
+ // CHECK-NEXT: %[[INVALID_CONDITION_DIRECTIVE_U1:.*]] = cir.cast bool_to_int %[[INVALID_CONDITION_DIRECTIVE_BOOL]]
+ // CHECK-NEXT: %[[INVALID_CONDITION_DIRECTIVE_I1:.*]] = cir.builtin_int_cast %[[INVALID_CONDITION_DIRECTIVE_U1]]
+ // CHECK-NEXT: omp.parallel if(%[[INVALID_CONDITION_DIRECTIVE_I1]]) {
+ // CHECK-NEXT: omp.terminator
+ // CHECK-NEXT: }
+}
More information about the cfe-commits
mailing list