From e87636defd1b64ee3682809f177d2d724298eb2e Mon Sep 17 00:00:00 2001 From: "Sabianin, Maksim" Date: Wed, 26 Mar 2025 07:20:06 -0700 Subject: [PATCH 1/3] [SYCL][ClangLinkerWrapper] Rework the testing of SYCL Offload Wrapping in clang-linker-wrapper The patch allows to test SYCL Offload Wrapping using clang-linker-wrapper in dry-run mode. Previously, it was tested by running the tool in non dry-run mode. The patch unites 2 debuging prints of "offload wrapper" step in clang-linker-wrapper in Verbose/DryRun modes. The patch returns the test case in linker-wrapper-sycl.cpp that has been removed in #17546. --- clang/test/Driver/linker-wrapper-sycl.cpp | 33 ++++---- .../test/Driver/sycl-linker-wrapper-image.cpp | 83 +++++++------------ .../ClangLinkerWrapper.cpp | 42 +++++----- 3 files changed, 72 insertions(+), 86 deletions(-) diff --git a/clang/test/Driver/linker-wrapper-sycl.cpp b/clang/test/Driver/linker-wrapper-sycl.cpp index 6ca069d82d5f5..45f4c91dd6f5d 100644 --- a/clang/test/Driver/linker-wrapper-sycl.cpp +++ b/clang/test/Driver/linker-wrapper-sycl.cpp @@ -19,7 +19,7 @@ // CHK-CMDS-NEXT: "{{.*}}llvm-link" -only-needed [[FIRSTLLVMLINKOUT]].bc {{.*}}.bc -o [[SECONDLLVMLINKOUT:.*]].bc --suppress-warnings // CHK-CMDS-NEXT: "{{.*}}sycl-post-link"{{.*}} SYCL_POST_LINK_OPTIONS -o [[SYCLPOSTLINKOUT:.*]].table [[SECONDLLVMLINKOUT]].bc // CHK-CMDS-NEXT: "{{.*}}llvm-spirv"{{.*}} LLVM_SPIRV_OPTIONS -o {{.*}} -// CHK-CMDS-NEXT: offload-wrapper: input: {{.*}}, output: [[WRAPPEROUT:.*]].bc +// CHK-CMDS-NEXT: offload-wrapper: input: {{.*}}, output: [[WRAPPEROUT:.*]].bc, compile-opts: , link-opts: // CHK-CMDS-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT:.*]] [[WRAPPEROUT]].bc // CHK-CMDS-NEXT: "{{.*}}/ld" -- HOST_LINKER_FLAGS -dynamic-linker HOST_DYN_LIB -o a.out [[LLCOUT]] HOST_LIB_PATH HOST_STAT_LIB {{.*}}.o @@ -32,7 +32,7 @@ // CHK-SPLIT-CMDS-NEXT: sycl-module-split: input: [[SECONDLLVMLINKOUT]].bc, output: [[SYCLMODULESPLITOUT:.*]].bc // CHK-SPLIT-CMDS-NEXT: "{{.*}}llvm-spirv"{{.*}} LLVM_SPIRV_OPTIONS -o [[SPIRVOUT:.*]].spv [[SYCLMODULESPLITOUT]].bc // LLVM-SPIRV is not called in dry-run -// CHK-SPLIT-CMDS-NEXT: offload-wrapper: input: [[SPIRVOUT]].spv, output: [[WRAPPEROUT:.*]].bc +// CHK-SPLIT-CMDS-NEXT: offload-wrapper: input: [[SPIRVOUT]].spv, output: [[WRAPPEROUT:.*]].bc, compile-opts: , link-opts: // CHK-SPLIT-CMDS-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT:.*]] [[WRAPPEROUT]].bc // CHK-SPLIT-CMDS-NEXT: "{{.*}}/ld" -- HOST_LINKER_FLAGS -dynamic-linker HOST_DYN_LIB -o a.out [[LLCOUT]] HOST_LIB_PATH HOST_STAT_LIB {{.*}}.o @@ -47,6 +47,11 @@ // RUN: clang-linker-wrapper -sycl-device-libraries=%t.devicelib.o -sycl-post-link-options="SYCL_POST_LINK_OPTIONS" -llvm-spirv-options="LLVM_SPIRV_OPTIONS" "--host-triple=x86_64-unknown-linux-gnu" "--triple=spir64" "--linker-path=/usr/bin/ld" -shared "--" HOST_LINKER_FLAGS "-dynamic-linker" HOST_DYN_LIB "-o" "a.out" HOST_LIB_PATH HOST_STAT_LIB %t.o --dry-run 2>&1 | FileCheck -check-prefix=CHK-SHARED %s // CHK-SHARED: "{{.*}}clang"{{.*}} -fPIC +// RUN: rm %T/linker_wrapper_dump || true +// RUN: clang-linker-wrapper -sycl-dump-device-code=%T/linker_wrapper_dump -sycl-device-libraries=%t.devicelib.o "--host-triple=x86_64-unknown-linux-gnu" "--triple=spir64" "--linker-path=/usr/bin/ld" -shared "--" HOST_LINKER_FLAGS "-dynamic-linker" HOST_DYN_LIB "-o" "a.out" HOST_LIB_PATH HOST_STAT_LIB %t.o --dry-run +// RUN: ls %T/linker_wrapper_dump | FileCheck -check-prefix=CHK-SYCL-DUMP-DEVICE %s +// CHK-SYCL-DUMP-DEVICE: {{.*}}.spv + /// Check for list of commands for standalone clang-linker-wrapper run for sycl (AOT for Intel GPU) // ------- // Generate .o file as linker wrapper input. @@ -117,8 +122,8 @@ // CHK-CMDS-AOT-NV-NEXT: "{{.*}}clang"{{.*}} -o [[CLANGOUT:.*]] --target=nvptx64-nvidia-cuda -march={{.*}} // CHK-CMDS-AOT-NV-NEXT: "{{.*}}ptxas"{{.*}} --output-file [[PTXASOUT:.*]] [[CLANGOUT]] // CHK-CMDS-AOT-NV-NEXT: "{{.*}}fatbinary"{{.*}} --create [[FATBINOUT:.*]] --image=profile={{.*}},file=[[CLANGOUT]] --image=profile={{.*}},file=[[PTXASOUT]] -// CHK-CMDS-AOT-NV-NEXT: offload-wrapper: input: [[FATBINOUT]], output: [[WRAPPEROUT:.*]] -// CHK-CMDS-AOT-NV-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT:.*]] [[WRAPPEROUT]] +// CHK-CMDS-AOT-NV-NEXT: offload-wrapper: input: [[FATBINOUT]], output: [[WRAPPEROUT:.*]].bc, +// CHK-CMDS-AOT-NV-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT:.*]] [[WRAPPEROUT]].bc // CHK-CMDS-AOT-NV-NEXT: "{{.*}}ld" -- HOST_LINKER_FLAGS -dynamic-linker HOST_DYN_LIB -o a.out [[LLCOUT]] HOST_LIB_PATH HOST_STAT_LIB {{.*}}.o /// Check for list of commands for standalone clang-linker-wrapper run for sycl (AOT for AMD) @@ -135,8 +140,8 @@ // CHK-CMDS-AOT-AMD-NEXT: "{{.*}}sycl-post-link"{{.*}} SYCL_POST_LINK_OPTIONS -o [[SYCLPOSTLINKOUT:.*]].table [[FIRSTLLVMLINKOUT]].bc // CHK-CMDS-AOT-AMD-NEXT: "{{.*}}clang"{{.*}} -o [[CLANGOUT:.*]] --target=amdgcn-amd-amdhsa -mcpu={{.*}} // CHK-CMDS-AOT-AMD-NEXT: "{{.*}}clang-offload-bundler"{{.*}} -targets=host-x86_64-unknown-linux-gnu,hip-amdgcn-amd-amdhsa--gfx803 -input=/dev/null -input=[[CLANGOUT]] -output=[[BUNDLEROUT:.*]] -// CHK-CMDS-AOT-AMD-NEXT: offload-wrapper: input: [[BUNDLEROUT]], output: [[WRAPPEROUT:.*]] -// CHK-CMDS-AOT-AMD-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT:.*]] [[WRAPPEROUT]] +// CHK-CMDS-AOT-AMD-NEXT: offload-wrapper: input: [[BUNDLEROUT]], output: [[WRAPPEROUT:.*]].bc, +// CHK-CMDS-AOT-AMD-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT:.*]] [[WRAPPEROUT]].bc // CHK-CMDS-AOT-AMD-NEXT: "{{.*}}ld" -- HOST_LINKER_FLAGS -dynamic-linker HOST_DYN_LIB -o a.out [[LLCOUT]] HOST_LIB_PATH HOST_STAT_LIB {{.*}}.o /// Check for -sycl-embed-ir for standalone clang-linker-wrapper run for sycl (NVPTX) @@ -157,13 +162,13 @@ // CHK-CMDS-AOT-NV-EMBED-IR-NEXT: "{{.*}}llvm-link" [[FIRSTLLVMLINKIN]].bc -o [[FIRSTLLVMLINKOUT:.*]].bc --suppress-warnings // CHK-CMDS-AOT-NV-EMBED-IR-NEXT: "{{.*}}llvm-link" -only-needed [[FIRSTLLVMLINKOUT]].bc {{.*}}.bc -o [[SECONDLLVMLINKOUT:.*]].bc --suppress-warnings // CHK-CMDS-AOT-NV-EMBED-IR-NEXT: "{{.*}}sycl-post-link"{{.*}} SYCL_POST_LINK_OPTIONS -o [[SYCLPOSTLINKOUT:.*]].table [[SECONDLLVMLINKOUT]].bc -// CHK-CMDS-AOT-NV-EMBED-IR-NEXT: offload-wrapper: input: {{.*}}.bc, output: [[WRAPPEROUT1:.*]] -// CHK-CMDS-AOT-NV-EMBED-IR-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT1:.*]] [[WRAPPEROUT1]] +// CHK-CMDS-AOT-NV-EMBED-IR-NEXT: offload-wrapper: input: {{.*}}.bc, output: [[WRAPPEROUT1:.*]].bc, +// CHK-CMDS-AOT-NV-EMBED-IR-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT1:.*]] [[WRAPPEROUT1]].bc // CHK-CMDS-AOT-NV-EMBED-IR-NEXT: "{{.*}}clang"{{.*}} -o [[CLANGOUT:.*]] --target=nvptx64-nvidia-cuda -march={{.*}} // CHK-CMDS-AOT-NV-EMBED-IR-NEXT: "{{.*}}ptxas"{{.*}} --output-file [[PTXASOUT:.*]] [[CLANGOUT]] // CHK-CMDS-AOT-NV-EMBED-IR-NEXT: "{{.*}}fatbinary"{{.*}} --create [[FATBINOUT:.*]] --image=profile={{.*}},file=[[CLANGOUT]] --image=profile={{.*}},file=[[PTXASOUT]] -// CHK-CMDS-AOT-NV-EMBED-IR-NEXT: offload-wrapper: input: [[FATBINOUT]], output: [[WRAPPEROUT:.*]] -// CHK-CMDS-AOT-NV-EMBED-IR-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT2:.*]] [[WRAPPEROUT]] +// CHK-CMDS-AOT-NV-EMBED-IR-NEXT: offload-wrapper: input: [[FATBINOUT]], output: [[WRAPPEROUT:.*]].bc, +// CHK-CMDS-AOT-NV-EMBED-IR-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT2:.*]] [[WRAPPEROUT]].bc // CHK-CMDS-AOT-NV-EMBED-IR-NEXT: "{{.*}}ld" -- HOST_LINKER_FLAGS -dynamic-linker HOST_DYN_LIB -o a.out [[LLCOUT1]] [[LLCOUT2]] HOST_LIB_PATH HOST_STAT_LIB {{.*}}.o /// Check for -sycl-embed-ir for standalone clang-linker-wrapper run for sycl (AMD) @@ -178,12 +183,12 @@ // CHK-CMDS-AOT-AMD-EMBED-IR: "{{.*}}spirv-to-ir-wrapper" {{.*}} -o [[FIRSTLLVMLINKIN:.*]].bc --llvm-spirv-opts --spirv-preserve-auxdata --spirv-target-env=SPV-IR --spirv-builtin-format=global // CHK-CMDS-AOT-AMD-EMBED-IR-NEXT: "{{.*}}llvm-link" [[FIRSTLLVMLINKIN]].bc -o [[FIRSTLLVMLINKOUT:.*]].bc --suppress-warnings // CHK-CMDS-AOT-AMD-EMBED-IR-NEXT: "{{.*}}sycl-post-link"{{.*}} SYCL_POST_LINK_OPTIONS -o [[SYCLPOSTLINKOUT:.*]].table [[FIRSTLLVMLINKOUT]].bc -// CHK-CMDS-AOT-AMD-EMBED-IR-NEXT: offload-wrapper: input: {{.*}}.bc, output: [[WRAPPEROUT1:.*]] -// CHK-CMDS-AOT-AMD-EMBED-IR-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT1:.*]] [[WRAPPEROUT1]] +// CHK-CMDS-AOT-AMD-EMBED-IR-NEXT: offload-wrapper: input: {{.*}}.bc, output: [[WRAPPEROUT1:.*]].bc, +// CHK-CMDS-AOT-AMD-EMBED-IR-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT1:.*]] [[WRAPPEROUT1]].bc // CHK-CMDS-AOT-AMD-EMBED-IR-NEXT: "{{.*}}clang"{{.*}} -o [[CLANGOUT:.*]] --target=amdgcn-amd-amdhsa -mcpu={{.*}} // CHK-CMDS-AOT-AMD-EMBED-IR-NEXT: "{{.*}}clang-offload-bundler"{{.*}} -input=[[CLANGOUT]] -output=[[BUNDLEROUT:.*]] -// CHK-CMDS-AOT-AMD-EMBED-IR-NEXT: offload-wrapper: input: [[BUNDLEROUT]], output: [[WRAPPEROUT2:.*]] -// CHK-CMDS-AOT-AMD-EMBED-IR-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT2:.*]] [[WRAPPEROUT2]] +// CHK-CMDS-AOT-AMD-EMBED-IR-NEXT: offload-wrapper: input: [[BUNDLEROUT]], output: [[WRAPPEROUT2:.*]].bc, +// CHK-CMDS-AOT-AMD-EMBED-IR-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT2:.*]] [[WRAPPEROUT2]].bc // CHK-CMDS-AOT-AMD-EMBED-IR-NEXT: "{{.*}}ld" -- HOST_LINKER_FLAGS -dynamic-linker HOST_DYN_LIB -o a.out [[LLCOUT1]] [[LLCOUT2]] HOST_LIB_PATH HOST_STAT_LIB {{.*}}.o // Error handling when --linker-path is not provided for clang-linker-wrapper diff --git a/clang/test/Driver/sycl-linker-wrapper-image.cpp b/clang/test/Driver/sycl-linker-wrapper-image.cpp index 57bab9cb7800e..88fd00fe734f5 100644 --- a/clang/test/Driver/sycl-linker-wrapper-image.cpp +++ b/clang/test/Driver/sycl-linker-wrapper-image.cpp @@ -3,7 +3,7 @@ // // Generate .o file as linker wrapper input. // -// RUN: %clang -cc1 -fsycl-is-device -disable-llvm-passes -triple=spir64-unknown-unknown %s -emit-llvm-bc -o %t.device.bc +// touch %t.device.bc // RUN: clang-offload-packager -o %t.fat --image=file=%t.device.bc,kind=sycl,triple=spir64-unknown-unknown // RUN: %clang -cc1 %s -triple=x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.fat // @@ -12,64 +12,43 @@ // RUN: touch %t.devicelib.cpp // RUN: %clang %t.devicelib.cpp -fsycl -fsycl-targets=spir64-unknown-unknown -c --offload-new-driver -o %t.devicelib.o // -// Run clang-linker-wrapper test +// Run clang-linker-wrapper test and check the output of SYCL Offload Wrapping. // -//// RUN: clang-linker-wrapper --print-wrapped-module --host-triple=x86_64-unknown-linux-gnu \ +// RUN: clang-linker-wrapper --print-wrapped-module --dry-run --host-triple=x86_64-unknown-linux-gnu \ // RUN: -sycl-device-libraries=%t.devicelib.o \ -// RUN: -sycl-post-link-options="-split=auto -symbols -properties" %t.o -o %t.out 2>&1 --linker-path="/usr/bin/ld" | FileCheck %s - -template -__attribute__((sycl_kernel)) void kernel(const Func &func) { - func(); -} - -extern "C" { -// symbols so that linker find them and doesn't fail. -void __sycl_register_lib(void *) {} -void __sycl_unregister_lib(void *) {} -} - -int main() { - kernel([](){}); -} - -//#endif - -// CHECK-DAG: %_pi_device_binary_property_struct = type { ptr, ptr, i32, i64 } -// CHECK-DAG: %_pi_device_binary_property_set_struct = type { ptr, ptr, ptr } -// CHECK-DAG: %struct.__tgt_offload_entry = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } -// CHECK-DAG: %__sycl.tgt_device_image = type { i16, i8, i8, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr } -// CHECK-DAG: %__sycl.tgt_bin_desc = type { i16, i16, ptr, ptr, ptr } - -// CHECK-DAG: @.sycl_offloading.target.0 = internal unnamed_addr constant [7 x i8] c"spir64\00" -// CHECK-DAG: @.sycl_offloading.opts.compile.0 = internal unnamed_addr constant [1 x i8] zeroinitializer -// CHECK-DAG: @.sycl_offloading.opts.link.0 = internal unnamed_addr constant [1 x i8] zeroinitializer -// CHECK-DAG: @prop = internal unnamed_addr constant [17 x i8] c"DeviceLibReqMask\00" -// CHECK-DAG: @__sycl_offload_prop_sets_arr = internal constant [1 x %_pi_device_binary_property_struct] [%_pi_device_binary_property_struct { ptr @prop, ptr null, i32 1, i64 0 }] -// CHECK-DAG: @SYCL_PropSetName = internal unnamed_addr constant [24 x i8] c"SYCL/devicelib req mask\00" -// CHECK-DAG: @prop.1 = internal unnamed_addr constant [8 x i8] c"aspects\00" -// CHECK-DAG: @prop_val = internal unnamed_addr constant [8 x i8] zeroinitializer -// CHECK-DAG: @__sycl_offload_prop_sets_arr.2 = internal constant [1 x %_pi_device_binary_property_struct] [%_pi_device_binary_property_struct { ptr @prop.1, ptr @prop_val, i32 2, i64 8 }] -// CHECK-DAG: @SYCL_PropSetName.3 = internal unnamed_addr constant [25 x i8] c"SYCL/device requirements\00" -// CHECK-DAG: @SYCL_PropSetName.4 = internal unnamed_addr constant [22 x i8] c"SYCL/kernel param opt\00" -// CHECK-DAG: @__sycl_offload_prop_sets_arr.5 = internal constant [3 x %_pi_device_binary_property_set_struct] [%_pi_device_binary_property_set_struct { ptr @SYCL_PropSetName, ptr @__sycl_offload_prop_sets_arr, ptr getelementptr ([1 x %_pi_device_binary_property_struct], ptr @__sycl_offload_prop_sets_arr, i64 0, i64 1) }, %_pi_device_binary_property_set_struct { ptr @SYCL_PropSetName.3, ptr @__sycl_offload_prop_sets_arr.2, ptr getelementptr ([1 x %_pi_device_binary_property_struct], ptr @__sycl_offload_prop_sets_arr.2, i64 0, i64 1) }, %_pi_device_binary_property_set_struct { ptr @SYCL_PropSetName.4, ptr null, ptr null }] -// CHECK-DAG: @.sycl_offloading.0.data = internal unnamed_addr constant [912 x i8] -// CHECK-DAG: @__sycl_offload_entry_name = internal unnamed_addr constant [25 x i8] c"_ZTSZ4mainE11fake_kernel\00" -// CHECK-DAG: @__sycl_offload_entries_arr = internal constant [1 x %struct.__tgt_offload_entry] [%struct.__tgt_offload_entry { i64 0, i16 1, i16 4, i32 0, ptr null, ptr @__sycl_offload_entry_name, i64 0, i64 0, ptr null }] -// CHECK-DAG: @.sycl_offloading.0.info = internal local_unnamed_addr constant [2 x i64] [i64 ptrtoint (ptr @.sycl_offloading.0.data to i64), i64 912], section ".tgtimg", align 16 -// CHECK-DAG: @llvm.used = appending global [1 x ptr] [ptr @.sycl_offloading.0.info], section "llvm.metadata" -// CHECK-DAG: @.sycl_offloading.device_images = internal unnamed_addr constant [1 x %__sycl.tgt_device_image] [%__sycl.tgt_device_image { i16 2, i8 4, i8 0, ptr @.sycl_offloading.target.0, ptr @.sycl_offloading.opts.compile.0, ptr @.sycl_offloading.opts.link.0, ptr null, ptr null, ptr @.sycl_offloading.0.data, ptr getelementptr ([912 x i8], ptr @.sycl_offloading.0.data, i64 0, i64 912), ptr @__sycl_offload_entries_arr, ptr getelementptr ([1 x %struct.__tgt_offload_entry], ptr @__sycl_offload_entries_arr, i64 0, i64 1), ptr @__sycl_offload_prop_sets_arr.5, ptr getelementptr ([3 x %_pi_device_binary_property_set_struct], ptr @__sycl_offload_prop_sets_arr.5, i64 0, i64 3) }] -// CHECK-DAG: @.sycl_offloading.descriptor = internal constant %__sycl.tgt_bin_desc { i16 1, i16 1, ptr @.sycl_offloading.device_images, ptr null, ptr null } -// CHECK-DAG: @llvm.global_ctors = {{.*}} { i32 1, ptr @sycl.descriptor_reg, ptr null }] -// CHECK-DAG: @llvm.global_dtors = {{.*}} { i32 1, ptr @sycl.descriptor_unreg, ptr null }] - -// CHECK: define internal void @sycl.descriptor_reg() section ".text.startup" { +// RUN: %t.o -o %t.out 2>&1 --linker-path="/usr/bin/ld" | FileCheck %s + +// CHECK: %_pi_device_binary_property_struct = type { ptr, ptr, i32, i64 } +// CHECK-NEXT: %_pi_device_binary_property_set_struct = type { ptr, ptr, ptr } +// CHECK-NEXT: %struct.__tgt_offload_entry = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } +// CHECK-NEXT: %__sycl.tgt_device_image = type { i16, i8, i8, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr } +// CHECK-NEXT: %__sycl.tgt_bin_desc = type { i16, i16, ptr, ptr, ptr } + +// CHECK: @.sycl_offloading.target.0 = internal unnamed_addr constant [7 x i8] c"spir64\00" +// CHECK-NEXT: @.sycl_offloading.opts.compile.0 = internal unnamed_addr constant [1 x i8] zeroinitializer +// CHECK-NEXT: @.sycl_offloading.opts.link.0 = internal unnamed_addr constant [1 x i8] zeroinitializer +// CHECK-NEXT: @prop = internal unnamed_addr constant [4 x i8] c"key\00" +// CHECK-NEXT: @__sycl_offload_prop_sets_arr = internal constant [1 x %_pi_device_binary_property_struct] [%_pi_device_binary_property_struct { ptr @prop, ptr null, i32 1, i64 0 }] +// CHECK-NEXT: @SYCL_PropSetName = internal unnamed_addr constant [25 x i8] c"SYCL/device requirements\00" +// CHECK-NEXT: @__sycl_offload_prop_sets_arr.1 = internal constant [1 x %_pi_device_binary_property_set_struct] [%_pi_device_binary_property_set_struct { ptr @SYCL_PropSetName, ptr @__sycl_offload_prop_sets_arr, ptr getelementptr ([1 x %_pi_device_binary_property_struct], ptr @__sycl_offload_prop_sets_arr, i64 0, i64 1) }] +// CHECK-NEXT: @.sycl_offloading.0.data = internal unnamed_addr constant [0 x i8] zeroinitializer, section "spir64" +// CHECK-NEXT: @__sycl_offload_entry_name = internal unnamed_addr constant [7 x i8] c"entry1\00" +// CHECK-NEXT: @__sycl_offload_entry_name.2 = internal unnamed_addr constant [7 x i8] c"entry2\00" +// CHECK-NEXT: @__sycl_offload_entries_arr = internal constant [2 x %struct.__tgt_offload_entry] [%struct.__tgt_offload_entry { i64 0, i16 1, i16 4, i32 0, ptr null, ptr @__sycl_offload_entry_name, i64 0, i64 0, ptr null }, %struct.__tgt_offload_entry { i64 0, i16 1, i16 4, i32 0, ptr null, ptr @__sycl_offload_entry_name.2, i64 0, i64 0, ptr null }] +// CHECK-NEXT: @.sycl_offloading.0.info = internal local_unnamed_addr constant [2 x i64] [i64 ptrtoint (ptr @.sycl_offloading.0.data to i64), i64 0], section ".tgtimg", align 16 +// CHECK-NEXT: @llvm.used = appending global [1 x ptr] [ptr @.sycl_offloading.0.info], section "llvm.metadata" +// CHECK-NEXT: @.sycl_offloading.device_images = internal unnamed_addr constant [1 x %__sycl.tgt_device_image] [%__sycl.tgt_device_image { i16 2, i8 4, i8 0, ptr @.sycl_offloading.target.0, ptr @.sycl_offloading.opts.compile.0, ptr @.sycl_offloading.opts.link.0, ptr null, ptr null, ptr @.sycl_offloading.0.data, ptr @.sycl_offloading.0.data, ptr @__sycl_offload_entries_arr, ptr getelementptr ([2 x %struct.__tgt_offload_entry], ptr @__sycl_offload_entries_arr, i64 0, i64 2), ptr @__sycl_offload_prop_sets_arr.1, ptr getelementptr ([1 x %_pi_device_binary_property_set_struct], ptr @__sycl_offload_prop_sets_arr.1, i64 0, i64 1) }] +// CHECK-NEXT: @.sycl_offloading.descriptor = internal constant %__sycl.tgt_bin_desc { i16 1, i16 1, ptr @.sycl_offloading.device_images, ptr null, ptr null } +// CHECK-NEXT: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 1, ptr @sycl.descriptor_reg, ptr null }] +// CHECK-NEXT: @llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 1, ptr @sycl.descriptor_unreg, ptr null }] + +// CHECK: define internal void @sycl.descriptor_reg() section ".text.startup" { // CHECK-NEXT: entry: // CHECK-NEXT: call void @__sycl_register_lib(ptr @.sycl_offloading.descriptor) // CHECK-NEXT: ret void // CHECK-NEXT: } -// CHECK: define internal void @sycl.descriptor_unreg() section ".text.startup" { +// CHECK: define internal void @sycl.descriptor_unreg() section ".text.startup" { // CHECK-NEXT: entry: // CHECK-NEXT: call void @__sycl_unregister_lib(ptr @.sycl_offloading.descriptor) // CHECK-NEXT: ret void diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp index ded1e3d6a4d5b..4734083baf91a 100644 --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -756,8 +756,12 @@ runSYCLPostLinkTool(ArrayRef InputFiles, const ArgList &Args) { if (!ImageFileOrErr) return ImageFileOrErr.takeError(); + // Arbitrary values are used for the testing of SYCL Offload Wrapping. + auto Properties = util::PropertySetRegistry(); + Properties.add(util::PropertySetRegistry::SYCL_DEVICE_REQUIREMENTS, "key", + util::PropertyValue(uint32_t(0))); std::vector Modules = {module_split::SplitModule( - *ImageFileOrErr, util::PropertySetRegistry(), "")}; + *ImageFileOrErr, std::move(Properties), "entry1\nentry2")}; return Modules; } @@ -1047,21 +1051,6 @@ wrapSYCLBinariesFromFile(std::vector &SplitModules, if (!OutputFileOrErr) return OutputFileOrErr.takeError(); - StringRef OutputFilePath = *OutputFileOrErr; - if (Verbose || DryRun) { - std::string InputFiles; - for (size_t I = 0, E = SplitModules.size(); I != E; ++I) { - InputFiles += SplitModules[I].ModuleFilePath; - if (I + 1 < E) - InputFiles += ','; - } - - errs() << formatv(" offload-wrapper: input: {0}, output: {1}\n", InputFiles, - OutputFilePath); - if (DryRun) - return OutputFilePath; - } - StringRef Target = Args.getLastArgValue(OPT_triple_EQ); if (Target.empty()) return createStringError( @@ -1092,7 +1081,9 @@ wrapSYCLBinariesFromFile(std::vector &SplitModules, CopyFrom, CopyTo, EC.value())); } - auto MBOrDesc = MemoryBuffer::getFile(SI.ModuleFilePath); + ErrorOr> MBOrDesc = + DryRun ? MemoryBuffer::getMemBuffer("") + : MemoryBuffer::getFile(SI.ModuleFilePath); if (!MBOrDesc) return createFileError(SI.ModuleFilePath, MBOrDesc.getError()); @@ -1119,10 +1110,21 @@ wrapSYCLBinariesFromFile(std::vector &SplitModules, offloading::SYCLWrappingOptions WrappingOptions; WrappingOptions.CompileOptions = CompileOptions; WrappingOptions.LinkOptions = LinkOptions; - if (Verbose) { - errs() << formatv(" offload-wrapper: compile-opts: {0}, link-opts: {1}\n", - CompileOptions, LinkOptions); + + StringRef OutputFilePath = *OutputFileOrErr; + if (Verbose || DryRun) { + std::string InputFiles; + for (size_t I = 0, E = SplitModules.size(); I != E; ++I) { + InputFiles += SplitModules[I].ModuleFilePath; + if (I + 1 < E) + InputFiles += ','; + } + + errs() << formatv(" offload-wrapper: input: {0}, output: {1}, " + "compile-opts: {2}, link-opts: {3}\n", + InputFiles, OutputFilePath, CompileOptions, LinkOptions); } + if (Error E = offloading::wrapSYCLBinaries(M, Images, WrappingOptions)) return E; From d290e513c3968006215b1af90dca3624178bf8f2 Mon Sep 17 00:00:00 2001 From: "Sabianin, Maksim" Date: Fri, 28 Mar 2025 07:37:58 -0700 Subject: [PATCH 2/3] addres CR --- clang/test/Driver/linker-wrapper-sycl.cpp | 5 - .../test/Driver/sycl-linker-wrapper-image.cpp | 132 ++++++++++++------ .../ClangLinkerWrapper.cpp | 6 +- 3 files changed, 94 insertions(+), 49 deletions(-) diff --git a/clang/test/Driver/linker-wrapper-sycl.cpp b/clang/test/Driver/linker-wrapper-sycl.cpp index 45f4c91dd6f5d..c908d8d193999 100644 --- a/clang/test/Driver/linker-wrapper-sycl.cpp +++ b/clang/test/Driver/linker-wrapper-sycl.cpp @@ -47,11 +47,6 @@ // RUN: clang-linker-wrapper -sycl-device-libraries=%t.devicelib.o -sycl-post-link-options="SYCL_POST_LINK_OPTIONS" -llvm-spirv-options="LLVM_SPIRV_OPTIONS" "--host-triple=x86_64-unknown-linux-gnu" "--triple=spir64" "--linker-path=/usr/bin/ld" -shared "--" HOST_LINKER_FLAGS "-dynamic-linker" HOST_DYN_LIB "-o" "a.out" HOST_LIB_PATH HOST_STAT_LIB %t.o --dry-run 2>&1 | FileCheck -check-prefix=CHK-SHARED %s // CHK-SHARED: "{{.*}}clang"{{.*}} -fPIC -// RUN: rm %T/linker_wrapper_dump || true -// RUN: clang-linker-wrapper -sycl-dump-device-code=%T/linker_wrapper_dump -sycl-device-libraries=%t.devicelib.o "--host-triple=x86_64-unknown-linux-gnu" "--triple=spir64" "--linker-path=/usr/bin/ld" -shared "--" HOST_LINKER_FLAGS "-dynamic-linker" HOST_DYN_LIB "-o" "a.out" HOST_LIB_PATH HOST_STAT_LIB %t.o --dry-run -// RUN: ls %T/linker_wrapper_dump | FileCheck -check-prefix=CHK-SYCL-DUMP-DEVICE %s -// CHK-SYCL-DUMP-DEVICE: {{.*}}.spv - /// Check for list of commands for standalone clang-linker-wrapper run for sycl (AOT for Intel GPU) // ------- // Generate .o file as linker wrapper input. diff --git a/clang/test/Driver/sycl-linker-wrapper-image.cpp b/clang/test/Driver/sycl-linker-wrapper-image.cpp index 88fd00fe734f5..a1ee01069eecd 100644 --- a/clang/test/Driver/sycl-linker-wrapper-image.cpp +++ b/clang/test/Driver/sycl-linker-wrapper-image.cpp @@ -3,7 +3,7 @@ // // Generate .o file as linker wrapper input. // -// touch %t.device.bc +// RUN: %clang -cc1 -fsycl-is-device -disable-llvm-passes -triple=spir64-unknown-unknown %s -emit-llvm-bc -o %t.device.bc // RUN: clang-offload-packager -o %t.fat --image=file=%t.device.bc,kind=sycl,triple=spir64-unknown-unknown // RUN: %clang -cc1 %s -triple=x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.fat // @@ -12,44 +12,98 @@ // RUN: touch %t.devicelib.cpp // RUN: %clang %t.devicelib.cpp -fsycl -fsycl-targets=spir64-unknown-unknown -c --offload-new-driver -o %t.devicelib.o // -// Run clang-linker-wrapper test and check the output of SYCL Offload Wrapping. +// Check SYCL Offload Wrapper in non-dry-mode since we need to cover every it's function. +// +// RUN: clang-linker-wrapper --print-wrapped-module --host-triple=x86_64-unknown-linux-gnu \ +// RUN: -sycl-device-libraries=%t.devicelib.o \ +// RUN: -sycl-post-link-options="-split=auto -symbols -properties" %t.o -o %t.out 2>&1 --linker-path="/usr/bin/ld" | FileCheck %s --check-prefix=CHECK-FULL + +template +__attribute__((sycl_kernel)) void kernel(const Func &func) { + func(); +} + +extern "C" { +// symbols so that linker find them and doesn't fail. +void __sycl_register_lib(void *) {} +void __sycl_unregister_lib(void *) {} +} + +int main() { + kernel([](){}); +} + +//#endif + +// CHECK-FULL: %_pi_device_binary_property_struct = type { ptr, ptr, i32, i64 } +// CHECK-FULL-NEXT: %_pi_device_binary_property_set_struct = type { ptr, ptr, ptr } +// CHECK-FULL-NEXT: %struct.__tgt_offload_entry = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } +// CHECK-FULL-NEXT: %__sycl.tgt_device_image = type { i16, i8, i8, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr } +// CHECK-FULL-NEXT: %__sycl.tgt_bin_desc = type { i16, i16, ptr, ptr, ptr } + +// CHECK-FULL: @.sycl_offloading.target.0 = internal unnamed_addr constant [7 x i8] c"spir64\00" +// CHECK-FULL-NEXT: @.sycl_offloading.opts.compile.0 = internal unnamed_addr constant [1 x i8] zeroinitializer +// CHECK-FULL-NEXT: @.sycl_offloading.opts.link.0 = internal unnamed_addr constant [1 x i8] zeroinitializer +// CHECK-FULL-NEXT: @prop = internal unnamed_addr constant [17 x i8] c"DeviceLibReqMask\00" +// CHECK-FULL-NEXT: @__sycl_offload_prop_sets_arr = internal constant [1 x %_pi_device_binary_property_struct] [%_pi_device_binary_property_struct { ptr @prop, ptr null, i32 1, i64 0 }] +// CHECK-FULL-NEXT: @SYCL_PropSetName = internal unnamed_addr constant [24 x i8] c"SYCL/devicelib req mask\00" +// CHECK-FULL-NEXT: @prop.1 = internal unnamed_addr constant [8 x i8] c"aspects\00" +// CHECK-FULL-NEXT: @prop_val = internal unnamed_addr constant [8 x i8] zeroinitializer +// CHECK-FULL-NEXT: @__sycl_offload_prop_sets_arr.2 = internal constant [1 x %_pi_device_binary_property_struct] [%_pi_device_binary_property_struct { ptr @prop.1, ptr @prop_val, i32 2, i64 8 }] +// CHECK-FULL-NEXT: @SYCL_PropSetName.3 = internal unnamed_addr constant [25 x i8] c"SYCL/device requirements\00" +// CHECK-FULL-NEXT: @SYCL_PropSetName.4 = internal unnamed_addr constant [22 x i8] c"SYCL/kernel param opt\00" +// CHECK-FULL-NEXT: @__sycl_offload_prop_sets_arr.5 = internal constant [3 x %_pi_device_binary_property_set_struct] [%_pi_device_binary_property_set_struct { ptr @SYCL_PropSetName, ptr @__sycl_offload_prop_sets_arr, ptr getelementptr ([1 x %_pi_device_binary_property_struct], ptr @__sycl_offload_prop_sets_arr, i64 0, i64 1) }, %_pi_device_binary_property_set_struct { ptr @SYCL_PropSetName.3, ptr @__sycl_offload_prop_sets_arr.2, ptr getelementptr ([1 x %_pi_device_binary_property_struct], ptr @__sycl_offload_prop_sets_arr.2, i64 0, i64 1) }, %_pi_device_binary_property_set_struct { ptr @SYCL_PropSetName.4, ptr null, ptr null }] +// CHECK-FULL-NEXT: @.sycl_offloading.0.data = internal unnamed_addr constant [912 x i8] +// CHECK-FULL-NEXT: @__sycl_offload_entry_name = internal unnamed_addr constant [25 x i8] c"_ZTSZ4mainE11fake_kernel\00" +// CHECK-FULL-NEXT: @__sycl_offload_entries_arr = internal constant [1 x %struct.__tgt_offload_entry] [%struct.__tgt_offload_entry { i64 0, i16 1, i16 4, i32 0, ptr null, ptr @__sycl_offload_entry_name, i64 0, i64 0, ptr null }] +// CHECK-FULL-NEXT: @.sycl_offloading.0.info = internal local_unnamed_addr constant [2 x i64] [i64 ptrtoint (ptr @.sycl_offloading.0.data to i64), i64 912], section ".tgtimg", align 16 +// CHECK-FULL-NEXT: @llvm.used = appending global [1 x ptr] [ptr @.sycl_offloading.0.info], section "llvm.metadata" +// CHECK-FULL-NEXT: @.sycl_offloading.device_images = internal unnamed_addr constant [1 x %__sycl.tgt_device_image] [%__sycl.tgt_device_image { i16 2, i8 4, i8 0, ptr @.sycl_offloading.target.0, ptr @.sycl_offloading.opts.compile.0, ptr @.sycl_offloading.opts.link.0, ptr null, ptr null, ptr @.sycl_offloading.0.data, ptr getelementptr ([912 x i8], ptr @.sycl_offloading.0.data, i64 0, i64 912), ptr @__sycl_offload_entries_arr, ptr getelementptr ([1 x %struct.__tgt_offload_entry], ptr @__sycl_offload_entries_arr, i64 0, i64 1), ptr @__sycl_offload_prop_sets_arr.5, ptr getelementptr ([3 x %_pi_device_binary_property_set_struct], ptr @__sycl_offload_prop_sets_arr.5, i64 0, i64 3) }] +// CHECK-FULL-NEXT: @.sycl_offloading.descriptor = internal constant %__sycl.tgt_bin_desc { i16 1, i16 1, ptr @.sycl_offloading.device_images, ptr null, ptr null } +// CHECK-FULL-NEXT: @llvm.global_ctors = {{.*}} { i32 1, ptr @sycl.descriptor_reg, ptr null }] +// CHECK-FULL-NEXT: @llvm.global_dtors = {{.*}} { i32 1, ptr @sycl.descriptor_unreg, ptr null }] + +// CHECK-FULL: define internal void @sycl.descriptor_reg() section ".text.startup" { +// CHECK-FULL-NEXT: entry: +// CHECK-FULL-NEXT: call void @__sycl_register_lib(ptr @.sycl_offloading.descriptor) +// CHECK-FULL-NEXT: ret void +// CHECK-FULL-NEXT: } + +// CHECK-FULL: define internal void @sycl.descriptor_unreg() section ".text.startup" { +// CHECK-FULL-NEXT: entry: +// CHECK-FULL-NEXT: call void @__sycl_unregister_lib(ptr @.sycl_offloading.descriptor) +// CHECK-FULL-NEXT: ret void +// CHECK-FULL-NEXT: } + + +// Run Check SYCL Offload Wrapping in dry-run mode. // // RUN: clang-linker-wrapper --print-wrapped-module --dry-run --host-triple=x86_64-unknown-linux-gnu \ // RUN: -sycl-device-libraries=%t.devicelib.o \ -// RUN: %t.o -o %t.out 2>&1 --linker-path="/usr/bin/ld" | FileCheck %s - -// CHECK: %_pi_device_binary_property_struct = type { ptr, ptr, i32, i64 } -// CHECK-NEXT: %_pi_device_binary_property_set_struct = type { ptr, ptr, ptr } -// CHECK-NEXT: %struct.__tgt_offload_entry = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } -// CHECK-NEXT: %__sycl.tgt_device_image = type { i16, i8, i8, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr } -// CHECK-NEXT: %__sycl.tgt_bin_desc = type { i16, i16, ptr, ptr, ptr } - -// CHECK: @.sycl_offloading.target.0 = internal unnamed_addr constant [7 x i8] c"spir64\00" -// CHECK-NEXT: @.sycl_offloading.opts.compile.0 = internal unnamed_addr constant [1 x i8] zeroinitializer -// CHECK-NEXT: @.sycl_offloading.opts.link.0 = internal unnamed_addr constant [1 x i8] zeroinitializer -// CHECK-NEXT: @prop = internal unnamed_addr constant [4 x i8] c"key\00" -// CHECK-NEXT: @__sycl_offload_prop_sets_arr = internal constant [1 x %_pi_device_binary_property_struct] [%_pi_device_binary_property_struct { ptr @prop, ptr null, i32 1, i64 0 }] -// CHECK-NEXT: @SYCL_PropSetName = internal unnamed_addr constant [25 x i8] c"SYCL/device requirements\00" -// CHECK-NEXT: @__sycl_offload_prop_sets_arr.1 = internal constant [1 x %_pi_device_binary_property_set_struct] [%_pi_device_binary_property_set_struct { ptr @SYCL_PropSetName, ptr @__sycl_offload_prop_sets_arr, ptr getelementptr ([1 x %_pi_device_binary_property_struct], ptr @__sycl_offload_prop_sets_arr, i64 0, i64 1) }] -// CHECK-NEXT: @.sycl_offloading.0.data = internal unnamed_addr constant [0 x i8] zeroinitializer, section "spir64" -// CHECK-NEXT: @__sycl_offload_entry_name = internal unnamed_addr constant [7 x i8] c"entry1\00" -// CHECK-NEXT: @__sycl_offload_entry_name.2 = internal unnamed_addr constant [7 x i8] c"entry2\00" -// CHECK-NEXT: @__sycl_offload_entries_arr = internal constant [2 x %struct.__tgt_offload_entry] [%struct.__tgt_offload_entry { i64 0, i16 1, i16 4, i32 0, ptr null, ptr @__sycl_offload_entry_name, i64 0, i64 0, ptr null }, %struct.__tgt_offload_entry { i64 0, i16 1, i16 4, i32 0, ptr null, ptr @__sycl_offload_entry_name.2, i64 0, i64 0, ptr null }] -// CHECK-NEXT: @.sycl_offloading.0.info = internal local_unnamed_addr constant [2 x i64] [i64 ptrtoint (ptr @.sycl_offloading.0.data to i64), i64 0], section ".tgtimg", align 16 -// CHECK-NEXT: @llvm.used = appending global [1 x ptr] [ptr @.sycl_offloading.0.info], section "llvm.metadata" -// CHECK-NEXT: @.sycl_offloading.device_images = internal unnamed_addr constant [1 x %__sycl.tgt_device_image] [%__sycl.tgt_device_image { i16 2, i8 4, i8 0, ptr @.sycl_offloading.target.0, ptr @.sycl_offloading.opts.compile.0, ptr @.sycl_offloading.opts.link.0, ptr null, ptr null, ptr @.sycl_offloading.0.data, ptr @.sycl_offloading.0.data, ptr @__sycl_offload_entries_arr, ptr getelementptr ([2 x %struct.__tgt_offload_entry], ptr @__sycl_offload_entries_arr, i64 0, i64 2), ptr @__sycl_offload_prop_sets_arr.1, ptr getelementptr ([1 x %_pi_device_binary_property_set_struct], ptr @__sycl_offload_prop_sets_arr.1, i64 0, i64 1) }] -// CHECK-NEXT: @.sycl_offloading.descriptor = internal constant %__sycl.tgt_bin_desc { i16 1, i16 1, ptr @.sycl_offloading.device_images, ptr null, ptr null } -// CHECK-NEXT: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 1, ptr @sycl.descriptor_reg, ptr null }] -// CHECK-NEXT: @llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 1, ptr @sycl.descriptor_unreg, ptr null }] - -// CHECK: define internal void @sycl.descriptor_reg() section ".text.startup" { -// CHECK-NEXT: entry: -// CHECK-NEXT: call void @__sycl_register_lib(ptr @.sycl_offloading.descriptor) -// CHECK-NEXT: ret void -// CHECK-NEXT: } - -// CHECK: define internal void @sycl.descriptor_unreg() section ".text.startup" { -// CHECK-NEXT: entry: -// CHECK-NEXT: call void @__sycl_unregister_lib(ptr @.sycl_offloading.descriptor) -// CHECK-NEXT: ret void -// CHECK-NEXT: } +// RUN: %t.o -o %t.out 2>&1 --linker-path="/usr/bin/ld" | FileCheck %s --check-prefix=CHECK-DRY + +// CHECK-DRY: %__sycl.tgt_device_image = type { i16, i8, i8, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr } +// CHECK-DRY-NEXT: %__sycl.tgt_bin_desc = type { i16, i16, ptr, ptr, ptr } + +// CHECK-DRY: @.sycl_offloading.target.0 = internal unnamed_addr constant [7 x i8] c"spir64\00" +// CHECK-DRY-NEXT: @.sycl_offloading.opts.compile.0 = internal unnamed_addr constant [1 x i8] zeroinitializer +// CHECK-DRY-NEXT: @.sycl_offloading.opts.link.0 = internal unnamed_addr constant [1 x i8] zeroinitializer +// CHECK-DRY-NEXT: @.sycl_offloading.0.data = internal unnamed_addr constant [0 x i8] zeroinitializer, section "spir64" +// CHECK-DRY-NEXT: @.sycl_offloading.0.info = internal local_unnamed_addr constant [2 x i64] [i64 ptrtoint (ptr @.sycl_offloading.0.data to i64), i64 0], section ".tgtimg", align 16 +// CHECK-DRY-NEXT: @llvm.used = appending global [1 x ptr] [ptr @.sycl_offloading.0.info], section "llvm.metadata" +// CHECK-DRY-NEXT: @.sycl_offloading.device_images = internal unnamed_addr constant [1 x %__sycl.tgt_device_image] [%__sycl.tgt_device_image { i16 2, i8 4, i8 0, ptr @.sycl_offloading.target.0, ptr @.sycl_offloading.opts.compile.0, ptr @.sycl_offloading.opts.link.0, ptr null, ptr null, ptr @.sycl_offloading.0.data, ptr @.sycl_offloading.0.data, ptr null, ptr null, ptr null, ptr null }] +// CHECK-DRY-NEXT: @.sycl_offloading.descriptor = internal constant %__sycl.tgt_bin_desc { i16 1, i16 1, ptr @.sycl_offloading.device_images, ptr null, ptr null } +// CHECK-DRY-NEXT: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 1, ptr @sycl.descriptor_reg, ptr null }] +// CHECK-DRY-NEXT: @llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 1, ptr @sycl.descriptor_unreg, ptr null }] + +// CHECK-DRY: define internal void @sycl.descriptor_reg() section ".text.startup" { +// CHECK-DRY-NEXT: entry: +// CHECK-DRY-NEXT: call void @__sycl_register_lib(ptr @.sycl_offloading.descriptor) +// CHECK-DRY-NEXT: ret void +// CHECK-DRY-NEXT: } + +// CHECK-DRY: define internal void @sycl.descriptor_unreg() section ".text.startup" { +// CHECK-DRY-NEXT: entry: +// CHECK-DRY-NEXT: call void @__sycl_unregister_lib(ptr @.sycl_offloading.descriptor) +// CHECK-DRY-NEXT: ret void +// CHECK-DRY-NEXT: } \ No newline at end of file diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp index 4734083baf91a..178e0b3472d03 100644 --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -756,12 +756,8 @@ runSYCLPostLinkTool(ArrayRef InputFiles, const ArgList &Args) { if (!ImageFileOrErr) return ImageFileOrErr.takeError(); - // Arbitrary values are used for the testing of SYCL Offload Wrapping. - auto Properties = util::PropertySetRegistry(); - Properties.add(util::PropertySetRegistry::SYCL_DEVICE_REQUIREMENTS, "key", - util::PropertyValue(uint32_t(0))); std::vector Modules = {module_split::SplitModule( - *ImageFileOrErr, std::move(Properties), "entry1\nentry2")}; + *ImageFileOrErr, util::PropertySetRegistry(), "")}; return Modules; } From ef1275c37f765562aae397b2089ae09f37c4c3ef Mon Sep 17 00:00:00 2001 From: "Sabianin, Maksim" Date: Tue, 20 May 2025 06:31:30 -0700 Subject: [PATCH 3/3] Remove printing of offloa-wrapper from clang-linker-wrapper. --- clang/test/Driver/linker-wrapper-sycl.cpp | 30 +++++++------------ .../test/Driver/sycl-linker-wrapper-image.cpp | 2 +- .../ClangLinkerWrapper.cpp | 16 +--------- 3 files changed, 12 insertions(+), 36 deletions(-) diff --git a/clang/test/Driver/linker-wrapper-sycl.cpp b/clang/test/Driver/linker-wrapper-sycl.cpp index c908d8d193999..1d5bd0dd60998 100644 --- a/clang/test/Driver/linker-wrapper-sycl.cpp +++ b/clang/test/Driver/linker-wrapper-sycl.cpp @@ -19,8 +19,7 @@ // CHK-CMDS-NEXT: "{{.*}}llvm-link" -only-needed [[FIRSTLLVMLINKOUT]].bc {{.*}}.bc -o [[SECONDLLVMLINKOUT:.*]].bc --suppress-warnings // CHK-CMDS-NEXT: "{{.*}}sycl-post-link"{{.*}} SYCL_POST_LINK_OPTIONS -o [[SYCLPOSTLINKOUT:.*]].table [[SECONDLLVMLINKOUT]].bc // CHK-CMDS-NEXT: "{{.*}}llvm-spirv"{{.*}} LLVM_SPIRV_OPTIONS -o {{.*}} -// CHK-CMDS-NEXT: offload-wrapper: input: {{.*}}, output: [[WRAPPEROUT:.*]].bc, compile-opts: , link-opts: -// CHK-CMDS-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT:.*]] [[WRAPPEROUT]].bc +// CHK-CMDS-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT:.*]] {{.*}}.bc // CHK-CMDS-NEXT: "{{.*}}/ld" -- HOST_LINKER_FLAGS -dynamic-linker HOST_DYN_LIB -o a.out [[LLCOUT]] HOST_LIB_PATH HOST_STAT_LIB {{.*}}.o // Check sycl-module-split-mode command line option. @@ -32,8 +31,7 @@ // CHK-SPLIT-CMDS-NEXT: sycl-module-split: input: [[SECONDLLVMLINKOUT]].bc, output: [[SYCLMODULESPLITOUT:.*]].bc // CHK-SPLIT-CMDS-NEXT: "{{.*}}llvm-spirv"{{.*}} LLVM_SPIRV_OPTIONS -o [[SPIRVOUT:.*]].spv [[SYCLMODULESPLITOUT]].bc // LLVM-SPIRV is not called in dry-run -// CHK-SPLIT-CMDS-NEXT: offload-wrapper: input: [[SPIRVOUT]].spv, output: [[WRAPPEROUT:.*]].bc, compile-opts: , link-opts: -// CHK-SPLIT-CMDS-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT:.*]] [[WRAPPEROUT]].bc +// CHK-SPLIT-CMDS-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT:.*]] {{.*}}.bc // CHK-SPLIT-CMDS-NEXT: "{{.*}}/ld" -- HOST_LINKER_FLAGS -dynamic-linker HOST_DYN_LIB -o a.out [[LLCOUT]] HOST_LIB_PATH HOST_STAT_LIB {{.*}}.o // Check errors with -[no-]use-sycl-post-link-tool. @@ -68,8 +66,7 @@ // CHK-CMDS-AOT-GEN-NEXT: "{{.*}}sycl-post-link"{{.*}} SYCL_POST_LINK_OPTIONS -o [[SYCLPOSTLINKOUT:.*]].table [[SECONDLLVMLINKOUT]].bc // CHK-CMDS-AOT-GEN-NEXT: "{{.*}}llvm-spirv"{{.*}} LLVM_SPIRV_OPTIONS -o {{.*}} // CHK-CMDS-AOT-GEN-NEXT: "{{.*}}ocloc"{{.*}} -output_no_suffix -spirv_input -device pvc {{.*}} -output {{.*}} -file {{.*}} -// CHK-CMDS-AOT-GEN-NEXT: offload-wrapper: input: {{.*}}, output: [[WRAPPEROUT:.*]].bc -// CHK-CMDS-AOT-GEN-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT:.*]].o [[WRAPPEROUT]].bc +// CHK-CMDS-AOT-GEN-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT:.*]].o {{.*}}.bc // CHK-CMDS-AOT-GEN-NEXT: "{{.*}}/ld" -- HOST_LINKER_FLAGS -dynamic-linker HOST_DYN_LIB -o a.out [[LLCOUT]].o HOST_LIB_PATH HOST_STAT_LIB {{.*}}.o /// Check for list of commands for standalone clang-linker-wrapper run for sycl (AOT for Intel CPU) @@ -92,8 +89,7 @@ // CHK-CMDS-AOT-CPU-NEXT: "{{.*}}sycl-post-link"{{.*}} SYCL_POST_LINK_OPTIONS -o [[SYCLPOSTLINKOUT:.*]].table [[SECONDLLVMLINKOUT]].bc // CHK-CMDS-AOT-CPU-NEXT: "{{.*}}llvm-spirv"{{.*}} LLVM_SPIRV_OPTIONS -o {{.*}} // CHK-CMDS-AOT-CPU-NEXT: "{{.*}}opencl-aot"{{.*}} --device=cpu -o {{.*}} -// CHK-CMDS-AOT-CPU-NEXT: offload-wrapper: input: {{.*}}, output: [[WRAPPEROUT:.*]].bc -// CHK-CMDS-AOT-CPU-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT:.*]].o [[WRAPPEROUT]].bc +// CHK-CMDS-AOT-CPU-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT:.*]].o {{.*}}.bc // CHK-CMDS-AOT-CPU-NEXT: "{{.*}}ld" -- HOST_LINKER_FLAGS -dynamic-linker HOST_DYN_LIB -o a.out [[LLCOUT]].o HOST_LIB_PATH HOST_STAT_LIB {{.*}}.o /// Check for list of commands for standalone clang-linker-wrapper run for sycl (AOT for NVPTX) @@ -117,8 +113,7 @@ // CHK-CMDS-AOT-NV-NEXT: "{{.*}}clang"{{.*}} -o [[CLANGOUT:.*]] --target=nvptx64-nvidia-cuda -march={{.*}} // CHK-CMDS-AOT-NV-NEXT: "{{.*}}ptxas"{{.*}} --output-file [[PTXASOUT:.*]] [[CLANGOUT]] // CHK-CMDS-AOT-NV-NEXT: "{{.*}}fatbinary"{{.*}} --create [[FATBINOUT:.*]] --image=profile={{.*}},file=[[CLANGOUT]] --image=profile={{.*}},file=[[PTXASOUT]] -// CHK-CMDS-AOT-NV-NEXT: offload-wrapper: input: [[FATBINOUT]], output: [[WRAPPEROUT:.*]].bc, -// CHK-CMDS-AOT-NV-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT:.*]] [[WRAPPEROUT]].bc +// CHK-CMDS-AOT-NV-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT:.*]] {{.*}}.bc // CHK-CMDS-AOT-NV-NEXT: "{{.*}}ld" -- HOST_LINKER_FLAGS -dynamic-linker HOST_DYN_LIB -o a.out [[LLCOUT]] HOST_LIB_PATH HOST_STAT_LIB {{.*}}.o /// Check for list of commands for standalone clang-linker-wrapper run for sycl (AOT for AMD) @@ -135,8 +130,7 @@ // CHK-CMDS-AOT-AMD-NEXT: "{{.*}}sycl-post-link"{{.*}} SYCL_POST_LINK_OPTIONS -o [[SYCLPOSTLINKOUT:.*]].table [[FIRSTLLVMLINKOUT]].bc // CHK-CMDS-AOT-AMD-NEXT: "{{.*}}clang"{{.*}} -o [[CLANGOUT:.*]] --target=amdgcn-amd-amdhsa -mcpu={{.*}} // CHK-CMDS-AOT-AMD-NEXT: "{{.*}}clang-offload-bundler"{{.*}} -targets=host-x86_64-unknown-linux-gnu,hip-amdgcn-amd-amdhsa--gfx803 -input=/dev/null -input=[[CLANGOUT]] -output=[[BUNDLEROUT:.*]] -// CHK-CMDS-AOT-AMD-NEXT: offload-wrapper: input: [[BUNDLEROUT]], output: [[WRAPPEROUT:.*]].bc, -// CHK-CMDS-AOT-AMD-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT:.*]] [[WRAPPEROUT]].bc +// CHK-CMDS-AOT-AMD-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT:.*]] {{.*}}.bc // CHK-CMDS-AOT-AMD-NEXT: "{{.*}}ld" -- HOST_LINKER_FLAGS -dynamic-linker HOST_DYN_LIB -o a.out [[LLCOUT]] HOST_LIB_PATH HOST_STAT_LIB {{.*}}.o /// Check for -sycl-embed-ir for standalone clang-linker-wrapper run for sycl (NVPTX) @@ -157,13 +151,11 @@ // CHK-CMDS-AOT-NV-EMBED-IR-NEXT: "{{.*}}llvm-link" [[FIRSTLLVMLINKIN]].bc -o [[FIRSTLLVMLINKOUT:.*]].bc --suppress-warnings // CHK-CMDS-AOT-NV-EMBED-IR-NEXT: "{{.*}}llvm-link" -only-needed [[FIRSTLLVMLINKOUT]].bc {{.*}}.bc -o [[SECONDLLVMLINKOUT:.*]].bc --suppress-warnings // CHK-CMDS-AOT-NV-EMBED-IR-NEXT: "{{.*}}sycl-post-link"{{.*}} SYCL_POST_LINK_OPTIONS -o [[SYCLPOSTLINKOUT:.*]].table [[SECONDLLVMLINKOUT]].bc -// CHK-CMDS-AOT-NV-EMBED-IR-NEXT: offload-wrapper: input: {{.*}}.bc, output: [[WRAPPEROUT1:.*]].bc, -// CHK-CMDS-AOT-NV-EMBED-IR-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT1:.*]] [[WRAPPEROUT1]].bc +// CHK-CMDS-AOT-NV-EMBED-IR-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT1:.*]] {{.*}}.bc // CHK-CMDS-AOT-NV-EMBED-IR-NEXT: "{{.*}}clang"{{.*}} -o [[CLANGOUT:.*]] --target=nvptx64-nvidia-cuda -march={{.*}} // CHK-CMDS-AOT-NV-EMBED-IR-NEXT: "{{.*}}ptxas"{{.*}} --output-file [[PTXASOUT:.*]] [[CLANGOUT]] // CHK-CMDS-AOT-NV-EMBED-IR-NEXT: "{{.*}}fatbinary"{{.*}} --create [[FATBINOUT:.*]] --image=profile={{.*}},file=[[CLANGOUT]] --image=profile={{.*}},file=[[PTXASOUT]] -// CHK-CMDS-AOT-NV-EMBED-IR-NEXT: offload-wrapper: input: [[FATBINOUT]], output: [[WRAPPEROUT:.*]].bc, -// CHK-CMDS-AOT-NV-EMBED-IR-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT2:.*]] [[WRAPPEROUT]].bc +// CHK-CMDS-AOT-NV-EMBED-IR-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT2:.*]] {{.*}}.bc // CHK-CMDS-AOT-NV-EMBED-IR-NEXT: "{{.*}}ld" -- HOST_LINKER_FLAGS -dynamic-linker HOST_DYN_LIB -o a.out [[LLCOUT1]] [[LLCOUT2]] HOST_LIB_PATH HOST_STAT_LIB {{.*}}.o /// Check for -sycl-embed-ir for standalone clang-linker-wrapper run for sycl (AMD) @@ -178,12 +170,10 @@ // CHK-CMDS-AOT-AMD-EMBED-IR: "{{.*}}spirv-to-ir-wrapper" {{.*}} -o [[FIRSTLLVMLINKIN:.*]].bc --llvm-spirv-opts --spirv-preserve-auxdata --spirv-target-env=SPV-IR --spirv-builtin-format=global // CHK-CMDS-AOT-AMD-EMBED-IR-NEXT: "{{.*}}llvm-link" [[FIRSTLLVMLINKIN]].bc -o [[FIRSTLLVMLINKOUT:.*]].bc --suppress-warnings // CHK-CMDS-AOT-AMD-EMBED-IR-NEXT: "{{.*}}sycl-post-link"{{.*}} SYCL_POST_LINK_OPTIONS -o [[SYCLPOSTLINKOUT:.*]].table [[FIRSTLLVMLINKOUT]].bc -// CHK-CMDS-AOT-AMD-EMBED-IR-NEXT: offload-wrapper: input: {{.*}}.bc, output: [[WRAPPEROUT1:.*]].bc, -// CHK-CMDS-AOT-AMD-EMBED-IR-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT1:.*]] [[WRAPPEROUT1]].bc +// CHK-CMDS-AOT-AMD-EMBED-IR-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT1:.*]] {{.*}}.bc // CHK-CMDS-AOT-AMD-EMBED-IR-NEXT: "{{.*}}clang"{{.*}} -o [[CLANGOUT:.*]] --target=amdgcn-amd-amdhsa -mcpu={{.*}} // CHK-CMDS-AOT-AMD-EMBED-IR-NEXT: "{{.*}}clang-offload-bundler"{{.*}} -input=[[CLANGOUT]] -output=[[BUNDLEROUT:.*]] -// CHK-CMDS-AOT-AMD-EMBED-IR-NEXT: offload-wrapper: input: [[BUNDLEROUT]], output: [[WRAPPEROUT2:.*]].bc, -// CHK-CMDS-AOT-AMD-EMBED-IR-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT2:.*]] [[WRAPPEROUT2]].bc +// CHK-CMDS-AOT-AMD-EMBED-IR-NEXT: "{{.*}}clang"{{.*}} -c -o [[LLCOUT2:.*]] {{.*}}.bc // CHK-CMDS-AOT-AMD-EMBED-IR-NEXT: "{{.*}}ld" -- HOST_LINKER_FLAGS -dynamic-linker HOST_DYN_LIB -o a.out [[LLCOUT1]] [[LLCOUT2]] HOST_LIB_PATH HOST_STAT_LIB {{.*}}.o // Error handling when --linker-path is not provided for clang-linker-wrapper diff --git a/clang/test/Driver/sycl-linker-wrapper-image.cpp b/clang/test/Driver/sycl-linker-wrapper-image.cpp index 9f5bc0e286042..d9dd327d75fc4 100644 --- a/clang/test/Driver/sycl-linker-wrapper-image.cpp +++ b/clang/test/Driver/sycl-linker-wrapper-image.cpp @@ -106,4 +106,4 @@ int main() { // CHECK-DRY-NEXT: entry: // CHECK-DRY-NEXT: call void @__sycl_unregister_lib(ptr @.sycl_offloading.descriptor) // CHECK-DRY-NEXT: ret void -// CHECK-DRY-NEXT: } \ No newline at end of file +// CHECK-DRY-NEXT: } diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp index 268253cf620f9..555a05a995588 100644 --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -1108,21 +1108,6 @@ wrapSYCLBinariesFromFile(std::vector &SplitModules, offloading::SYCLWrappingOptions WrappingOptions; WrappingOptions.CompileOptions = CompileOptions; WrappingOptions.LinkOptions = LinkOptions; - - StringRef OutputFilePath = *OutputFileOrErr; - if (Verbose || DryRun) { - std::string InputFiles; - for (size_t I = 0, E = SplitModules.size(); I != E; ++I) { - InputFiles += SplitModules[I].ModuleFilePath; - if (I + 1 < E) - InputFiles += ','; - } - - errs() << formatv(" offload-wrapper: input: {0}, output: {1}, " - "compile-opts: {2}, link-opts: {3}\n", - InputFiles, OutputFilePath, CompileOptions, LinkOptions); - } - if (Error E = offloading::wrapSYCLBinaries(M, Images, WrappingOptions)) return E; @@ -1132,6 +1117,7 @@ wrapSYCLBinariesFromFile(std::vector &SplitModules, // TODO: Once "clang tool->runCompile" migration is finished we need to remove // this scope and use community flow. int FD = -1; + StringRef OutputFilePath = *OutputFileOrErr; if (std::error_code EC = sys::fs::openFileForWrite(OutputFilePath, FD)) return errorCodeToError(EC);