[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
Wed May 6 23:52:43 PDT 2026


https://github.com/IamYJLee created https://github.com/llvm/llvm-project/pull/196249

## Issue
`getKernelEnvironementGVFromKernelInitCB` uses `cast<GlobalVariable>` on the first argument of `__kmpc_target_init`. 
When that argument is `ptr null`, the cast fails and OpenMPOpt hits an assertion.

## Fix
Use `dyn_cast` instead and let each caller skip the kernel when the kernel environment is missing.
This does not affect well-formed IR.

Fixes #191973.

>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] [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;



More information about the llvm-commits mailing list