https://github.com/schittir updated https://github.com/llvm/llvm-project/pull/215620
>From e465e699bacb7e0be98902a68a7c53c04270f32f Mon Sep 17 00:00:00 2001 From: Sindhu Chittireddy <[email protected]> Date: Tue, 11 Aug 2026 10:05:44 -0700 Subject: [PATCH 1/2] [clang] Diagnose host/device pointer width mismatches in offload compilations SPIR, physical SPIR-V, and NVPTX device targets take their pointer related types from the host target, so a host whose pointer width differs from the device's leaves size_t, ptrdiff_t, and intptr_t inconsistent with the device data layout. Such pairings were previously accepted and silently miscompiled. This patch diagnoses these invalid combinations by calling the diagnostic at: 1. Driver::CreateOffloadingDeviceToolChains(), covering --offload=, --offload-targets=, and -fsycl. 2. TargetInfo::CreateTargetInfo(), covering -cc1 -triple X -aux-triple Y and anything else that bypasses the driver. This is the follow-up to #208196, as discussed during review. --- clang/docs/ReleaseNotes.md | 6 +++ .../clang/Basic/DiagnosticCommonKinds.td | 3 ++ clang/lib/Basic/Targets.cpp | 24 +++++++++ clang/lib/Basic/Targets/SPIR.h | 50 +++++++++++-------- clang/lib/Driver/Driver.cpp | 16 ++++++ clang/test/CodeGenCUDA/anon-ns.cu | 4 +- clang/test/CodeGenCUDA/long-double.cu | 2 +- .../CodeGenCUDASPIRV/copy-aggregate-byval.cu | 4 +- .../test/CodeGenCUDASPIRV/kernel-argument.cu | 4 +- .../CodeGenSYCL/kernel-caller-entry-point.cpp | 9 ---- clang/test/Driver/cuda-device-triple.cu | 2 +- clang/test/Frontend/sycl-aux-triple.cpp | 4 +- clang/test/SemaCUDA/allow-int128.cu | 2 +- .../SemaCUDA/cuda-inherits-calling-conv.cu | 2 +- ...v-implicit-alloc-function-calling-conv.hip | 2 - 15 files changed, 91 insertions(+), 43 deletions(-) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 2f13ec59483ee..d1651cdb92581 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -51,6 +51,12 @@ The previous behavior can be restored with `-Wno-error=unicode-whitespace`. Clang will stop accepting non-ascii whitespaces as token separators in a future version of Clang. +- Offload compilations that pair a SPIR, physical SPIR-V, or NVPTX device target + with a host of a different pointer width are now rejected, for example + `--offload=spirv32` with an `x86_64` host. These targets take `size_t`, + `ptrdiff_t`, and `intptr_t` from the host, so a mismatch disagreed with the + device data layout. Select a device target whose width matches the host's. + ### C++ Specific Potentially Breaking Changes ### ABI Changes in This Version diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index 192fdf9299eb4..ece27b02f840e 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -338,6 +338,9 @@ def err_target_unknown_cpu : Error<"unknown target CPU '%0'">; def note_valid_options : Note<"valid target CPU values are: %0">; def err_target_unsupported_cpu_for_micromips : Error< "micromips is not supported for target CPU '%0'">; +def err_target_unsupported_host_device_pointer_width : Error< + "device target '%0' with %1-bit pointers is incompatible with host target " + "'%2' with %3-bit pointers">; def err_target_unknown_abi : Error<"unknown target ABI '%0'">; def err_target_unsupported_abi : Error<"ABI '%0' is not supported on CPU '%1'">; def err_target_unsupported_abi_for_triple : Error< diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index 8c01cfca8ccb4..a939eb9b94470 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -835,6 +835,15 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple, } // namespace clang using namespace clang::targets; + +/// Returns true if Triple names a target that takes its pointer related types +/// from a host target. Logical SPIR-V is excluded; it uses fixed values for +/// those types regardless of the host. +static bool adaptsToHostTarget(const llvm::Triple &Triple) { + return (Triple.isSPIROrSPIRV() && Triple.getArch() != llvm::Triple::spirv) || + Triple.isNVPTX(); +} + /// CreateTargetInfo - Return the target info object for the specified target /// options. TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, @@ -843,6 +852,21 @@ TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, llvm::Triple Triple(llvm::Triple::normalize(Opts->Triple)); + // Host and device pointer related type widths must match. Reject a mismatch + // before constructing the device target, which asserts on this. + if (adaptsToHostTarget(Triple) && !Opts->HostTriple.empty()) { + llvm::Triple HostTriple(llvm::Triple::normalize(Opts->HostTriple)); + if (!adaptsToHostTarget(HostTriple) && + HostTriple.getArch() != llvm::Triple::UnknownArch && + Triple.getArchPointerBitWidth() != + HostTriple.getArchPointerBitWidth()) { + Diags.Report(diag::err_target_unsupported_host_device_pointer_width) + << Triple.str() << Triple.getArchPointerBitWidth() << HostTriple.str() + << HostTriple.getArchPointerBitWidth(); + return nullptr; + } + } + // Construct the target std::unique_ptr<TargetInfo> Target = AllocateTarget(Triple, *Opts); if (!Target) { diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h index 20d8efdc83234..17f90e80dc5fd 100644 --- a/clang/lib/Basic/Targets/SPIR.h +++ b/clang/lib/Basic/Targets/SPIR.h @@ -254,16 +254,18 @@ class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo { : SPIRTargetInfo(Triple, Opts) { assert(Triple.getArch() == llvm::Triple::spir && "Invalid architecture for 32-bit SPIR."); - // FIXME: Assert that a present host target's pointer types match the ones - // set below, once the driver diagnoses unsupported host/device combinations - // (until then such an assert would fire on existing tests). PointerWidth = PointerAlign = 32; - const TargetInfo *HostTarget = getHostTarget(); - if (!HostTarget || HostTarget->getPointerWidth(LangAS::Default) != 32) { + if (!getHostTarget()) { SizeType = TargetInfo::UnsignedInt; PtrDiffType = IntPtrType = TargetInfo::SignedInt; } + // Host and device pointer related type widths must match. + assert(PointerWidth == 32 && PointerAlign == 32 && + getTypeWidth(SizeType) == 32 && getTypeWidth(PtrDiffType) == 32 && + getTypeWidth(IntPtrType) == 32 && + "Invalid pointer related types for SPIR32"); + // SPIR32 has support for atomic ops if atomic extension is enabled. // Take the maximum because it's possible the Host supports wider types. MaxAtomicInlineWidth = std::max<unsigned char>(MaxAtomicInlineWidth, 64); @@ -281,16 +283,18 @@ class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo : public SPIRTargetInfo { : SPIRTargetInfo(Triple, Opts) { assert(Triple.getArch() == llvm::Triple::spir64 && "Invalid architecture for 64-bit SPIR."); - // FIXME: Assert that a present host target's pointer types match the ones - // set below, once the driver diagnoses unsupported host/device combinations - // (until then such an assert would fire on existing tests). PointerWidth = PointerAlign = 64; - const TargetInfo *HostTarget = getHostTarget(); - if (!HostTarget || HostTarget->getPointerWidth(LangAS::Default) != 64) { + if (!getHostTarget()) { SizeType = TargetInfo::UnsignedLong; PtrDiffType = IntPtrType = TargetInfo::SignedLong; } + // Host and device pointer related type widths must match. + assert(PointerWidth == 64 && PointerAlign == 64 && + getTypeWidth(SizeType) == 64 && getTypeWidth(PtrDiffType) == 64 && + getTypeWidth(IntPtrType) == 64 && + "Invalid pointer related types for SPIR64"); + // SPIR64 has support for atomic ops if atomic extension is enabled. // Take the maximum because it's possible the Host supports wider types. MaxAtomicInlineWidth = std::max<unsigned char>(MaxAtomicInlineWidth, 64); @@ -379,15 +383,18 @@ class LLVM_LIBRARY_VISIBILITY SPIRV32TargetInfo : public BaseSPIRVTargetInfo { "32-bit SPIR-V target must use unknown, chipstar, or vulkan OS"); assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && "32-bit SPIR-V target must use unknown environment type"); - // FIXME: Assert that a present host target's pointer types match the ones - // set below, once the driver diagnoses unsupported host/device combinations - // (until then such an assert would fire on existing tests). PointerWidth = PointerAlign = 32; - const TargetInfo *HostTarget = getHostTarget(); - if (!HostTarget || HostTarget->getPointerWidth(LangAS::Default) != 32) { + if (!getHostTarget()) { SizeType = TargetInfo::UnsignedInt; PtrDiffType = IntPtrType = TargetInfo::SignedInt; } + + // Host and device pointer related type widths must match. + assert(PointerWidth == 32 && PointerAlign == 32 && + getTypeWidth(SizeType) == 32 && getTypeWidth(PtrDiffType) == 32 && + getTypeWidth(IntPtrType) == 32 && + "Invalid pointer related types for SPIR-V 32"); + // SPIR-V has core support for atomic ops, and Int32 is always available; // we take the maximum because it's possible the Host supports wider types. MaxAtomicInlineWidth = std::max<unsigned char>(MaxAtomicInlineWidth, 64); @@ -410,15 +417,18 @@ class LLVM_LIBRARY_VISIBILITY SPIRV64TargetInfo : public BaseSPIRVTargetInfo { "64-bit SPIR-V target must use unknown, chipstar, or vulkan OS"); assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && "64-bit SPIR-V target must use unknown environment type"); - // FIXME: Assert that a present host target's pointer types match the ones - // set below, once the driver diagnoses unsupported host/device combinations - // (until then such an assert would fire on existing tests). PointerWidth = PointerAlign = 64; - const TargetInfo *HostTarget = getHostTarget(); - if (!HostTarget || HostTarget->getPointerWidth(LangAS::Default) != 64) { + if (!getHostTarget()) { SizeType = TargetInfo::UnsignedLong; PtrDiffType = IntPtrType = TargetInfo::SignedLong; } + + // Host and device pointer related type widths must match. + assert(PointerWidth == 64 && PointerAlign == 64 && + getTypeWidth(SizeType) == 64 && getTypeWidth(PtrDiffType) == 64 && + getTypeWidth(IntPtrType) == 64 && + "Invalid pointer related types for SPIR-V 64"); + // SPIR-V has core support for atomic ops, and Int64 is always available; // we take the maximum because it's possible the Host supports wider types. MaxAtomicInlineWidth = std::max<unsigned char>(MaxAtomicInlineWidth, 64); diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 3b5d0c0aad981..cf7e49932a1a2 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -1129,6 +1129,22 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C, continue; } + const llvm::Triple &HostTriple = C.getDefaultToolChain().getTriple(); + // Logical SPIR-V is excluded; it overrides those types with fixed values. + auto AdaptsToHostTarget = [](const llvm::Triple &T) { + return (T.isSPIROrSPIRV() && T.getArch() != llvm::Triple::spirv) || + T.isNVPTX(); + }; + // Target and host pointer related type widths must match. + if (AdaptsToHostTarget(Target) && !AdaptsToHostTarget(HostTriple) && + Target.getArchPointerBitWidth() != + HostTriple.getArchPointerBitWidth()) { + Diag(diag::err_target_unsupported_host_device_pointer_width) + << Target.str() << Target.getArchPointerBitWidth() + << HostTriple.str() << HostTriple.getArchPointerBitWidth(); + continue; + } + std::string NormalizedName = Target.normalize(); auto [TripleIt, Inserted] = FoundNormalizedTriples.try_emplace(NormalizedName, Target.str()); diff --git a/clang/test/CodeGenCUDA/anon-ns.cu b/clang/test/CodeGenCUDA/anon-ns.cu index 651a20c653458..e2b290bd21c3d 100644 --- a/clang/test/CodeGenCUDA/anon-ns.cu +++ b/clang/test/CodeGenCUDA/anon-ns.cu @@ -11,12 +11,12 @@ // RUN: echo "GPU binary" > %t.fatbin -// RUN: %clang_cc1 -triple nvptx -fcuda-is-device -cuid=abc \ +// RUN: %clang_cc1 -triple nvptx64 -fcuda-is-device -cuid=abc \ // RUN: -aux-triple x86_64-unknown-linux-gnu -std=c++17 -fgpu-rdc \ // RUN: -emit-llvm -o - %s > %t.dev // RUN: %clang_cc1 -triple x86_64-gnu-linux -cuid=abc \ -// RUN: -aux-triple nvptx -std=c++17 -fgpu-rdc -fcuda-include-gpubinary %t.fatbin \ +// RUN: -aux-triple nvptx64 -std=c++17 -fgpu-rdc -fcuda-include-gpubinary %t.fatbin \ // RUN: -emit-llvm -o - %s > %t.host // RUN: cat %t.dev %t.host | FileCheck -check-prefixes=CUDA,COMMON %s diff --git a/clang/test/CodeGenCUDA/long-double.cu b/clang/test/CodeGenCUDA/long-double.cu index b4116c0b81594..0a06fbe5db6d0 100644 --- a/clang/test/CodeGenCUDA/long-double.cu +++ b/clang/test/CodeGenCUDA/long-double.cu @@ -6,7 +6,7 @@ // RUN: -aux-triple x86_64-unknown-gnu-linux -fcuda-is-device \ // RUN: -emit-llvm -o - -x hip %s 2>&1 | FileCheck %s -// RUN: %clang_cc1 -triple nvptx \ +// RUN: %clang_cc1 -triple nvptx64 \ // RUN: -aux-triple x86_64-unknown-gnu-linux -fcuda-is-device \ // RUN: -emit-llvm -o - %s 2>&1 | FileCheck %s diff --git a/clang/test/CodeGenCUDASPIRV/copy-aggregate-byval.cu b/clang/test/CodeGenCUDASPIRV/copy-aggregate-byval.cu index 2692ce4c92b28..fa6521b1fa5e3 100644 --- a/clang/test/CodeGenCUDASPIRV/copy-aggregate-byval.cu +++ b/clang/test/CodeGenCUDASPIRV/copy-aggregate-byval.cu @@ -2,12 +2,12 @@ // destructor, copy constructor or move constructor defined by user. // RUN: %clang -emit-llvm --cuda-device-only --offload=spirv32 \ -// RUN: -nocudalib -nocudainc %s -o %t.bc -c 2>&1 +// RUN: --target=i386-unknown-linux-gnu -nocudalib -nocudainc %s -o %t.bc -c 2>&1 // RUN: llvm-dis %t.bc -o %t.ll // RUN: FileCheck %s --input-file=%t.ll // RUN: %clang -emit-llvm --cuda-device-only --offload=spirv64 \ -// RUN: -nocudalib -nocudainc %s -o %t.bc -c 2>&1 +// RUN: --target=x86_64-unknown-linux-gnu -nocudalib -nocudainc %s -o %t.bc -c 2>&1 // RUN: llvm-dis %t.bc -o %t.ll // RUN: FileCheck %s --input-file=%t.ll diff --git a/clang/test/CodeGenCUDASPIRV/kernel-argument.cu b/clang/test/CodeGenCUDASPIRV/kernel-argument.cu index ab885eb3d85c4..8ec47949d0092 100644 --- a/clang/test/CodeGenCUDASPIRV/kernel-argument.cu +++ b/clang/test/CodeGenCUDASPIRV/kernel-argument.cu @@ -2,12 +2,12 @@ // RUN: %clang -emit-llvm --cuda-device-only --offload=spirv32 \ -// RUN: -nocudalib -nocudainc %s -o %t.bc -c 2>&1 +// RUN: --target=i386-unknown-linux-gnu -nocudalib -nocudainc %s -o %t.bc -c 2>&1 // RUN: llvm-dis %t.bc -o %t.ll // RUN: FileCheck %s --input-file=%t.ll // RUN: %clang -emit-llvm --cuda-device-only --offload=spirv64 \ -// RUN: -nocudalib -nocudainc %s -o %t.bc -c 2>&1 +// RUN: --target=x86_64-unknown-linux-gnu -nocudalib -nocudainc %s -o %t.bc -c 2>&1 // RUN: llvm-dis %t.bc -o %t.ll // RUN: FileCheck %s --input-file=%t.ll diff --git a/clang/test/CodeGenSYCL/kernel-caller-entry-point.cpp b/clang/test/CodeGenSYCL/kernel-caller-entry-point.cpp index cc751cc683b59..bbbf4c037f760 100644 --- a/clang/test/CodeGenSYCL/kernel-caller-entry-point.cpp +++ b/clang/test/CodeGenSYCL/kernel-caller-entry-point.cpp @@ -1,26 +1,17 @@ // RUN: %clang_cc1 -fsycl-is-host -emit-llvm -triple x86_64-unknown-linux-gnu -std=c++17 %s -o - | FileCheck --check-prefixes=CHECK-HOST,CHECK-HOST-LINUX %s // RUN: %clang_cc1 -fsycl-is-device -emit-llvm -aux-triple x86_64-unknown-linux-gnu -triple amdgpu-amd-amdhsa -std=c++17 %s -o - | FileCheck --check-prefixes=CHECK-DEVICE,CHECK-AMDGCN %s -// RUN: %clang_cc1 -fsycl-is-device -emit-llvm -aux-triple x86_64-unknown-linux-gnu -triple nvptx-nvidia-cuda -std=c++17 %s -o - | FileCheck --check-prefixes=CHECK-DEVICE,CHECK-NVPTX %s // RUN: %clang_cc1 -fsycl-is-device -emit-llvm -aux-triple x86_64-unknown-linux-gnu -triple nvptx64-nvidia-cuda -std=c++17 %s -o - | FileCheck --check-prefixes=CHECK-DEVICE,CHECK-NVPTX %s -// RUN: %clang_cc1 -fsycl-is-device -emit-llvm -aux-triple x86_64-unknown-linux-gnu -triple spir-unknown-unknown -std=c++17 %s -o - | FileCheck --check-prefixes=CHECK-DEVICE,CHECK-SPIR,CHECK-SPIRNV %s // RUN: %clang_cc1 -fsycl-is-device -emit-llvm -aux-triple x86_64-unknown-linux-gnu -triple spir64-unknown-unknown -std=c++17 %s -o - | FileCheck --check-prefixes=CHECK-DEVICE,CHECK-SPIR,CHECK-SPIRNV %s -// RUN: %clang_cc1 -fsycl-is-device -emit-llvm -aux-triple x86_64-unknown-linux-gnu -triple spirv32-unknown-unknown -std=c++17 %s -o - | FileCheck --check-prefixes=CHECK-DEVICE,CHECK-SPIR,CHECK-SPIRV %s // RUN: %clang_cc1 -fsycl-is-device -emit-llvm -aux-triple x86_64-unknown-linux-gnu -triple spirv64-unknown-unknown -std=c++17 %s -o - | FileCheck --check-prefixes=CHECK-DEVICE,CHECK-SPIR,CHECK-SPIRV %s // RUN: %clang_cc1 -fsycl-is-host -emit-llvm -triple x86_64-pc-windows-msvc -std=c++17 %s -o - | FileCheck --check-prefixes=CHECK-HOST,CHECK-HOST-WINDOWS %s // RUN: %clang_cc1 -fsycl-is-device -emit-llvm -aux-triple x86_64-pc-windows-msvc -triple amdgpu-amd-amdhsa -std=c++17 %s -o - | FileCheck --check-prefixes=CHECK-DEVICE,CHECK-AMDGCN %s -// RUN: %clang_cc1 -fsycl-is-device -emit-llvm -aux-triple x86_64-pc-windows-msvc -triple nvptx-nvidia-cuda -std=c++17 %s -o - | FileCheck --check-prefixes=CHECK-DEVICE,CHECK-NVPTX %s // RUN: %clang_cc1 -fsycl-is-device -emit-llvm -aux-triple x86_64-pc-windows-msvc -triple nvptx64-nvidia-cuda -std=c++17 %s -o - | FileCheck --check-prefixes=CHECK-DEVICE,CHECK-NVPTX %s -// RUN: %clang_cc1 -fsycl-is-device -emit-llvm -aux-triple x86_64-pc-windows-msvc -triple spir-unknown-unknown -std=c++17 %s -o - | FileCheck --check-prefixes=CHECK-DEVICE,CHECK-SPIR,CHECK-SPIRNV %s // RUN: %clang_cc1 -fsycl-is-device -emit-llvm -aux-triple x86_64-pc-windows-msvc -triple spir64-unknown-unknown -std=c++17 %s -o - | FileCheck --check-prefixes=CHECK-DEVICE,CHECK-SPIR,CHECK-SPIRNV %s -// RUN: %clang_cc1 -fsycl-is-device -emit-llvm -aux-triple x86_64-pc-windows-msvc -triple spirv32-unknown-unknown -std=c++17 %s -o - | FileCheck --check-prefixes=CHECK-DEVICE,CHECK-SPIR,CHECK-SPIRV %s // RUN: %clang_cc1 -fsycl-is-device -emit-llvm -aux-triple x86_64-pc-windows-msvc -triple spirv64-unknown-unknown -std=c++17 %s -o - | FileCheck --check-prefixes=CHECK-DEVICE,CHECK-SPIR,CHECK-SPIRV %s // RUN: %clang_cc1 -fsycl-is-host -emit-llvm -triple x86_64-uefi -std=c++17 %s -o - | FileCheck --check-prefixes=CHECK-HOST,CHECK-HOST-WINDOWS %s // RUN: %clang_cc1 -fsycl-is-device -emit-llvm -aux-triple x86_64-uefi -triple amdgpu-amd-amdhsa -std=c++17 %s -o - | FileCheck --check-prefixes=CHECK-DEVICE,CHECK-AMDGCN %s -// RUN: %clang_cc1 -fsycl-is-device -emit-llvm -aux-triple x86_64-uefi -triple nvptx-nvidia-cuda -std=c++17 %s -o - | FileCheck --check-prefixes=CHECK-DEVICE,CHECK-NVPTX %s // RUN: %clang_cc1 -fsycl-is-device -emit-llvm -aux-triple x86_64-uefi -triple nvptx64-nvidia-cuda -std=c++17 %s -o - | FileCheck --check-prefixes=CHECK-DEVICE,CHECK-NVPTX %s -// RUN: %clang_cc1 -fsycl-is-device -emit-llvm -aux-triple x86_64-uefi -triple spir-unknown-unknown -std=c++17 %s -o - | FileCheck --check-prefixes=CHECK-DEVICE,CHECK-SPIR,CHECK-SPIRNV %s // RUN: %clang_cc1 -fsycl-is-device -emit-llvm -aux-triple x86_64-uefi -triple spir64-unknown-unknown -std=c++17 %s -o - | FileCheck --check-prefixes=CHECK-DEVICE,CHECK-SPIR,CHECK-SPIRNV %s -// RUN: %clang_cc1 -fsycl-is-device -emit-llvm -aux-triple x86_64-uefi -triple spirv32-unknown-unknown -std=c++17 %s -o - | FileCheck --check-prefixes=CHECK-DEVICE,CHECK-SPIR,CHECK-SPIRV %s // RUN: %clang_cc1 -fsycl-is-device -emit-llvm -aux-triple x86_64-uefi -triple spirv64-unknown-unknown -std=c++17 %s -o - | FileCheck --check-prefixes=CHECK-DEVICE,CHECK-SPIR,CHECK-SPIRV %s // Test code generation for functions declared with the sycl_kernel_entry_point diff --git a/clang/test/Driver/cuda-device-triple.cu b/clang/test/Driver/cuda-device-triple.cu index 8acd4585b8c82..5abdcbf2b7381 100644 --- a/clang/test/Driver/cuda-device-triple.cu +++ b/clang/test/Driver/cuda-device-triple.cu @@ -1,4 +1,4 @@ -// RUN: %clang -### -emit-llvm --cuda-device-only \ +// RUN: %clang -### -emit-llvm --cuda-device-only --target=i386-unknown-linux-gnu \ // RUN: -nocudalib -nocudainc --offload=spirv32-unknown-unknown -c %s 2>&1 | FileCheck %s // Make sure there's no sm_* suffix on the output name diff --git a/clang/test/Frontend/sycl-aux-triple.cpp b/clang/test/Frontend/sycl-aux-triple.cpp index 38b6a24fb3ce9..2ab23fd1cf7e8 100644 --- a/clang/test/Frontend/sycl-aux-triple.cpp +++ b/clang/test/Frontend/sycl-aux-triple.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 %s -triple spir -aux-triple x86_64-unknown-linux-gnu -E -dM | FileCheck %s -// RUN: %clang_cc1 %s -fsycl-is-device -triple spir -aux-triple x86_64-unknown-linux-gnu -E -dM | FileCheck --check-prefix=CHECK-SYCL %s +// RUN: %clang_cc1 %s -triple spir64 -aux-triple x86_64-unknown-linux-gnu -E -dM | FileCheck %s +// RUN: %clang_cc1 %s -fsycl-is-device -triple spir64 -aux-triple x86_64-unknown-linux-gnu -E -dM | FileCheck --check-prefix=CHECK-SYCL %s // CHECK-NOT:#define __x86_64__ 1 // CHECK-SYCL:#define __x86_64__ 1 diff --git a/clang/test/SemaCUDA/allow-int128.cu b/clang/test/SemaCUDA/allow-int128.cu index 44f8fefa3aa05..5d2f484bcd44d 100644 --- a/clang/test/SemaCUDA/allow-int128.cu +++ b/clang/test/SemaCUDA/allow-int128.cu @@ -4,7 +4,7 @@ // RUN: %clang_cc1 -triple spirv64-amd-amdhsa \ // RUN: -aux-triple x86_64-unknown-linux-gnu \ // RUN: -fcuda-is-device -verify -fsyntax-only %s -// RUN: %clang_cc1 -triple nvptx \ +// RUN: %clang_cc1 -triple nvptx64 \ // RUN: -aux-triple x86_64-unknown-linux-gnu \ // RUN: -fcuda-is-device -verify -fsyntax-only %s diff --git a/clang/test/SemaCUDA/cuda-inherits-calling-conv.cu b/clang/test/SemaCUDA/cuda-inherits-calling-conv.cu index a6928e71f3ae0..a4a6292e012e4 100644 --- a/clang/test/SemaCUDA/cuda-inherits-calling-conv.cu +++ b/clang/test/SemaCUDA/cuda-inherits-calling-conv.cu @@ -5,7 +5,7 @@ // RUN: -aux-triple i386-windows-msvc -fsyntax-only \ // RUN: -fcuda-is-device -verify %s -// RUN: %clang_cc1 -std=c++11 -triple nvptx-nvidia-cuda \ +// RUN: %clang_cc1 -std=c++11 -triple nvptx64-nvidia-cuda \ // RUN: -aux-triple x86_64-linux-gnu -fsyntax-only \ // RUN: -fcuda-is-device -verify -verify-ignore-unexpected=note \ // RUN: -DEXPECT_ERR %s diff --git a/clang/test/SemaHIP/amdgcnspirv-implicit-alloc-function-calling-conv.hip b/clang/test/SemaHIP/amdgcnspirv-implicit-alloc-function-calling-conv.hip index c3e7e1a5cd59e..66bf9b359e65a 100644 --- a/clang/test/SemaHIP/amdgcnspirv-implicit-alloc-function-calling-conv.hip +++ b/clang/test/SemaHIP/amdgcnspirv-implicit-alloc-function-calling-conv.hip @@ -1,10 +1,8 @@ // RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv32 -verify // RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv64 -verify // RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv64-amd-amdhsa -verify -// RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv32 -aux-triple x86_64-unknown-linux-gnu -verify // RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv64 -aux-triple x86_64-unknown-linux-gnu -verify // RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv64-amd-amdhsa -aux-triple x86_64-unknown-linux-gnu -verify -// RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv32 -aux-triple x86_64-pc-windows-msvc -verify // RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv64 -aux-triple x86_64-pc-windows-msvc -verify // RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv64-amd-amdhsa -aux-triple x86_64-pc-windows-msvc -verify >From 306f69d8643631f04d935f9b3834f1031f61576a Mon Sep 17 00:00:00 2001 From: Sindhu Chittireddy <[email protected]> Date: Fri, 28 Aug 2026 10:44:07 -0700 Subject: [PATCH 2/2] Diagnose other type and size mismatches in addition to pointer width --- clang/docs/ReleaseNotes.md | 9 ++- .../clang/Basic/DiagnosticCommonKinds.td | 7 +- clang/include/clang/Basic/TargetInfo.h | 30 +++++++ clang/lib/Basic/Targets.cpp | 79 ++++++++++++++----- clang/lib/Basic/Targets/SPIR.h | 32 +------- clang/lib/Driver/Driver.cpp | 18 ++--- clang/lib/Frontend/CompilerInstance.cpp | 8 +- clang/test/Driver/hip-autolink.hip | 6 +- clang/test/SemaCUDA/amdgpu-bf16.cu | 4 +- 9 files changed, 121 insertions(+), 72 deletions(-) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index d1651cdb92581..42f52a2fd1a83 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -51,11 +51,12 @@ The previous behavior can be restored with `-Wno-error=unicode-whitespace`. Clang will stop accepting non-ascii whitespaces as token separators in a future version of Clang. -- Offload compilations that pair a SPIR, physical SPIR-V, or NVPTX device target - with a host of a different pointer width are now rejected, for example - `--offload=spirv32` with an `x86_64` host. These targets take `size_t`, +- Offload compilations that pair a SPIR, physical SPIR-V, NVPTX, or AMDGPU device + target with an incompatible host target are now rejected, for example + `--offload=spirv32` with an `x86_64` host, or `--offload-arch=gfx906` with an + `i386` host. These targets take the pointer width and alignment, `size_t`, `ptrdiff_t`, and `intptr_t` from the host, so a mismatch disagreed with the - device data layout. Select a device target whose width matches the host's. + device data layout. Select a host and device target that agree on those types. ### C++ Specific Potentially Breaking Changes diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index ece27b02f840e..bbf9882ffda06 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -338,9 +338,10 @@ def err_target_unknown_cpu : Error<"unknown target CPU '%0'">; def note_valid_options : Note<"valid target CPU values are: %0">; def err_target_unsupported_cpu_for_micromips : Error< "micromips is not supported for target CPU '%0'">; -def err_target_unsupported_host_device_pointer_width : Error< - "device target '%0' with %1-bit pointers is incompatible with host target " - "'%2' with %3-bit pointers">; +def err_target_unsupported_host_pointer_related_type : Error< + "device target '%0' takes %select{a pointer width|a pointer alignment|" + "a 'size_t' width|a 'ptrdiff_t' width|an 'intptr_t' width}2 of %3 bits from " + "host target '%1', but requires %4 bits">; def err_target_unknown_abi : Error<"unknown target ABI '%0'">; def err_target_unsupported_abi : Error<"ABI '%0' is not supported on CPU '%1'">; def err_target_unsupported_abi_for_triple : Error< diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 6311b6b567a5e..f0f5bf735ae95 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -327,6 +327,36 @@ class TargetInfo : public TransferrableTargetInfo, static TargetInfo *CreateTargetInfo(DiagnosticsEngine &Diags, TargetOptions &Opts); + /// When a device target takes its pointer related types (the pointer width + /// and alignment, size_t, ptrdiff_t, and intptr_t) from a host target. + enum class HostAdaptation { + /// It keeps its own pointer related types. + None, + /// It adapts in its constructor, from TargetOptions::HostTriple. + Constructor, + SetAuxTarget, + }; + + /// Returns when the device target takes its pointer related types from the + /// host target, mirroring the conditions under which the TargetInfo + /// subclasses adapt. A device that declines a host keeps its own types, which + /// the driver's triple level check must not report as a mismatch. + static HostAdaptation getHostAdaptation(const llvm::Triple &DeviceTriple, + const llvm::Triple &HostTriple); + + static bool adaptsToHostTarget(const llvm::Triple &DeviceTriple, + const llvm::Triple &HostTriple) { + return getHostAdaptation(DeviceTriple, HostTriple) != HostAdaptation::None; + } + + /// Reports an error if this target adapts to the given host target at the + /// given stage and ended up with pointer related types that disagree with its + /// own data layout. Does nothing if it does not adapt at that stage. Returns + /// true if no error was reported. + bool checkHostPointerRelatedTypes(DiagnosticsEngine &Diags, + const llvm::Triple &HostTriple, + HostAdaptation Stage) const; + virtual ~TargetInfo(); /// Retrieve the target options. diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index a939eb9b94470..ed48400a947f9 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -836,12 +836,59 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple, using namespace clang::targets; -/// Returns true if Triple names a target that takes its pointer related types -/// from a host target. Logical SPIR-V is excluded; it uses fixed values for -/// those types regardless of the host. -static bool adaptsToHostTarget(const llvm::Triple &Triple) { - return (Triple.isSPIROrSPIRV() && Triple.getArch() != llvm::Triple::spirv) || - Triple.isNVPTX(); +TargetInfo::HostAdaptation +TargetInfo::getHostAdaptation(const llvm::Triple &DeviceTriple, + const llvm::Triple &HostTriple) { + // No recognizable host triple, so nothing to adapt to. + if (HostTriple.getArch() == llvm::Triple::UnknownArch) + return HostAdaptation::None; + + // setAuxTarget() overwrites these, so constructor values are not yet final. + if (DeviceTriple.isAMDGPU() || + (DeviceTriple.getArch() == llvm::Triple::spirv64 && + DeviceTriple.getOS() == llvm::Triple::AMDHSA)) + return HostAdaptation::SetAuxTarget; + + // Logical SPIR-V sets these itself, with a 32-bit size_t by design. + if (DeviceTriple.isSPIRVLogical()) + return HostAdaptation::None; + + if (DeviceTriple.isSPIROrSPIRV()) + return HostTriple.isSPIROrSPIRV() ? HostAdaptation::None + : HostAdaptation::Constructor; + if (DeviceTriple.isNVPTX()) + return HostTriple.isNVPTX() ? HostAdaptation::None + : HostAdaptation::Constructor; + + return HostAdaptation::None; +} + +bool TargetInfo::checkHostPointerRelatedTypes(DiagnosticsEngine &Diags, + const llvm::Triple &HostTriple, + HostAdaptation Stage) const { + assert(Stage != HostAdaptation::None && "Nothing to check"); + if (getHostAdaptation(getTriple(), HostTriple) != Stage) + return true; + + // The device data layout fixes the width of every one of these types. + unsigned Required = getTriple().getArchPointerBitWidth(); + // The order matches the %select in the diagnostic below. + unsigned Widths[] = {getPointerWidth(LangAS::Default), + getPointerAlign(LangAS::Default), + getTypeWidth(getSizeType()), + getTypeWidth(getPtrDiffType(LangAS::Default)), + getTypeWidth(getIntPtrType())}; + + for (auto [Which, Width] : llvm::enumerate(Widths)) { + if (Width != Required) { + Diags.Report(diag::err_target_unsupported_host_pointer_related_type) + << getTriple().str() << HostTriple.str() + << static_cast<unsigned>(Which) << Width << Required; + return false; + } + } + + return true; } /// CreateTargetInfo - Return the target info object for the specified target @@ -852,21 +899,6 @@ TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, llvm::Triple Triple(llvm::Triple::normalize(Opts->Triple)); - // Host and device pointer related type widths must match. Reject a mismatch - // before constructing the device target, which asserts on this. - if (adaptsToHostTarget(Triple) && !Opts->HostTriple.empty()) { - llvm::Triple HostTriple(llvm::Triple::normalize(Opts->HostTriple)); - if (!adaptsToHostTarget(HostTriple) && - HostTriple.getArch() != llvm::Triple::UnknownArch && - Triple.getArchPointerBitWidth() != - HostTriple.getArchPointerBitWidth()) { - Diags.Report(diag::err_target_unsupported_host_device_pointer_width) - << Triple.str() << Triple.getArchPointerBitWidth() << HostTriple.str() - << HostTriple.getArchPointerBitWidth(); - return nullptr; - } - } - // Construct the target std::unique_ptr<TargetInfo> Target = AllocateTarget(Triple, *Opts); if (!Target) { @@ -875,6 +907,11 @@ TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, } Target->TargetOpts = Opts; + // Targets that adapt in their constructor have done so by now. + if (!Target->checkHostPointerRelatedTypes( + Diags, llvm::Triple(Opts->HostTriple), HostAdaptation::Constructor)) + return nullptr; + // Set the target CPU if specified. if (!Opts->CPU.empty() && !Target->setCPU(Opts->CPU)) { Diags.Report(diag::err_target_unknown_cpu) << Opts->CPU; diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h index 17f90e80dc5fd..b5400cddf575c 100644 --- a/clang/lib/Basic/Targets/SPIR.h +++ b/clang/lib/Basic/Targets/SPIR.h @@ -254,18 +254,12 @@ class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo { : SPIRTargetInfo(Triple, Opts) { assert(Triple.getArch() == llvm::Triple::spir && "Invalid architecture for 32-bit SPIR."); - PointerWidth = PointerAlign = 32; if (!getHostTarget()) { + PointerWidth = PointerAlign = 32; SizeType = TargetInfo::UnsignedInt; PtrDiffType = IntPtrType = TargetInfo::SignedInt; } - // Host and device pointer related type widths must match. - assert(PointerWidth == 32 && PointerAlign == 32 && - getTypeWidth(SizeType) == 32 && getTypeWidth(PtrDiffType) == 32 && - getTypeWidth(IntPtrType) == 32 && - "Invalid pointer related types for SPIR32"); - // SPIR32 has support for atomic ops if atomic extension is enabled. // Take the maximum because it's possible the Host supports wider types. MaxAtomicInlineWidth = std::max<unsigned char>(MaxAtomicInlineWidth, 64); @@ -283,18 +277,12 @@ class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo : public SPIRTargetInfo { : SPIRTargetInfo(Triple, Opts) { assert(Triple.getArch() == llvm::Triple::spir64 && "Invalid architecture for 64-bit SPIR."); - PointerWidth = PointerAlign = 64; if (!getHostTarget()) { + PointerWidth = PointerAlign = 64; SizeType = TargetInfo::UnsignedLong; PtrDiffType = IntPtrType = TargetInfo::SignedLong; } - // Host and device pointer related type widths must match. - assert(PointerWidth == 64 && PointerAlign == 64 && - getTypeWidth(SizeType) == 64 && getTypeWidth(PtrDiffType) == 64 && - getTypeWidth(IntPtrType) == 64 && - "Invalid pointer related types for SPIR64"); - // SPIR64 has support for atomic ops if atomic extension is enabled. // Take the maximum because it's possible the Host supports wider types. MaxAtomicInlineWidth = std::max<unsigned char>(MaxAtomicInlineWidth, 64); @@ -383,18 +371,12 @@ class LLVM_LIBRARY_VISIBILITY SPIRV32TargetInfo : public BaseSPIRVTargetInfo { "32-bit SPIR-V target must use unknown, chipstar, or vulkan OS"); assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && "32-bit SPIR-V target must use unknown environment type"); - PointerWidth = PointerAlign = 32; if (!getHostTarget()) { + PointerWidth = PointerAlign = 32; SizeType = TargetInfo::UnsignedInt; PtrDiffType = IntPtrType = TargetInfo::SignedInt; } - // Host and device pointer related type widths must match. - assert(PointerWidth == 32 && PointerAlign == 32 && - getTypeWidth(SizeType) == 32 && getTypeWidth(PtrDiffType) == 32 && - getTypeWidth(IntPtrType) == 32 && - "Invalid pointer related types for SPIR-V 32"); - // SPIR-V has core support for atomic ops, and Int32 is always available; // we take the maximum because it's possible the Host supports wider types. MaxAtomicInlineWidth = std::max<unsigned char>(MaxAtomicInlineWidth, 64); @@ -417,18 +399,12 @@ class LLVM_LIBRARY_VISIBILITY SPIRV64TargetInfo : public BaseSPIRVTargetInfo { "64-bit SPIR-V target must use unknown, chipstar, or vulkan OS"); assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && "64-bit SPIR-V target must use unknown environment type"); - PointerWidth = PointerAlign = 64; if (!getHostTarget()) { + PointerWidth = PointerAlign = 64; SizeType = TargetInfo::UnsignedLong; PtrDiffType = IntPtrType = TargetInfo::SignedLong; } - // Host and device pointer related type widths must match. - assert(PointerWidth == 64 && PointerAlign == 64 && - getTypeWidth(SizeType) == 64 && getTypeWidth(PtrDiffType) == 64 && - getTypeWidth(IntPtrType) == 64 && - "Invalid pointer related types for SPIR-V 64"); - // SPIR-V has core support for atomic ops, and Int64 is always available; // we take the maximum because it's possible the Host supports wider types. MaxAtomicInlineWidth = std::max<unsigned char>(MaxAtomicInlineWidth, 64); diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index cf7e49932a1a2..f90c2804b805c 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -55,6 +55,7 @@ #include "ToolChains/ZOS.h" #include "clang/Basic/DiagnosticDriver.h" #include "clang/Basic/TargetID.h" +#include "clang/Basic/TargetInfo.h" #include "clang/Basic/Version.h" #include "clang/Config/config.h" #include "clang/Driver/Action.h" @@ -1129,19 +1130,16 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C, continue; } + // A triple level approximation that catches the common cases early; the + // types are checked once the device adapts. const llvm::Triple &HostTriple = C.getDefaultToolChain().getTriple(); - // Logical SPIR-V is excluded; it overrides those types with fixed values. - auto AdaptsToHostTarget = [](const llvm::Triple &T) { - return (T.isSPIROrSPIRV() && T.getArch() != llvm::Triple::spirv) || - T.isNVPTX(); - }; - // Target and host pointer related type widths must match. - if (AdaptsToHostTarget(Target) && !AdaptsToHostTarget(HostTriple) && + if (TargetInfo::adaptsToHostTarget(Target, HostTriple) && Target.getArchPointerBitWidth() != HostTriple.getArchPointerBitWidth()) { - Diag(diag::err_target_unsupported_host_device_pointer_width) - << Target.str() << Target.getArchPointerBitWidth() - << HostTriple.str() << HostTriple.getArchPointerBitWidth(); + Diag(diag::err_target_unsupported_host_pointer_related_type) + << Target.str() << HostTriple.str() << /*pointer width*/ 0 + << HostTriple.getArchPointerBitWidth() + << Target.getArchPointerBitWidth(); continue; } diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index 66662a786e6fc..7a7373b82ebb9 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -167,9 +167,15 @@ bool CompilerInstance::createTarget() { // created. This complexity should be lifted elsewhere. getTarget().adjust(getDiagnostics(), getLangOpts(), getAuxTarget()); - if (auto *Aux = getAuxTarget()) + if (auto *Aux = getAuxTarget()) { getTarget().setAuxTarget(Aux); + if (!getTarget().checkHostPointerRelatedTypes( + getDiagnostics(), Aux->getTriple(), + TargetInfo::HostAdaptation::SetAuxTarget)) + return false; + } + return true; } diff --git a/clang/test/Driver/hip-autolink.hip b/clang/test/Driver/hip-autolink.hip index cce3977375d2e..e37c6e5d7e502 100644 --- a/clang/test/Driver/hip-autolink.hip +++ b/clang/test/Driver/hip-autolink.hip @@ -1,10 +1,10 @@ -// RUN: %clang --target=i386-pc-windows-msvc --cuda-gpu-arch=gfx906 -nogpulib -nogpuinc \ +// RUN: %clang --target=x86_64-pc-windows-msvc --cuda-gpu-arch=gfx906 -nogpulib -nogpuinc \ // RUN: --cuda-device-only %s -### 2>&1 | FileCheck --check-prefix=DEV %s -// RUN: %clang --target=i386-pc-windows-msvc --cuda-gpu-arch=gfx906 -nogpulib -nogpuinc \ +// RUN: %clang --target=x86_64-pc-windows-msvc --cuda-gpu-arch=gfx906 -nogpulib -nogpuinc \ // RUN: --cuda-host-only %s -### 2>&1 | FileCheck --check-prefix=HOST %s // DEV: "-cc1" "-triple" "amdgcn-amd-amdhsa" // DEV-SAME: "-fno-autolink" -// HOST: "-cc1" "-triple" "i386-pc-windows-msvc{{.*}}" +// HOST: "-cc1" "-triple" "x86_64-pc-windows-msvc{{.*}}" // HOST-NOT: "-fno-autolink" diff --git a/clang/test/SemaCUDA/amdgpu-bf16.cu b/clang/test/SemaCUDA/amdgpu-bf16.cu index 0b5ce1a4f64cf..b14a3dd608aeb 100644 --- a/clang/test/SemaCUDA/amdgpu-bf16.cu +++ b/clang/test/SemaCUDA/amdgpu-bf16.cu @@ -1,8 +1,8 @@ // REQUIRES: amdgpu-registered-target // REQUIRES: x86-registered-target -// RUN: %clang_cc1 "-aux-triple" "x86_64-unknown-linux-gnu" "-triple" "r600-unknown-unknown"\ -// RUN: -fcuda-is-device "-aux-target-cpu" "x86-64" -fsyntax-only -verify=r600 %s +// RUN: %clang_cc1 "-aux-triple" "i386-unknown-linux-gnu" "-triple" "r600-unknown-unknown"\ +// RUN: -fcuda-is-device "-aux-target-cpu" "i686" -fsyntax-only -verify=r600 %s // AMDGCN has storage-only support for bf16. R600 does not support it should error out when // it's the main target. _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
