Skip to content

[flang][OpenMP] Map device pointers on host device as well #145562

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 2 commits into from
Jun 24, 2025

Conversation

kparzysz
Copy link
Contributor

Given a TARGET DATA construct with USE_DEVICE_PTR(x) and IF(FALSE), the compiler will crash if x was used in the body. The cause of the crash is that the MLIR->LLVM codegen tries to look up the translated value of x, but one had not been mapped.

Given an IF clause, the translation will generate an if-then-else construct, with the "else" block corresponding to the false condition, i.e. the host device playing the role of the target device. In that block, still process the USE_DEVICE_ADDR/USE_DEVICE_PTR clauses, which will cause the translation mappings to be created.

Fixes #145558

Given a TARGET DATA construct with USE_DEVICE_PTR(x) and IF(FALSE),
the compiler will crash if `x` was used in the body.
The cause of the crash is that the MLIR->LLVM codegen tries to look up
the translated value of x, but one had not been mapped.

Given an IF clause, the translation will generate an if-then-else
construct, with the "else" block corresponding to the false condition,
i.e. the host device playing the role of the target device. In that
block, still process the USE_DEVICE_ADDR/USE_DEVICE_PTR clauses, which
will cause the translation mappings to be created.

Fixes llvm#145558
@kparzysz kparzysz requested review from skatrak and TIFitis June 24, 2025 18:11
@llvmbot llvmbot added mlir:llvm mlir flang Flang issues not falling into any other category mlir:openmp flang:fir-hlfir flang:openmp labels Jun 24, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 24, 2025

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

@llvm/pr-subscribers-flang-fir-hlfir

Author: Krzysztof Parzyszek (kparzysz)

Changes

Given a TARGET DATA construct with USE_DEVICE_PTR(x) and IF(FALSE), the compiler will crash if x was used in the body. The cause of the crash is that the MLIR->LLVM codegen tries to look up the translated value of x, but one had not been mapped.

Given an IF clause, the translation will generate an if-then-else construct, with the "else" block corresponding to the false condition, i.e. the host device playing the role of the target device. In that block, still process the USE_DEVICE_ADDR/USE_DEVICE_PTR clauses, which will cause the translation mappings to be created.

Fixes #145558


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

2 Files Affected:

  • (added) flang/test/Lower/OpenMP/target-data-if-false.f90 (+25)
  • (modified) mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp (+12)
diff --git a/flang/test/Lower/OpenMP/target-data-if-false.f90 b/flang/test/Lower/OpenMP/target-data-if-false.f90
new file mode 100644
index 0000000000000..ac0f675ddc806
--- /dev/null
+++ b/flang/test/Lower/OpenMP/target-data-if-false.f90
@@ -0,0 +1,25 @@
+!RUN: %flang_fc1 -emit-llvm -fopenmp %openmp_flags -fopenmp-version=52 %s -o - | FileCheck %s
+
+!Check that this doesn't crash.
+
+!CHECK-LABEL: define void @f00_()
+!CHECK: call i1 @_FortranAioOutputDerivedType
+
+subroutine f00
+  use iso_c_binding
+  type(c_ptr) :: x
+
+!$omp target data use_device_ptr(x) if(.false.)
+  print *, x
+!$omp end target data
+end
+
+!CHECK-LABEL: define void @f01_()
+!CHECK: call i1 @_FortranAioOutputInteger32
+subroutine f01
+  integer :: x
+
+!$omp target data use_device_addr(x) if(.false.)
+  print *, x
+!$omp end target data
+end
diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
index 90ce06a0345c0..d7986dbf451fc 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
@@ -4549,6 +4549,18 @@ convertOmpTargetData(Operation *op, llvm::IRBuilderBase &builder,
       }
       break;
     case BodyGenTy::DupNoPriv:
+      if (info.DevicePtrInfoMap.empty()) {
+        // For host device we still need to do the mapping for codegen,
+        // otherwise it may try to lookup a missing value.
+        if (!ompBuilder->Config.IsTargetDevice.value_or(false)) {
+          mapUseDevice(llvm::OpenMPIRBuilder::DeviceInfoTy::Address,
+                       blockArgIface.getUseDeviceAddrBlockArgs(),
+                       useDeviceAddrVars, mapData);
+          mapUseDevice(llvm::OpenMPIRBuilder::DeviceInfoTy::Pointer,
+                       blockArgIface.getUseDevicePtrBlockArgs(),
+                       useDevicePtrVars, mapData);
+        }
+      }
       // We must always restoreIP regardless of doing anything the caller
       // does not restore it, leading to incorrect (no) branch generation.
       builder.restoreIP(codeGenIP);

@llvmbot
Copy link
Member

llvmbot commented Jun 24, 2025

@llvm/pr-subscribers-flang-openmp

Author: Krzysztof Parzyszek (kparzysz)

Changes

Given a TARGET DATA construct with USE_DEVICE_PTR(x) and IF(FALSE), the compiler will crash if x was used in the body. The cause of the crash is that the MLIR->LLVM codegen tries to look up the translated value of x, but one had not been mapped.

Given an IF clause, the translation will generate an if-then-else construct, with the "else" block corresponding to the false condition, i.e. the host device playing the role of the target device. In that block, still process the USE_DEVICE_ADDR/USE_DEVICE_PTR clauses, which will cause the translation mappings to be created.

Fixes #145558


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

2 Files Affected:

  • (added) flang/test/Lower/OpenMP/target-data-if-false.f90 (+25)
  • (modified) mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp (+12)
diff --git a/flang/test/Lower/OpenMP/target-data-if-false.f90 b/flang/test/Lower/OpenMP/target-data-if-false.f90
new file mode 100644
index 0000000000000..ac0f675ddc806
--- /dev/null
+++ b/flang/test/Lower/OpenMP/target-data-if-false.f90
@@ -0,0 +1,25 @@
+!RUN: %flang_fc1 -emit-llvm -fopenmp %openmp_flags -fopenmp-version=52 %s -o - | FileCheck %s
+
+!Check that this doesn't crash.
+
+!CHECK-LABEL: define void @f00_()
+!CHECK: call i1 @_FortranAioOutputDerivedType
+
+subroutine f00
+  use iso_c_binding
+  type(c_ptr) :: x
+
+!$omp target data use_device_ptr(x) if(.false.)
+  print *, x
+!$omp end target data
+end
+
+!CHECK-LABEL: define void @f01_()
+!CHECK: call i1 @_FortranAioOutputInteger32
+subroutine f01
+  integer :: x
+
+!$omp target data use_device_addr(x) if(.false.)
+  print *, x
+!$omp end target data
+end
diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
index 90ce06a0345c0..d7986dbf451fc 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
@@ -4549,6 +4549,18 @@ convertOmpTargetData(Operation *op, llvm::IRBuilderBase &builder,
       }
       break;
     case BodyGenTy::DupNoPriv:
+      if (info.DevicePtrInfoMap.empty()) {
+        // For host device we still need to do the mapping for codegen,
+        // otherwise it may try to lookup a missing value.
+        if (!ompBuilder->Config.IsTargetDevice.value_or(false)) {
+          mapUseDevice(llvm::OpenMPIRBuilder::DeviceInfoTy::Address,
+                       blockArgIface.getUseDeviceAddrBlockArgs(),
+                       useDeviceAddrVars, mapData);
+          mapUseDevice(llvm::OpenMPIRBuilder::DeviceInfoTy::Pointer,
+                       blockArgIface.getUseDevicePtrBlockArgs(),
+                       useDevicePtrVars, mapData);
+        }
+      }
       // We must always restoreIP regardless of doing anything the caller
       // does not restore it, leading to incorrect (no) branch generation.
       builder.restoreIP(codeGenIP);

@llvmbot
Copy link
Member

llvmbot commented Jun 24, 2025

@llvm/pr-subscribers-mlir

Author: Krzysztof Parzyszek (kparzysz)

Changes

Given a TARGET DATA construct with USE_DEVICE_PTR(x) and IF(FALSE), the compiler will crash if x was used in the body. The cause of the crash is that the MLIR->LLVM codegen tries to look up the translated value of x, but one had not been mapped.

Given an IF clause, the translation will generate an if-then-else construct, with the "else" block corresponding to the false condition, i.e. the host device playing the role of the target device. In that block, still process the USE_DEVICE_ADDR/USE_DEVICE_PTR clauses, which will cause the translation mappings to be created.

Fixes #145558


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

2 Files Affected:

  • (added) flang/test/Lower/OpenMP/target-data-if-false.f90 (+25)
  • (modified) mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp (+12)
diff --git a/flang/test/Lower/OpenMP/target-data-if-false.f90 b/flang/test/Lower/OpenMP/target-data-if-false.f90
new file mode 100644
index 0000000000000..ac0f675ddc806
--- /dev/null
+++ b/flang/test/Lower/OpenMP/target-data-if-false.f90
@@ -0,0 +1,25 @@
+!RUN: %flang_fc1 -emit-llvm -fopenmp %openmp_flags -fopenmp-version=52 %s -o - | FileCheck %s
+
+!Check that this doesn't crash.
+
+!CHECK-LABEL: define void @f00_()
+!CHECK: call i1 @_FortranAioOutputDerivedType
+
+subroutine f00
+  use iso_c_binding
+  type(c_ptr) :: x
+
+!$omp target data use_device_ptr(x) if(.false.)
+  print *, x
+!$omp end target data
+end
+
+!CHECK-LABEL: define void @f01_()
+!CHECK: call i1 @_FortranAioOutputInteger32
+subroutine f01
+  integer :: x
+
+!$omp target data use_device_addr(x) if(.false.)
+  print *, x
+!$omp end target data
+end
diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
index 90ce06a0345c0..d7986dbf451fc 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
@@ -4549,6 +4549,18 @@ convertOmpTargetData(Operation *op, llvm::IRBuilderBase &builder,
       }
       break;
     case BodyGenTy::DupNoPriv:
+      if (info.DevicePtrInfoMap.empty()) {
+        // For host device we still need to do the mapping for codegen,
+        // otherwise it may try to lookup a missing value.
+        if (!ompBuilder->Config.IsTargetDevice.value_or(false)) {
+          mapUseDevice(llvm::OpenMPIRBuilder::DeviceInfoTy::Address,
+                       blockArgIface.getUseDeviceAddrBlockArgs(),
+                       useDeviceAddrVars, mapData);
+          mapUseDevice(llvm::OpenMPIRBuilder::DeviceInfoTy::Pointer,
+                       blockArgIface.getUseDevicePtrBlockArgs(),
+                       useDevicePtrVars, mapData);
+        }
+      }
       // We must always restoreIP regardless of doing anything the caller
       // does not restore it, leading to incorrect (no) branch generation.
       builder.restoreIP(codeGenIP);

blockArgIface.getUseDevicePtrBlockArgs(),
useDevicePtrVars, mapData);
}
}
// We must always restoreIP regardless of doing anything the caller
// does not restore it, leading to incorrect (no) branch generation.
builder.restoreIP(codeGenIP);
Copy link
Member

Choose a reason for hiding this comment

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

Nit: Sorry unrelated to your change, minor code cleanup.

This restoreIP call seems redundant as we have one at the entry of bodyGenCB, can we please remove it and move the comment to the restoreIP call above.

Thanks.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The one at the beginning of bodyGenCB?

Copy link
Member

Choose a reason for hiding this comment

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

Thanks, the new revision is what I wanted :)

Copy link
Member

@TIFitis TIFitis left a comment

Choose a reason for hiding this comment

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

LGTM.

@kparzysz kparzysz merged commit 3a71884 into llvm:main Jun 24, 2025
7 checks passed
@kparzysz kparzysz deleted the users/kparzysz/target-data-if-false branch June 24, 2025 20:38
anthonyhatran pushed a commit to anthonyhatran/llvm-project that referenced this pull request Jun 26, 2025
Given a TARGET DATA construct with USE_DEVICE_PTR(x) and IF(FALSE), the
compiler will crash if `x` was used in the body. The cause of the crash
is that the MLIR->LLVM codegen tries to look up the translated value of
x, but one had not been mapped.

Given an IF clause, the translation will generate an if-then-else
construct, with the "else" block corresponding to the false condition,
i.e. the host device playing the role of the target device. In that
block, still process the USE_DEVICE_ADDR/USE_DEVICE_PTR clauses, which
will cause the translation mappings to be created.

Fixes llvm#145558
rlavaee pushed a commit to rlavaee/llvm-project that referenced this pull request Jul 1, 2025
Given a TARGET DATA construct with USE_DEVICE_PTR(x) and IF(FALSE), the
compiler will crash if `x` was used in the body. The cause of the crash
is that the MLIR->LLVM codegen tries to look up the translated value of
x, but one had not been mapped.

Given an IF clause, the translation will generate an if-then-else
construct, with the "else" block corresponding to the false condition,
i.e. the host device playing the role of the target device. In that
block, still process the USE_DEVICE_ADDR/USE_DEVICE_PTR clauses, which
will cause the translation mappings to be created.

Fixes llvm#145558
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

OpenMP TARGET DATA crash with IF(.FALSE.)
3 participants