[clang] af781f7 - [OPENMP51]Codegen for error directive.
Jennifer Yu via cfe-commits
cfe-commits at lists.llvm.org
Thu Dec 8 13:22:41 PST 2022
Author: Jennifer Yu
Date: 2022-12-08T13:07:08-08:00
New Revision: af781f7042392910c4cf70106c6a0c2244c69478
URL: https://github.com/llvm/llvm-project/commit/af781f7042392910c4cf70106c6a0c2244c69478
DIFF: https://github.com/llvm/llvm-project/commit/af781f7042392910c4cf70106c6a0c2244c69478.diff
LOG: [OPENMP51]Codegen for error directive.
Added codegen for `omp error` directive.
This is to generate IR to call:
void __kmpc_error(ident_t *loc, int severity, const char *message);
Differential Revision: https://reviews.llvm.org/D139166
Added:
clang/test/OpenMP/error_codegen.cpp
Modified:
clang/lib/CodeGen/CGOpenMPRuntime.cpp
clang/lib/CodeGen/CGOpenMPRuntime.h
clang/lib/CodeGen/CGStmtOpenMP.cpp
llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 10c88964da0ed..396075183102d 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -1363,10 +1363,11 @@ static StringRef getIdentStringFromSourceLocation(CodeGenFunction &CGF,
llvm::Value *CGOpenMPRuntime::emitUpdateLocation(CodeGenFunction &CGF,
SourceLocation Loc,
- unsigned Flags) {
+ unsigned Flags, bool EmitLoc) {
uint32_t SrcLocStrSize;
llvm::Constant *SrcLocStr;
- if (CGM.getCodeGenOpts().getDebugInfo() == codegenoptions::NoDebugInfo ||
+ if ((!EmitLoc &&
+ CGM.getCodeGenOpts().getDebugInfo() == codegenoptions::NoDebugInfo) ||
Loc.isInvalid()) {
SrcLocStr = OMPBuilder.getOrCreateDefaultSrcLocStr(SrcLocStrSize);
} else {
@@ -2557,6 +2558,22 @@ void CGOpenMPRuntime::emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
Args);
}
+void CGOpenMPRuntime::emitErrorCall(CodeGenFunction &CGF, SourceLocation Loc,
+ Expr *ME, bool IsFatal) {
+ llvm::Value *MVL =
+ ME ? CGF.EmitStringLiteralLValue(cast<StringLiteral>(ME)).getPointer(CGF)
+ : llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
+ // Build call void __kmpc_error(ident_t *loc, int severity, const char
+ // *message)
+ llvm::Value *Args[] = {
+ emitUpdateLocation(CGF, Loc, /*Flags=*/0, /*GenLoc=*/true),
+ llvm::ConstantInt::get(CGM.Int32Ty, IsFatal ? 2 : 1),
+ CGF.Builder.CreatePointerCast(MVL, CGM.Int8PtrTy)};
+ CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
+ CGM.getModule(), OMPRTL___kmpc_error),
+ Args);
+}
+
/// Map the OpenMP loop schedule to the runtime enumeration.
static OpenMPSchedType getRuntimeSchedule(OpenMPScheduleClauseKind ScheduleKind,
bool Chunked, bool Ordered) {
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.h b/clang/lib/CodeGen/CGOpenMPRuntime.h
index ee3211858fe18..e7c1a098c7689 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.h
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.h
@@ -329,9 +329,10 @@ class CGOpenMPRuntime {
/// Emits object of ident_t type with info for source location.
/// \param Flags Flags for OpenMP location.
+ /// \param EmitLoc emit source location with debug-info is off.
///
llvm::Value *emitUpdateLocation(CodeGenFunction &CGF, SourceLocation Loc,
- unsigned Flags = 0);
+ unsigned Flags = 0, bool EmitLoc = false);
/// Emit the number of teams for a target directive. Inspect the num_teams
/// clause associated with a teams construct combined or closely nested
@@ -822,6 +823,11 @@ class CGOpenMPRuntime {
/// Emits code for a taskyield directive.
virtual void emitTaskyieldCall(CodeGenFunction &CGF, SourceLocation Loc);
+ /// Emit __kmpc_error call for error directive
+ /// extern void __kmpc_error(ident_t *loc, int severity, const char *message);
+ virtual void emitErrorCall(CodeGenFunction &CGF, SourceLocation Loc, Expr *ME,
+ bool IsFatal);
+
/// Emit a taskgroup region.
/// \param TaskgroupOpGen Generator for the statement associated with the
/// given taskgroup region.
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index b84fee77c66dd..cf9b704e0ae6f 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -5246,7 +5246,13 @@ void CodeGenFunction::EmitOMPTaskyieldDirective(
}
void CodeGenFunction::EmitOMPErrorDirective(const OMPErrorDirective &S) {
- llvm_unreachable("CodeGen for 'omp error' is not supported yet.");
+ const OMPMessageClause *MC = S.getSingleClause<OMPMessageClause>();
+ Expr *ME = MC ? MC->getMessageString() : nullptr;
+ const OMPSeverityClause *SC = S.getSingleClause<OMPSeverityClause>();
+ bool IsFatal = false;
+ if (!SC || SC->getSeverityKind() == OMPC_SEVERITY_fatal)
+ IsFatal = true;
+ CGM.getOpenMPRuntime().emitErrorCall(*this, S.getBeginLoc(), ME, IsFatal);
}
void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &S) {
diff --git a/clang/test/OpenMP/error_codegen.cpp b/clang/test/OpenMP/error_codegen.cpp
new file mode 100644
index 0000000000000..0f4d1863e69fc
--- /dev/null
+++ b/clang/test/OpenMP/error_codegen.cpp
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -std=c++11 -fopenmp -fopenmp-version=51 -triple x86_64 \
+// RUN: -emit-llvm -o - %s | FileCheck %s
+
+// RUN: %clang_cc1 -std=c++11 -fopenmp-simd -fopenmp-version=51 \
+// RUN: -debug-info-kind=limited -triple x86_64 -emit-llvm -o - %s | \
+// RUN: FileCheck --check-prefix SIMD %s
+
+//CHECK: @.str = private unnamed_addr constant [23 x i8] c"GPU compiler required.\00", align 1
+//CHECK: @0 = private unnamed_addr constant {{.*}}error_codegen.cpp;main;52;1;;\00", align 1
+//CHECK: @1 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 {{.*}}, ptr @0 }, align 8
+//CHECK: @.str.1 = private unnamed_addr constant [27 x i8] c"Note this is functioncall.\00", align 1
+//CHECK: @2 = private unnamed_addr constant {{.*}}error_codegen.cpp;main;54;1;;\00", align 1
+//CHECK: @3 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 {{.*}}, ptr @2 }, align 8
+//CHECK: @.str.2 = private unnamed_addr constant [23 x i8] c"GNU compiler required.\00", align 1
+//CHECK: @4 = private unnamed_addr constant {{.*}}error_codegen.cpp;tmain;29;1;;\00", align 1
+//CHECK: @5 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 {{.*}}, ptr @4 }, align 8
+//CHECK: @.str.3 = private unnamed_addr constant [22 x i8] c"Notice: add for loop.\00", align 1
+//CHECK: @6 = private unnamed_addr constant {{.*}}error_codegen.cpp;tmain;32;1;;\00", align 1
+//CHECK: @7 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 {{.*}}, ptr @6 }, align 8
+//CHECK: @8 = private unnamed_addr constant {{.*}}error_codegen.cpp;tmain;38;1;;\00", align 1
+//CHECK: @9 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 {{.*}}, ptr @8 }, align 8
+
+void foo() {}
+
+template <typename T, int N>
+int tmain(T argc, char **argv) {
+ T b = argc, c, d, e, f, g;
+ static int a;
+#pragma omp error at(execution) severity(fatal) message("GNU compiler required.")
+ a = argv[0][0];
+ ++a;
+#pragma omp error at(execution) severity(warning) message("Notice: add for loop.")
+ {
+ int b = 10;
+ T c = 100;
+ a = b + c;
+ }
+#pragma omp error at(execution) severity(fatal) message("GPU compiler required.")
+ foo();
+return N;
+}
+// CHECK-LABEL: @main(
+// SIMD-LABEL: @main(
+// CHECK: call void @__kmpc_error(ptr @1, i32 2, ptr @.str)
+// SIMD-NOT: call void @__kmpc_error(ptr @1, i32 2, ptr @.str)
+// CHECK: call void @__kmpc_error(ptr @3, i32 1, ptr @.str.1)
+// SIMD-NOT: call void @__kmpc_error(ptr @3, i32 1, ptr @.str.1)
+//
+int main (int argc, char **argv) {
+ int b = argc, c, d, e, f, g;
+ static int a;
+#pragma omp error at(execution) severity(fatal) message("GPU compiler required.")
+ a=2;
+#pragma omp error at(execution) severity(warning) message("Note this is functioncall.")
+ foo();
+ tmain<int, 10>(argc, argv);
+}
+
+//CHECK-LABEL: @_Z5tmainIiLi10EEiT_PPc(
+//SIMD-LABEL: @_Z5tmainIiLi10EEiT_PPc(
+//CHECK: call void @__kmpc_error(ptr @5, i32 2, ptr @.str.2)
+//CHECK: call void @__kmpc_error(ptr @7, i32 1, ptr @.str.3)
+//CHECK: call void @__kmpc_error(ptr @9, i32 2, ptr @.str)
+//SIMD-NOT: call void @__kmpc_error(ptr @5, i32 2, ptr @.str.2)
+//SIMD-NOT: call void @__kmpc_error(ptr @7, i32 1, ptr @.str.3)
+//SIMD-NOT: call void @__kmpc_error(ptr @9, i32 2, ptr @.str)
+//CHECK: ret i32 10
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
index a9b8b8754587c..87ac4d59d59b9 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
+++ b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
@@ -198,6 +198,7 @@ __ICV_RT_GET(proc_bind, omp_get_proc_bind)
__OMP_RTL(__kmpc_barrier, false, Void, IdentPtr, Int32)
__OMP_RTL(__kmpc_cancel, false, Int32, IdentPtr, Int32, Int32)
__OMP_RTL(__kmpc_cancel_barrier, false, Int32, IdentPtr, Int32)
+__OMP_RTL(__kmpc_error, false, Void, IdentPtr, Int32, Int8Ptr)
__OMP_RTL(__kmpc_flush, false, Void, IdentPtr)
__OMP_RTL(__kmpc_global_thread_num, false, Int32, IdentPtr)
__OMP_RTL(__kmpc_get_hardware_thread_id_in_block, false, Int32, )
More information about the cfe-commits
mailing list