[flang-commits] [flang] [llvm] [OpenMPIRBuilder] Clear the debug location when emitting reduction helpers (PR #211395)

Spencer Bryngelson via flang-commits flang-commits at lists.llvm.org
Thu Jul 23 05:30:02 PDT 2026


https://github.com/sbryngelson updated https://github.com/llvm/llvm-project/pull/211395

>From 4b01dd5d9b13e26526955dc9ad9b353ff9e93731 Mon Sep 17 00:00:00 2001
From: Spencer Bryngelson <sbryngelson at gmail.com>
Date: Wed, 22 Jul 2026 17:23:23 -0500
Subject: [PATCH] [OpenMPIRBuilder] Clear the debug location when emitting
 reduction helpers

The device reduction helpers are created with no debug info of their own,
but the builder's current debug location is left set while their bodies are
emitted. Their instructions therefore carry locations scoped to the enclosing
kernel's subprogram.

The verifier's check only applies to functions that have a subprogram, so
this is latent until the inliner folds a helper into one that does. In a
Fortran target region with a scalar reduction that happens during the device
LTO link, and the module is rejected with "!dbg attachment points at wrong
subprogram for function". -g at -O1 and above is enough to hit it.

Clear the debug location after switching the insert point into each helper.

Fixes #211385.
---
 .../OpenMP/target-reduction-debug-loc.f90     | 43 +++++++++++++++++++
 llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp     | 12 +++++-
 2 files changed, 53 insertions(+), 2 deletions(-)
 create mode 100644 flang/test/Integration/OpenMP/target-reduction-debug-loc.f90

diff --git a/flang/test/Integration/OpenMP/target-reduction-debug-loc.f90 b/flang/test/Integration/OpenMP/target-reduction-debug-loc.f90
new file mode 100644
index 0000000000000..599bf5900032a
--- /dev/null
+++ b/flang/test/Integration/OpenMP/target-reduction-debug-loc.f90
@@ -0,0 +1,43 @@
+!===----------------------------------------------------------------------===!
+! This directory can be used to add Integration tests involving multiple
+! stages of the compiler (for eg. from Fortran to LLVM IR). It should not
+! contain executable tests. We should only add tests here sparingly and only
+! if there is no other way to test. Repeat this message in each test that is
+! added to this directory and sub-directories.
+!===----------------------------------------------------------------------===!
+
+! The device reduction helpers emitted by OpenMPIRBuilder have no debug info of
+! their own. If the builder's current debug location is left set while they are
+! emitted, their instructions carry locations scoped to the enclosing kernel's
+! subprogram. That is latent until the inliner folds a helper into a function
+! that does have a subprogram, at which point the module fails verification with
+! "!dbg attachment points at wrong subprogram for function".
+
+! REQUIRES: amdgpu-registered-target
+
+! RUN: %flang_fc1 -emit-llvm -fopenmp -fopenmp-is-target-device \
+! RUN:   -triple amdgcn-amd-amdhsa -debug-info-kind=standalone -O0 \
+! RUN:   -o - %s | FileCheck %s
+
+subroutine k(a, n, s)
+  real(8), intent(in)  :: a(*)
+  integer, intent(in)  :: n
+  real(8), intent(out) :: s
+  integer :: i
+  s = 0
+  !$omp target teams distribute parallel do reduction(+:s)
+  do i = 1, n
+     s = s + a(i)
+  end do
+end subroutine
+
+! The helpers must be emitted without debug locations, so no !dbg appears
+! between their definition and the closing brace.
+
+! CHECK-LABEL: define internal void @_omp_reduction_shuffle_and_reduce_func
+! CHECK-NOT:     !dbg
+! CHECK:       }
+
+! CHECK-LABEL: define internal void @_omp_reduction_inter_warp_copy_func
+! CHECK-NOT:     !dbg
+! CHECK:       }
diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
index e19ed110adf1e..292b8e09e2bd5 100644
--- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
+++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
@@ -3526,7 +3526,8 @@ Error OpenMPIRBuilder::emitReductionListCopy(
 Expected<Function *> OpenMPIRBuilder::emitInterWarpCopyFunction(
     const LocationDescription &Loc, ArrayRef<ReductionInfo> ReductionInfos,
     AttributeList FuncAttrs, ArrayRef<bool> IsByRef) {
-  InsertPointTy SavedIP = Builder.saveIP();
+  // Restores the insertion point and the debug location on the way out.
+  IRBuilder<>::InsertPointGuard IPG(Builder);
   LLVMContext &Ctx = M.getContext();
   FunctionType *FuncTy = FunctionType::get(
       Builder.getVoidTy(), {Builder.getPtrTy(), Builder.getInt32Ty()},
@@ -3540,6 +3541,9 @@ Expected<Function *> OpenMPIRBuilder::emitInterWarpCopyFunction(
   WcFunc->addParamAttr(1, Attribute::NoUndef);
   BasicBlock *EntryBB = BasicBlock::Create(M.getContext(), "entry", WcFunc);
   Builder.SetInsertPoint(EntryBB);
+  // The helper has no debug info of its own; a location left over from the
+  // caller would be scoped to the caller's subprogram.
+  Builder.SetCurrentDebugLocation(DebugLoc());
 
   // ReduceList: thread local Reduce list.
   // At the stage of the computation when this function is called, partially
@@ -3778,7 +3782,6 @@ Expected<Function *> OpenMPIRBuilder::emitInterWarpCopyFunction(
   }
 
   Builder.CreateRetVoid();
-  Builder.restoreIP(SavedIP);
 
   return WcFunc;
 }
@@ -3786,6 +3789,8 @@ Expected<Function *> OpenMPIRBuilder::emitInterWarpCopyFunction(
 Expected<Function *> OpenMPIRBuilder::emitShuffleAndReduceFunction(
     ArrayRef<ReductionInfo> ReductionInfos, Function *ReduceFn,
     AttributeList FuncAttrs, ArrayRef<bool> IsByRef) {
+  // Restores the insertion point and the debug location on the way out.
+  IRBuilder<>::InsertPointGuard IPG(Builder);
   LLVMContext &Ctx = M.getContext();
   FunctionType *FuncTy =
       FunctionType::get(Builder.getVoidTy(),
@@ -3806,6 +3811,9 @@ Expected<Function *> OpenMPIRBuilder::emitShuffleAndReduceFunction(
   SarFunc->addParamAttr(3, Attribute::SExt);
   BasicBlock *EntryBB = BasicBlock::Create(M.getContext(), "entry", SarFunc);
   Builder.SetInsertPoint(EntryBB);
+  // The helper has no debug info of its own; a location left over from the
+  // caller would be scoped to the caller's subprogram.
+  Builder.SetCurrentDebugLocation(DebugLoc());
 
   // Thread local Reduce list used to host the values of data to be reduced.
   Argument *ReduceListArg = SarFunc->getArg(0);



More information about the flang-commits mailing list