[Mlir-commits] [mlir] 0566bfb - [OpenMP] Move constant size allocas in the entry block. (#231907)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Mon Oct 19 01:21:30 PDT 2026


Author: Abid Qadeer
Date: 2026-10-19T09:21:25+01:00
New Revision: 0566bfbe2e6545c0b18cc648420cfbe977b7bb9e

URL: https://github.com/llvm/llvm-project/commit/0566bfbe2e6545c0b18cc648420cfbe977b7bb9e
DIFF: https://github.com/llvm/llvm-project/commit/0566bfbe2e6545c0b18cc648420cfbe977b7bb9e.diff

LOG: [OpenMP] Move constant size allocas in the entry block. (#231907)

The `createOutlinedFunction` embeds the user code in the middle of the
outlined function, so allocas from the region end up outside its entry
block. It already moves the constant-sized ones back, but only when
compiling for the device.

Doing it on the host too helps in two ways.

1. Better debug experience. #229876 started placing the hidden variables
that hold the bounds of an adjustable array in allocas. They only get a
frame slot if they are in the entry block.

2. The comment in the code says that we "must move what allocas we can
into the entry block to avoid possible breaking optimisations for
device", but that reasoning is true for the host as well. SROA only
looks at allocas in the entry block.

Assisted By: Cursor

---------

Co-authored-by: Cursor <cursoragent at cursor.com>

Added: 
    

Modified: 
    llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
    mlir/test/Target/LLVMIR/omptarget-constant-alloca-raise.mlir
    mlir/test/Target/LLVMIR/openmp-target-wsloop-private.mlir

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
index eee3dca5a014f..c8695bf2b57a9 100644
--- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
+++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
@@ -1035,9 +1035,7 @@ void OpenMPIRBuilder::finalize(Function *Fn) {
   // The createTarget functions embeds user written code into
   // the target region which may inject allocas which need to
   // be moved to the entry block of our target or risk malformed
-  // optimisations by later passes, this is only relevant for
-  // the device pass which appears to be a little more delicate
-  // when it comes to optimisations (however, we do not block on
+  // optimisations by later passes (however, we do not block on
   // that here, it's up to the inserter to the list to do so).
   // This notbaly has to occur after the OutlinedInfo candidates
   // have been extracted so we have an end product that will not
@@ -9398,9 +9396,8 @@ static Expected<Function *> createOutlinedFunction(
 
   // As we embed the user code in the middle of our target region after we
   // generate entry code, we must move what allocas we can into the entry
-  // block to avoid possible breaking optimisations for device
-  if (OMPBuilder.Config.isTargetDevice())
-    OMPBuilder.ConstantAllocaRaiseCandidates.emplace_back(Func);
+  // block to avoid possible breaking optimisations
+  OMPBuilder.ConstantAllocaRaiseCandidates.emplace_back(Func);
 
   BasicBlock *ExitBB = splitBB(Builder, /*CreateBranch=*/true, "target.exit");
   BasicBlock *OutlinedBodyBB =

diff  --git a/mlir/test/Target/LLVMIR/omptarget-constant-alloca-raise.mlir b/mlir/test/Target/LLVMIR/omptarget-constant-alloca-raise.mlir
index 1b53ec3e058a8..4897bc4c379f8 100644
--- a/mlir/test/Target/LLVMIR/omptarget-constant-alloca-raise.mlir
+++ b/mlir/test/Target/LLVMIR/omptarget-constant-alloca-raise.mlir
@@ -1,4 +1,4 @@
-// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+// RUN: mlir-translate -mlir-to-llvmir -split-input-file %s | FileCheck %s
 
 // A small condensed version of a problem requiring constant alloca raising in
 // Target Region Entries for user injected code, found in an issue in the Flang
@@ -42,3 +42,38 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<"dlti.alloca_memo
 
 // CHECK: user_code.entry:                                  ; preds = %entry
 // CHECK-NEXT:  %[[MAP_ARG_ALLOC:.*]] = call align 8 ptr @__kmpc_alloc_shared(i64 8)
+
+// -----
+
+// The same raising is required for the host fallback copy of a target region,
+// where the user allocations are injected into a separate block in the same
+// way.
+
+module attributes {llvm.target_triple = "x86_64-unknown-linux-gnu", omp.is_target_device = false} {
+  llvm.func @_QQmain() {
+    %1 = llvm.mlir.constant(1 : i64) : i64
+    %2 = llvm.alloca %1 x !llvm.struct<(ptr)> : (i64) -> !llvm.ptr
+    %3 = omp.map.info var_ptr(%2 : !llvm.ptr, !llvm.struct<(ptr)>) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr
+    omp.target kernel_type(generic) map_entries(%3 -> %arg0 : !llvm.ptr) {
+      %4 = llvm.mlir.constant(1 : i32) : i32
+      %5 = llvm.alloca %4 x !llvm.struct<(ptr)> {alignment = 8 : i64} : (i32) -> !llvm.ptr
+      %6 = llvm.mlir.constant(50 : i32) : i32
+      %7 = llvm.mlir.constant(1 : i64) : i64
+      %8 = llvm.alloca %7 x i32 : (i64) -> !llvm.ptr
+      llvm.store %6, %8 : i32, !llvm.ptr
+      %9 = llvm.mlir.undef : !llvm.struct<(ptr)>
+      %10 = llvm.insertvalue %8, %9[0] : !llvm.struct<(ptr)>
+      llvm.store %10, %5 : !llvm.struct<(ptr)>, !llvm.ptr
+      %11 = llvm.call @_ExternalCall(%arg0, %5) : (!llvm.ptr, !llvm.ptr) -> !llvm.struct<()>
+      omp.terminator
+    }
+    llvm.return
+  }
+  llvm.func @_ExternalCall(!llvm.ptr, !llvm.ptr) -> !llvm.struct<()>
+}
+
+// CHECK:      define internal void @{{.*}}QQmain_l{{[0-9]+}}(ptr {{.*}}, ptr {{.*}}) {
+// CHECK-NEXT: entry:
+// CHECK-NEXT:  %[[HOST_MOVED_ALLOCA1:.*]] = alloca { ptr }, align 8
+// CHECK-NEXT:  %[[HOST_MOVED_ALLOCA2:.*]] = alloca i32, i64 1, align 4
+// CHECK-NEXT:  br label %omp.region.after_alloca

diff  --git a/mlir/test/Target/LLVMIR/openmp-target-wsloop-private.mlir b/mlir/test/Target/LLVMIR/openmp-target-wsloop-private.mlir
index 359ae9a21d0ce..67e656c3f3045 100644
--- a/mlir/test/Target/LLVMIR/openmp-target-wsloop-private.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-target-wsloop-private.mlir
@@ -31,10 +31,10 @@ llvm.func @test_alloca_ip_workaround() {
 
 // CHECK-LABEL: define {{.*}} @__omp_offloading_{{.*}}_test_alloca_ip_workaround
 // CHECK:       entry:
+// CHECK:         %[[ALLOC_REG_ARG:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, align 8
 // CHECK:         %[[PRIV_ALLOC:.*]] = alloca ptr, align 8
 
 // CHECK:       omp.target:
-// CHECK:         %[[ALLOC_REG_ARG:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, align 8
 // Verify that the `init` region of the privatizer is inlined within the `target`
 // region body not before that.
 // CHECK:         call void @foo(ptr %[[ALLOC_REG_ARG]])


        


More information about the Mlir-commits mailing list