[clang] clang-linker-wrapper: Set the host DataLayout on the offload wrapper module (PR #224280)
Matt Arsenault via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 17 06:00:07 PDT 2026
https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/224280
>From 5068c4140c97187d499e547aeb05ef5328ce3d22 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Thu, 17 Sep 2026 13:53:35 +0200
Subject: [PATCH] clang-linker-wrapper: Set the host DataLayout on the offload
wrapper module
The offload wrapper module was created with only a target triple, and the
datalayout wasn't set until later, where it was copied from the TargetMachine,
after the wrapping code already ran.
The wrapping code did query the datalayout for the pointer size, so this was
broken for host and devices with different pointer sizes.
queries the DataLayout (e.g. the size_t / intptr type via getSizeTTy), so on a
host whose pointer size differs from the default layout (e.g. a 32-bit host) it
used the wrong integer width for image offsets.
This removes a use of TargetMachine::createDataLayout, which I am trying to
remove.
Co-authored-by: Claude (Claude-Opus-4.8) <noreply at anthropic.com>
---
.../linker-wrapper-host-datalayout.c | 27 +++++++++++++++++++
.../linker-wrapper-image.c | 8 +++---
.../ClangLinkerWrapper.cpp | 9 +++----
3 files changed, 35 insertions(+), 9 deletions(-)
create mode 100644 clang/test/OffloadTools/clang-linker-wrapper/linker-wrapper-host-datalayout.c
diff --git a/clang/test/OffloadTools/clang-linker-wrapper/linker-wrapper-host-datalayout.c b/clang/test/OffloadTools/clang-linker-wrapper/linker-wrapper-host-datalayout.c
new file mode 100644
index 0000000000000..0c1e0ed04dd9d
--- /dev/null
+++ b/clang/test/OffloadTools/clang-linker-wrapper/linker-wrapper-host-datalayout.c
@@ -0,0 +1,27 @@
+// Check that the offload wrapper module is created with the correct host
+// DataLayout, so the wrapping code emits pointer-size-dependent values using
+// the correct pointer width rather than the default layout's.
+
+// REQUIRES: x86-registered-target, amdgpu-registered-target
+
+// RUN: %clang -cc1 -triple i386-unknown-linux-gnu -emit-obj %s -o %t.elf.o
+// RUN: %clang -cc1 -triple amdgpu9.00-amd-amdhsa -emit-llvm-bc %s -o %t.amdgpu.bc
+
+// RUN: llvm-offload-binary -o %t.out \
+// RUN: --image=file=%t.amdgpu.bc,kind=openmp,triple=amdgpu9.00-amd-amdhsa
+// RUN: %clang -cc1 %s -triple i386-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.out
+
+// RUN: clang-linker-wrapper --host-triple=i386-unknown-linux-gnu --dry-run \
+// RUN: --print-wrapped-module --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 \
+// RUN: | FileCheck %s
+
+// CHECK: target datalayout = "e-m:e-p:32:32-{{.*}}"
+// CHECK: target triple = "i386-unknown-linux-gnu"
+
+// The image offsets should use the host's 32-bit size_t type, instead of the
+// incorrect i64 according to the default DataLayout.
+
+// CHECK: @.omp_offloading.device_images =
+// CHECK-SAME: getelementptr (i8, ptr @.omp_offloading.device_image, i32 {{[0-9]+}})
+
+__attribute__((visibility("protected"), used)) int x;
diff --git a/clang/test/OffloadTools/clang-linker-wrapper/linker-wrapper-image.c b/clang/test/OffloadTools/clang-linker-wrapper/linker-wrapper-image.c
index 75226e913b3d3..baa56f951ac29 100644
--- a/clang/test/OffloadTools/clang-linker-wrapper/linker-wrapper-image.c
+++ b/clang/test/OffloadTools/clang-linker-wrapper/linker-wrapper-image.c
@@ -104,11 +104,11 @@
// CUDA-NEXT: %5 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i32 0, i32 5
// CUDA-NEXT: %name = load ptr, ptr %5, align 8
// CUDA-NEXT: %6 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i32 0, i32 6
-// CUDA-NEXT: %size = load i64, ptr %6, align 4
+// CUDA-NEXT: %size = load i64, ptr %6, align 8
// CUDA-NEXT: %7 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i32 0, i32 3
// CUDA-NEXT: %flags = load i32, ptr %7, align 4
// CUDA-NEXT: %8 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i32 0, i32 7
-// CUDA-NEXT: %data = load i64, ptr %8, align 4
+// CUDA-NEXT: %data = load i64, ptr %8, align 8
// CUDA-NEXT: %9 = trunc i64 %data to i32
// CUDA-NEXT: %type = and i32 %flags, 7
// CUDA-NEXT: %10 = and i32 %flags, 8
@@ -246,11 +246,11 @@
// HIP-NEXT: %5 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i32 0, i32 5
// HIP-NEXT: %name = load ptr, ptr %5, align 8
// HIP-NEXT: %6 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i32 0, i32 6
-// HIP-NEXT: %size = load i64, ptr %6, align 4
+// HIP-NEXT: %size = load i64, ptr %6, align 8
// HIP-NEXT: %7 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i32 0, i32 3
// HIP-NEXT: %flags = load i32, ptr %7, align 4
// HIP-NEXT: %8 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i32 0, i32 7
-// HIP-NEXT: %data = load i64, ptr %8, align 4
+// HIP-NEXT: %data = load i64, ptr %8, align 8
// HIP-NEXT: %9 = trunc i64 %data to i32
// HIP-NEXT: %type = and i32 %flags, 7
// HIP-NEXT: %10 = and i32 %flags, 8
diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
index ec1b824589de9..59faf38dda140 100644
--- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
@@ -706,9 +706,6 @@ Expected<StringRef> compileModule(Module &M, OffloadKind Kind) {
T->createTargetMachine(M.getTargetTriple(), CPU, Features, Options,
Reloc::PIC_, M.getCodeModel()));
- if (M.getDataLayout().isDefault())
- M.setDataLayout(TM->createDataLayout());
-
int FD = -1;
auto TempFileOrErr = createOutputFile(
ExecutableName + "." + getOffloadKindName(Kind) + ".image.wrapper", "o");
@@ -809,8 +806,10 @@ wrapDeviceImages(ArrayRef<std::unique_ptr<MemoryBuffer>> Buffers,
LLVMContext Context;
Module M("offload.wrapper.module", Context);
- M.setTargetTriple(Triple(
- Args.getLastArgValue(OPT_host_triple_EQ, sys::getDefaultTargetTriple())));
+ Triple TheTriple(
+ Args.getLastArgValue(OPT_host_triple_EQ, sys::getDefaultTargetTriple()));
+ M.setTargetTriple(TheTriple);
+ M.setDataLayout(TheTriple.computeDataLayout());
switch (Kind) {
case OFK_OpenMP:
More information about the cfe-commits
mailing list