Skip to content

[mlir][OpenMP] Use correct debug location with link clause. #145026

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 25, 2025

Conversation

abidh
Copy link
Contributor

@abidh abidh commented Jun 20, 2025

Please see the following program.

module test_0
    INTEGER :: sp = 1
!$omp declare target link(sp)
end module test_0

program main
use test_0
integer :: new_len

!$omp target map(tofrom:new_len) map(tofrom:sp)
    new_len = sp
!$omp end target

  print *, new_len
  print *, sp
end program

When compiled with
flang -g -O0 -fopenmp --offload-arch=gfx1100

will fail the compilation with the following error:

dbg attachment points at wrong subprogram for function

The reason is that with the link clause on !$omp declare target, an extra load instruction is inserted. But the debug location was not updated before insertion which caused an invalid location to be attached to the instruction.

Please see the following program.

module test_0
    INTEGER :: sp = 1
!$omp declare target link(sp)
end module test_0

program main
use test_0
integer :: new_len

!$omp target map(tofrom:new_len) map(tofrom:sp)
    new_len = sp
!$omp end target

  print *, new_len
  print *, sp
end program

flang -g -O0 -fopenmp --offload-arch=gfx1100

will fail the compilation with the following error:

dbg attachment points at wrong subprogram for function

The reason is that with the link clause on !$omp declare target, an
extra load instruction is inserted. But the debug location was not
updated before insertion which cuased it to have an invalid debug
location.
@llvmbot
Copy link
Member

llvmbot commented Jun 20, 2025

@llvm/pr-subscribers-mlir-llvm
@llvm/pr-subscribers-mlir-openmp

@llvm/pr-subscribers-mlir

Author: Abid Qadeer (abidh)

Changes

Please see the following program.

module test_0
    INTEGER :: sp = 1
!$omp declare target link(sp)
end module test_0

program main
use test_0
integer :: new_len

!$omp target map(tofrom:new_len) map(tofrom:sp)
    new_len = sp
!$omp end target

  print *, new_len
  print *, sp
end program

When compiled with
flang -g -O0 -fopenmp --offload-arch=gfx1100

will fail the compilation with the following error:

dbg attachment points at wrong subprogram for function

The reason is that with the link clause on !$omp declare target, an extra load instruction is inserted. But the debug location was not updated before insertion which caused an invalid location to be attached to the instruction.


Full diff: https://github.com/llvm/llvm-project/pull/145026.diff

2 Files Affected:

  • (modified) mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp (+2)
  • (added) mlir/test/Target/LLVMIR/omptarget-debug-map-link-loc.mlir (+40)
diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
index 90ce06a0345c0..63f7fa1638904 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
@@ -4808,6 +4808,7 @@ handleDeclareTargetMapVar(MapInfoData &mapData,
                           llvm::IRBuilderBase &builder, llvm::Function *func) {
   assert(moduleTranslation.getOpenMPBuilder()->Config.isTargetDevice() &&
          "function only supported for target device codegen");
+  llvm::IRBuilderBase::InsertPointGuard guard(builder);
   for (size_t i = 0; i < mapData.MapClause.size(); ++i) {
     // In the case of declare target mapped variables, the basePointer is
     // the reference pointer generated by the convertDeclareTargetAttr
@@ -4842,6 +4843,7 @@ handleDeclareTargetMapVar(MapInfoData &mapData,
       for (llvm::User *user : userVec) {
         if (auto *insn = dyn_cast<llvm::Instruction>(user)) {
           if (insn->getFunction() == func) {
+            builder.SetCurrentDebugLocation(insn->getDebugLoc());
             auto *load = builder.CreateLoad(mapData.BasePointers[i]->getType(),
                                             mapData.BasePointers[i]);
             load->moveBefore(insn->getIterator());
diff --git a/mlir/test/Target/LLVMIR/omptarget-debug-map-link-loc.mlir b/mlir/test/Target/LLVMIR/omptarget-debug-map-link-loc.mlir
new file mode 100644
index 0000000000000..89fc1dde4b6cb
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/omptarget-debug-map-link-loc.mlir
@@ -0,0 +1,40 @@
+// RUN: mlir-translate -mlir-to-llvmir %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<"dlti.alloca_memory_space", 5 : ui32>>, llvm.target_triple = "amdgcn-amd-amdhsa", omp.is_target_device = true} {
+  llvm.mlir.global external @_QMtest_0Esp() {addr_space = 1 : i32, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} : i32 {
+    %0 = llvm.mlir.constant(1 : i32) : i32 loc(#loc1)
+    llvm.return %0 : i32 loc(#loc1)
+  } loc(#loc1)
+  llvm.func @_QQmain() {
+    %0 = llvm.mlir.constant(1 : i64) : i64
+    %1 = llvm.alloca %0 x i32 : (i64) -> !llvm.ptr<5> loc(#loc2)
+    %2 = llvm.addrspacecast %1 : !llvm.ptr<5> to !llvm.ptr loc(#loc2)
+    %5 = llvm.mlir.addressof @_QMtest_0Esp : !llvm.ptr<1> loc(#loc1)
+    %6 = llvm.addrspacecast %5 : !llvm.ptr<1> to !llvm.ptr loc(#loc1)
+    %7 = omp.map.info var_ptr(%2 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr loc(#loc3)
+    %8 = omp.map.info var_ptr(%6 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr loc(#loc3)
+    omp.target map_entries(%7 -> %arg0, %8 -> %arg1 : !llvm.ptr, !llvm.ptr) {
+      %16 = llvm.load %arg1 : !llvm.ptr -> i32 loc(#loc5)
+      llvm.store %16, %arg0 : i32, !llvm.ptr loc(#loc5)
+      omp.terminator loc(#loc5)
+    } loc(#loc5)
+    llvm.return loc(#loc6)
+  } loc(#loc15)
+}
+#di_file = #llvm.di_file<"target7.f90" in "">
+#di_null_type = #llvm.di_null_type
+#di_compile_unit = #llvm.di_compile_unit<id = distinct[0]<>,
+ sourceLanguage = DW_LANG_Fortran95, file = #di_file, producer = "flang",
+ isOptimized = false, emissionKind = LineTablesOnly>
+#di_subroutine_type = #llvm.di_subroutine_type<
+  callingConvention = DW_CC_program, types = #di_null_type>
+#di_subprogram = #llvm.di_subprogram<id = distinct[1]<>,
+  compileUnit = #di_compile_unit, scope = #di_file, name = "main",
+  file = #di_file, subprogramFlags = "Definition|MainSubprogram",
+  type = #di_subroutine_type>
+#loc1 = loc("test.f90":3:18)
+#loc2 = loc("test.f90":7:7)
+#loc3 = loc("test.f90":9:18)
+#loc5 = loc("test.f90":11:7)
+#loc6 = loc("test.f90":12:7)
+#loc15 = loc(fused<#di_subprogram>[#loc2])

@llvmbot
Copy link
Member

llvmbot commented Jun 20, 2025

@llvm/pr-subscribers-flang-openmp

Author: Abid Qadeer (abidh)

Changes

Please see the following program.

module test_0
    INTEGER :: sp = 1
!$omp declare target link(sp)
end module test_0

program main
use test_0
integer :: new_len

!$omp target map(tofrom:new_len) map(tofrom:sp)
    new_len = sp
!$omp end target

  print *, new_len
  print *, sp
end program

When compiled with
flang -g -O0 -fopenmp --offload-arch=gfx1100

will fail the compilation with the following error:

dbg attachment points at wrong subprogram for function

The reason is that with the link clause on !$omp declare target, an extra load instruction is inserted. But the debug location was not updated before insertion which caused an invalid location to be attached to the instruction.


Full diff: https://github.com/llvm/llvm-project/pull/145026.diff

2 Files Affected:

  • (modified) mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp (+2)
  • (added) mlir/test/Target/LLVMIR/omptarget-debug-map-link-loc.mlir (+40)
diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
index 90ce06a0345c0..63f7fa1638904 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
@@ -4808,6 +4808,7 @@ handleDeclareTargetMapVar(MapInfoData &mapData,
                           llvm::IRBuilderBase &builder, llvm::Function *func) {
   assert(moduleTranslation.getOpenMPBuilder()->Config.isTargetDevice() &&
          "function only supported for target device codegen");
+  llvm::IRBuilderBase::InsertPointGuard guard(builder);
   for (size_t i = 0; i < mapData.MapClause.size(); ++i) {
     // In the case of declare target mapped variables, the basePointer is
     // the reference pointer generated by the convertDeclareTargetAttr
@@ -4842,6 +4843,7 @@ handleDeclareTargetMapVar(MapInfoData &mapData,
       for (llvm::User *user : userVec) {
         if (auto *insn = dyn_cast<llvm::Instruction>(user)) {
           if (insn->getFunction() == func) {
+            builder.SetCurrentDebugLocation(insn->getDebugLoc());
             auto *load = builder.CreateLoad(mapData.BasePointers[i]->getType(),
                                             mapData.BasePointers[i]);
             load->moveBefore(insn->getIterator());
diff --git a/mlir/test/Target/LLVMIR/omptarget-debug-map-link-loc.mlir b/mlir/test/Target/LLVMIR/omptarget-debug-map-link-loc.mlir
new file mode 100644
index 0000000000000..89fc1dde4b6cb
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/omptarget-debug-map-link-loc.mlir
@@ -0,0 +1,40 @@
+// RUN: mlir-translate -mlir-to-llvmir %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<"dlti.alloca_memory_space", 5 : ui32>>, llvm.target_triple = "amdgcn-amd-amdhsa", omp.is_target_device = true} {
+  llvm.mlir.global external @_QMtest_0Esp() {addr_space = 1 : i32, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} : i32 {
+    %0 = llvm.mlir.constant(1 : i32) : i32 loc(#loc1)
+    llvm.return %0 : i32 loc(#loc1)
+  } loc(#loc1)
+  llvm.func @_QQmain() {
+    %0 = llvm.mlir.constant(1 : i64) : i64
+    %1 = llvm.alloca %0 x i32 : (i64) -> !llvm.ptr<5> loc(#loc2)
+    %2 = llvm.addrspacecast %1 : !llvm.ptr<5> to !llvm.ptr loc(#loc2)
+    %5 = llvm.mlir.addressof @_QMtest_0Esp : !llvm.ptr<1> loc(#loc1)
+    %6 = llvm.addrspacecast %5 : !llvm.ptr<1> to !llvm.ptr loc(#loc1)
+    %7 = omp.map.info var_ptr(%2 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr loc(#loc3)
+    %8 = omp.map.info var_ptr(%6 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr loc(#loc3)
+    omp.target map_entries(%7 -> %arg0, %8 -> %arg1 : !llvm.ptr, !llvm.ptr) {
+      %16 = llvm.load %arg1 : !llvm.ptr -> i32 loc(#loc5)
+      llvm.store %16, %arg0 : i32, !llvm.ptr loc(#loc5)
+      omp.terminator loc(#loc5)
+    } loc(#loc5)
+    llvm.return loc(#loc6)
+  } loc(#loc15)
+}
+#di_file = #llvm.di_file<"target7.f90" in "">
+#di_null_type = #llvm.di_null_type
+#di_compile_unit = #llvm.di_compile_unit<id = distinct[0]<>,
+ sourceLanguage = DW_LANG_Fortran95, file = #di_file, producer = "flang",
+ isOptimized = false, emissionKind = LineTablesOnly>
+#di_subroutine_type = #llvm.di_subroutine_type<
+  callingConvention = DW_CC_program, types = #di_null_type>
+#di_subprogram = #llvm.di_subprogram<id = distinct[1]<>,
+  compileUnit = #di_compile_unit, scope = #di_file, name = "main",
+  file = #di_file, subprogramFlags = "Definition|MainSubprogram",
+  type = #di_subroutine_type>
+#loc1 = loc("test.f90":3:18)
+#loc2 = loc("test.f90":7:7)
+#loc3 = loc("test.f90":9:18)
+#loc5 = loc("test.f90":11:7)
+#loc6 = loc("test.f90":12:7)
+#loc15 = loc(fused<#di_subprogram>[#loc2])

Copy link
Contributor

@bhandarkar-pranav bhandarkar-pranav left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@abidh abidh merged commit 0060376 into llvm:main Jun 25, 2025
12 checks passed
@abidh
Copy link
Contributor Author

abidh commented Jun 25, 2025

I noticed that it causes a sanitizer fail on the newly added test. I am investigating.

@qinkunbao
Copy link
Member

I noticed that it causes a sanitizer fail on the newly added test. I am investigating.

Hi, if the failure can’t be quickly fixed, do you mind reverting the PR first?

@abidh
Copy link
Contributor Author

abidh commented Jun 25, 2025

I noticed that it causes a sanitizer fail on the newly added test. I am investigating.

Hi, if the failure can’t be quickly fixed, do you mind reverting the PR first?

Done.

llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Jun 25, 2025
abidh added a commit to abidh/llvm-project that referenced this pull request Jun 26, 2025
The code in OpenMPIRBuilder::getTargetEntryUniqueInfo calls
ID.getDevice() even when getUniqueID has failed and ID is
un-initialized. This caused a sanitizer fail for me in
llvm#145026. Fix it by giving
a default value to ID. The value chosen is the same as used in
OpenMPToLLVMIRTranslation.cpp.
abidh added a commit that referenced this pull request Jun 26, 2025
The code in `OpenMPIRBuilder::getTargetEntryUniqueInfo` calls
`ID.getDevice()` even when `getUniqueID` has failed and ID is
un-initialized. This caused a sanitizer fail for me in
#145026. Fix it by giving a
default value to `ID`. The value chosen is the same as used in
`OpenMPToLLVMIRTranslation.cpp`.
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Jun 26, 2025
The code in `OpenMPIRBuilder::getTargetEntryUniqueInfo` calls
`ID.getDevice()` even when `getUniqueID` has failed and ID is
un-initialized. This caused a sanitizer fail for me in
llvm/llvm-project#145026. Fix it by giving a
default value to `ID`. The value chosen is the same as used in
`OpenMPToLLVMIRTranslation.cpp`.
abidh added a commit that referenced this pull request Jun 26, 2025
…145889)

#145026 was reverted because it
failed a sanitizer test. That issue has been fixed in
#145883.
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Jun 26, 2025
… clause. (#145889)

llvm/llvm-project#145026 was reverted because it
failed a sanitizer test. That issue has been fixed in
llvm/llvm-project#145883.
anthonyhatran pushed a commit to anthonyhatran/llvm-project that referenced this pull request Jun 26, 2025
)

Please see the following program.

```
module test_0
    INTEGER :: sp = 1
!$omp declare target link(sp)
end module test_0

program main
use test_0
integer :: new_len

!$omp target map(tofrom:new_len) map(tofrom:sp)
    new_len = sp
!$omp end target

  print *, new_len
  print *, sp
end program
```

When compiled with
`flang -g -O0 -fopenmp --offload-arch=gfx1100`

will fail the compilation with the following error:

`dbg attachment points at wrong subprogram for function`

The reason is that with the `link` clause on `!$omp declare target`, an
extra load instruction is inserted. But the debug location was not
updated before insertion which caused an invalid location to be attached
to the instruction.
anthonyhatran pushed a commit to anthonyhatran/llvm-project that referenced this pull request Jun 26, 2025
The code in `OpenMPIRBuilder::getTargetEntryUniqueInfo` calls
`ID.getDevice()` even when `getUniqueID` has failed and ID is
un-initialized. This caused a sanitizer fail for me in
llvm#145026. Fix it by giving a
default value to `ID`. The value chosen is the same as used in
`OpenMPToLLVMIRTranslation.cpp`.
anthonyhatran pushed a commit to anthonyhatran/llvm-project that referenced this pull request Jun 26, 2025
…lvm#145889)

llvm#145026 was reverted because it
failed a sanitizer test. That issue has been fixed in
llvm#145883.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants