[llvm] [OpenMPOpt] Don't assert when __kmpc_target_init has a null kernel environment argument (PR #196249)
via llvm-commits
llvm-commits at lists.llvm.org
Thu May 7 00:12:37 PDT 2026
https://github.com/IamYJLee updated https://github.com/llvm/llvm-project/pull/196249
>From e33daf90fe29f167a0d27be051a7e34f6efb5ab0 Mon Sep 17 00:00:00 2001
From: LeeYoungJoon <dog3hk.dev at gmail.com>
Date: Thu, 7 May 2026 15:42:03 +0900
Subject: [PATCH 1/2] [OpenMPOpt] Don't assert when __kmpc_target_init has a
null kernel environment argument
---
llvm/lib/Transforms/IPO/OpenMPOpt.cpp | 34 ++++++++++++++++++++-------
1 file changed, 26 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Transforms/IPO/OpenMPOpt.cpp b/llvm/lib/Transforms/IPO/OpenMPOpt.cpp
index 31e9d41ca3410..dd8c598fd49c7 100644
--- a/llvm/lib/Transforms/IPO/OpenMPOpt.cpp
+++ b/llvm/lib/Transforms/IPO/OpenMPOpt.cpp
@@ -259,7 +259,7 @@ KERNEL_ENVIRONMENT_CONFIGURATION_GETTER(MaxTeams)
GlobalVariable *
getKernelEnvironementGVFromKernelInitCB(CallBase *KernelInitCB) {
constexpr int InitKernelEnvironmentArgNo = 0;
- return cast<GlobalVariable>(
+ return dyn_cast<GlobalVariable>(
KernelInitCB->getArgOperand(InitKernelEnvironmentArgNo)
->stripPointerCasts());
}
@@ -267,7 +267,9 @@ getKernelEnvironementGVFromKernelInitCB(CallBase *KernelInitCB) {
ConstantStruct *getKernelEnvironementFromKernelInitCB(CallBase *KernelInitCB) {
GlobalVariable *KernelEnvGV =
getKernelEnvironementGVFromKernelInitCB(KernelInitCB);
- return cast<ConstantStruct>(KernelEnvGV->getInitializer());
+ if (!KernelEnvGV || !KernelEnvGV->hasInitializer())
+ return nullptr;
+ return dyn_cast<ConstantStruct>(KernelEnvGV->getInitializer());
}
} // namespace KernelInfo
@@ -2947,6 +2949,8 @@ struct AAExecutionDomainFunction : public AAExecutionDomain {
return false;
ConstantStruct *KernelEnvC =
KernelInfo::getKernelEnvironementFromKernelInitCB(CB);
+ if (!KernelEnvC)
+ return false;
ConstantInt *ExecModeC =
KernelInfo::getExecModeFromKernelEnvironment(KernelEnvC);
return ExecModeC->getSExtValue() & OMP_TGT_EXEC_MODE_GENERIC;
@@ -3744,14 +3748,16 @@ struct AAKernelInfoFunction : AAKernelInfo {
if (!KernelInitCB || !KernelDeinitCB)
return;
- // Add itself to the reaching kernel and set IsKernelEntry.
- ReachingKernelEntries.insert(Fn);
- IsKernelEntry = true;
-
KernelEnvC =
KernelInfo::getKernelEnvironementFromKernelInitCB(KernelInitCB);
GlobalVariable *KernelEnvGV =
KernelInfo::getKernelEnvironementGVFromKernelInitCB(KernelInitCB);
+ if (!KernelEnvC || !KernelEnvGV)
+ return;
+
+ // Add itself to the reaching kernel and set IsKernelEntry.
+ ReachingKernelEntries.insert(Fn);
+ IsKernelEntry = true;
Attributor::GlobalVariableSimplifictionCallbackTy
KernelConfigurationSimplifyCB =
@@ -3920,6 +3926,14 @@ struct AAKernelInfoFunction : AAKernelInfo {
if (!KernelInitCB || !KernelDeinitCB)
return ChangeStatus::UNCHANGED;
+ // Likewise, if the kernel-environment global is missing (e.g. the IR
+ // passes a null pointer as the first argument of __kmpc_target_init)
+ // there is no environment to update.
+ GlobalVariable *KernelEnvGV =
+ KernelInfo::getKernelEnvironementGVFromKernelInitCB(KernelInitCB);
+ if (!KernelEnvGV || !KernelEnvC)
+ return ChangeStatus::UNCHANGED;
+
ChangeStatus Changed = ChangeStatus::UNCHANGED;
bool HasBuiltStateMachine = true;
@@ -3941,8 +3955,6 @@ struct AAKernelInfoFunction : AAKernelInfo {
OldUseGenericStateMachineVal);
// At last, update the KernelEnvc
- GlobalVariable *KernelEnvGV =
- KernelInfo::getKernelEnvironementGVFromKernelInitCB(KernelInitCB);
if (KernelEnvGV->getInitializer() != KernelEnvC) {
KernelEnvGV->setInitializer(KernelEnvC);
Changed = ChangeStatus::CHANGED;
@@ -4271,6 +4283,8 @@ struct AAKernelInfoFunction : AAKernelInfo {
// Check if the kernel is already in SPMD mode, if so, return success.
ConstantStruct *ExistingKernelEnvC =
KernelInfo::getKernelEnvironementFromKernelInitCB(KernelInitCB);
+ if (!ExistingKernelEnvC)
+ return false;
auto *ExecModeC =
KernelInfo::getExecModeFromKernelEnvironment(ExistingKernelEnvC);
const int8_t ExecModeVal = ExecModeC->getSExtValue();
@@ -4322,6 +4336,8 @@ struct AAKernelInfoFunction : AAKernelInfo {
ConstantStruct *ExistingKernelEnvC =
KernelInfo::getKernelEnvironementFromKernelInitCB(KernelInitCB);
+ if (!ExistingKernelEnvC)
+ return false;
// Check if the current configuration is non-SPMD and generic state machine.
// If we already have SPMD mode or a custom state machine we do not need to
@@ -4650,6 +4666,8 @@ struct AAKernelInfoFunction : AAKernelInfo {
ConstantStruct *ExistingKernelEnvC =
KernelInfo::getKernelEnvironementFromKernelInitCB(AA.KernelInitCB);
+ if (!ExistingKernelEnvC)
+ return;
if (!AA.isValidState()) {
AA.KernelEnvC = ExistingKernelEnvC;
>From abe257e68930e61a0a921419887b4f90fa4e9f81 Mon Sep 17 00:00:00 2001
From: LeeYoungJoon <dog3hk.dev at gmail.com>
Date: Thu, 7 May 2026 16:12:21 +0900
Subject: [PATCH 2/2] [OpenMPOpt] Add regression test for null kernel
environment
---
.../OpenMP/kernel_env_null_init_arg.ll | 46 +++++++++++++++++++
1 file changed, 46 insertions(+)
create mode 100644 llvm/test/Transforms/OpenMP/kernel_env_null_init_arg.ll
diff --git a/llvm/test/Transforms/OpenMP/kernel_env_null_init_arg.ll b/llvm/test/Transforms/OpenMP/kernel_env_null_init_arg.ll
new file mode 100644
index 0000000000000..2d1c23b92a7cd
--- /dev/null
+++ b/llvm/test/Transforms/OpenMP/kernel_env_null_init_arg.ll
@@ -0,0 +1,46 @@
+; RUN: opt -S -passes=openmp-opt < %s | FileCheck %s
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; CHECK-LABEL: define ptx_kernel void @kernel_no_deinit
+; CHECK: %{{.*}} = call i32 @__kmpc_target_init(ptr null, ptr null)
+define ptx_kernel void @kernel_no_deinit() {
+entry:
+ %0 = call i32 @__kmpc_target_init(ptr null, ptr null)
+ %exec_user_code = icmp eq i32 %0, -1
+ br i1 %exec_user_code, label %user_code.entry, label %worker.exit
+
+user_code.entry:
+ ret void
+
+worker.exit:
+ ret void
+}
+
+; CHECK-LABEL: define ptx_kernel void @kernel_with_deinit
+; CHECK: %{{.*}} = call i32 @__kmpc_target_init(ptr null, ptr null)
+; CHECK: call void @__kmpc_target_deinit()
+define ptx_kernel void @kernel_with_deinit() #0 {
+entry:
+ %0 = call i32 @__kmpc_target_init(ptr null, ptr null)
+ %exec_user_code = icmp eq i32 %0, -1
+ br i1 %exec_user_code, label %user_code.entry, label %worker.exit
+
+user_code.entry:
+ call void @__kmpc_target_deinit()
+ ret void
+
+worker.exit:
+ ret void
+}
+
+declare i32 @__kmpc_target_init(ptr, ptr)
+declare void @__kmpc_target_deinit()
+
+attributes #0 = { "kernel" }
+
+!llvm.module.flags = !{!0, !1}
+
+!0 = !{i32 7, !"openmp", i32 50}
+!1 = !{i32 7, !"openmp-device", i32 50}
More information about the llvm-commits
mailing list