https://github.com/AlexVlx updated https://github.com/llvm/llvm-project/pull/192136
>From c0933bf40cee4ed34a14c6b70cab9950194ad6d3 Mon Sep 17 00:00:00 2001 From: Alex Voicu <[email protected]> Date: Tue, 9 Dec 2025 21:44:27 +0000 Subject: [PATCH 1/7] i128 is legal in IR / MIR, even though it might yield a module which requires extensions. --- llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp | 17 +++++++++-------- llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp | 4 ++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp index 2078bfee2e767..73e813ef53094 100644 --- a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp @@ -115,18 +115,19 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) { v4s1, v4s8, v4s16, v4s32, v4s64}; auto allScalarsAndVectors = { - s1, s8, s16, s32, s64, v2s1, v2s8, v2s16, v2s32, v2s64, - v3s1, v3s8, v3s16, v3s32, v3s64, v4s1, v4s8, v4s16, v4s32, v4s64, - v8s1, v8s8, v8s16, v8s32, v8s64, v16s1, v16s8, v16s16, v16s32, v16s64}; + s1, s8, s16, s32, s64, s128, v2s1, v2s8, v2s16, v2s32, + v2s64, v3s1, v3s8, v3s16, v3s32, v3s64, v4s1, v4s8, v4s16, v4s32, + v4s64, v8s1, v8s8, v8s16, v8s32, v8s64, v16s1, v16s8, v16s16, v16s32, + v16s64}; - auto allIntScalarsAndVectors = {s8, s16, s32, s64, v2s8, v2s16, - v2s32, v2s64, v3s8, v3s16, v3s32, v3s64, - v4s8, v4s16, v4s32, v4s64, v8s8, v8s16, - v8s32, v8s64, v16s8, v16s16, v16s32, v16s64}; + auto allIntScalarsAndVectors = { + s8, s16, s32, s64, s128, v2s8, v2s16, v2s32, v2s64, v3s8, + v3s16, v3s32, v3s64, v4s8, v4s16, v4s32, v4s64, v8s8, v8s16, v8s32, + v8s64, v16s8, v16s16, v16s32, v16s64}; auto allBoolScalarsAndVectors = {s1, v2s1, v3s1, v4s1, v8s1, v16s1}; - auto allIntScalars = {s8, s16, s32, s64}; + auto allIntScalars = {s8, s16, s32, s64, s128}; auto allFloatScalarsAndF16Vector2AndVector4s = {s16, s32, s64, v2s16, v4s16}; diff --git a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp index acc726717743d..9ddbeee92ffb6 100644 --- a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp @@ -388,11 +388,11 @@ static SPIRVType *propagateSPIRVType(MachineInstr *MI, SPIRVGlobalRegistry *GR, // To support current approach and limitations wrt. bit width here we widen a // scalar register with a bit width greater than 1 to valid sizes and cap it to -// 64 width. +// 128 width. static unsigned widenBitWidthToNextPow2(unsigned BitWidth) { if (BitWidth == 1) return 1; // No need to widen 1-bit values - return std::min(std::max(1u << Log2_32_Ceil(BitWidth), 8u), 64u); + return std::min(std::max(1u << Log2_32_Ceil(BitWidth), 8u), 128u); } static void widenScalarType(Register Reg, MachineRegisterInfo &MRI) { >From 82dbfe9ac050698e040cfacf5bc1ea4125901518 Mon Sep 17 00:00:00 2001 From: Alex Voicu <[email protected]> Date: Tue, 9 Dec 2025 21:54:01 +0000 Subject: [PATCH 2/7] Fix formatting. --- llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp index 73e813ef53094..30703ee40be06 100644 --- a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp @@ -115,15 +115,15 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) { v4s1, v4s8, v4s16, v4s32, v4s64}; auto allScalarsAndVectors = { - s1, s8, s16, s32, s64, s128, v2s1, v2s8, v2s16, v2s32, - v2s64, v3s1, v3s8, v3s16, v3s32, v3s64, v4s1, v4s8, v4s16, v4s32, - v4s64, v8s1, v8s8, v8s16, v8s32, v8s64, v16s1, v16s8, v16s16, v16s32, - v16s64}; + s1, s8, s16, s32, s64, s128, v2s1, v2s8, + v2s16, v2s32, v2s64, v3s1, v3s8, v3s16, v3s32, v3s64, + v4s1, v4s8, v4s16, v4s32, v4s64, v8s1, v8s8, v8s16, + v8s32, v8s64, v16s1, v16s8, v16s16, v16s32, v16s64}; auto allIntScalarsAndVectors = { - s8, s16, s32, s64, s128, v2s8, v2s16, v2s32, v2s64, v3s8, - v3s16, v3s32, v3s64, v4s8, v4s16, v4s32, v4s64, v8s8, v8s16, v8s32, - v8s64, v16s8, v16s16, v16s32, v16s64}; + s8, s16, s32, s64, s128, v2s8, v2s16, v2s32, v2s64, + v3s8, v3s16, v3s32, v3s64, v4s8, v4s16, v4s32, v4s64, v8s8, + v8s16, v8s32, v8s64, v16s8, v16s16, v16s32, v16s64}; auto allBoolScalarsAndVectors = {s1, v2s1, v3s1, v4s1, v8s1, v16s1}; >From 97d5cc2eaa4db8027ecb6f038b356231c745c0a8 Mon Sep 17 00:00:00 2001 From: Alex Voicu <[email protected]> Date: Mon, 15 Dec 2025 17:59:30 +0000 Subject: [PATCH 3/7] Handle storing of aggregates via `spv_store`. --- llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp | 13 ++++++++ .../Target/SPIRV/SPIRVInstructionSelector.cpp | 10 +++++++ .../SPIRV/instructions/nested-composites.ll | 30 +++++++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp index 9b34ff90abe69..73dcec062d3f0 100644 --- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp @@ -2021,6 +2021,19 @@ Instruction *SPIRVEmitIntrinsics::visitStoreInst(StoreInst &I) { MachineMemOperand::Flags Flags = TLI->getStoreMemOperandFlags(I, CurrF->getDataLayout()); auto *PtrOp = I.getPointerOperand(); + + if (I.getValueOperand()->getType()->isAggregateType()) { + // It is possible that what used to be an ExtractValueInst has been replaced + // with a call to the spv_extractv intrinsic, and that said call hasn't + // had its return type replaced with i32 during the dedicated pass (because + // it was emitted later); we have to handle this here, because IRTranslator + // cannot deal with multi-register types at the moment. + CallBase *CB = dyn_cast<CallBase>(I.getValueOperand()); + assert(CB && CB->getIntrinsicID() == Intrinsic::spv_extractv && + "Unexpected argument of aggregate type, should be spv_extractv!"); + CB->mutateType(B.getInt32Ty()); + } + auto *NewI = B.CreateIntrinsic( Intrinsic::spv_store, {I.getValueOperand()->getType(), PtrOp->getType()}, {I.getValueOperand(), PtrOp, B.getInt16(Flags), diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp index 2e4563795e8f0..dd2e3f1951850 100644 --- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp @@ -3297,6 +3297,16 @@ bool SPIRVInstructionSelector::selectInsertVal(Register ResVReg, bool SPIRVInstructionSelector::selectExtractVal(Register ResVReg, const SPIRVType *ResType, MachineInstr &I) const { + Type *MaybeResTy = nullptr; + StringRef ResName; + if (GR.findValueAttrs(&I, MaybeResTy, ResName) && + MaybeResTy != GR.getTypeForSPIRVType(ResType)) { + assert(!MaybeResTy || MaybeResTy->isAggregateType() && + "Expected aggregate type for extractv instruction"); + ResType = GR.getOrCreateSPIRVType(MaybeResTy, I, + SPIRV::AccessQualifier::ReadWrite, false); + GR.assignSPIRVTypeToVReg(ResType, ResVReg, *I.getMF()); + } MachineBasicBlock &BB = *I.getParent(); auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpCompositeExtract)) .addDef(ResVReg) diff --git a/llvm/test/CodeGen/SPIRV/instructions/nested-composites.ll b/llvm/test/CodeGen/SPIRV/instructions/nested-composites.ll index 88e992f183452..7b49002766a26 100644 --- a/llvm/test/CodeGen/SPIRV/instructions/nested-composites.ll +++ b/llvm/test/CodeGen/SPIRV/instructions/nested-composites.ll @@ -1,13 +1,19 @@ ; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s +; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %} +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %} ; CHECK-DAG: OpName [[FOOBAR:%.+]] "foobar" ; CHECK-DAG: OpName [[PRODUCER:%.+]] "producer" ; CHECK-DAG: OpName [[CONSUMER:%.+]] "consumer" +; CHECK-DAG: OpName [[SNEAKY:%.+]] "sneaky" +; CHECK-DAG: OpName [[ARR_RET:%.+]] "arr_ret" ; CHECK-NOT: DAG-FENCE %ty1 = type {i16, i32} %ty2 = type {%ty1, i64} +%ty3 = type {ptr addrspace(4), ptr addrspace(4), [8 x i8]} ; CHECK-DAG: [[I16:%.+]] = OpTypeInt 16 ; CHECK-DAG: [[I32:%.+]] = OpTypeInt 32 @@ -18,6 +24,12 @@ ; CHECK-DAG: [[UNDEF_I64:%.+]] = OpUndef [[I64]] ; CHECK-DAG: [[UNDEF_TY2:%.+]] = OpUndef [[TY2]] ; CHECK-DAG: [[CST_42:%.+]] = OpConstant [[I32]] 42 +; CHECK-DAG: [[I8:%.+]] = OpTypeInt 8 0 +; CHECK-DAG: [[PTR:%.+]] = OpTypePointer Generic [[I8]] +; CHECK-DAG: [[CST_8:%.+]] = OpConstant [[I32]] 8 +; CHECK-DAG: [[ARR:%.+]] = OpTypeArray [[I8]] [[CST_8]] +; CHECK-DAG: [[TY3:%.+]] = OpTypeStruct [[PTR]] [[PTR]] [[ARR]] +; CHECK-DAG: [[PTR_ARR:%.+]] = OpTypePointer Generic [[ARR]] ; CHECK-NOT: DAG-FENCE @@ -62,3 +74,21 @@ define i32 @consumer(%ty2 %agg) { ; CHECK: [[RET:%.+]] = OpCompositeExtract [[I32]] [[AGG]] 0 1 ; CHECK: OpReturnValue [[RET]] ; CHECK: OpFunctionEnd + +declare %ty3 @arr_ret() + +define void @sneaky(ptr addrspace(4) %p, [8 x i8] %a) { + %1 = call spir_func %ty3 @arr_ret() + %2 = getelementptr inbounds nuw %ty3, ptr addrspace(4) %p, i32 0, i32 2 + %3 = extractvalue %ty3 %1, 2 + store [8 x i8] %3, ptr addrspace(4) %2, align 8 + ret void +} + +; CHECK: [[SNEAKY]] = OpFunction +; CHECK: [[PTR_AGG:%.+]] = OpFunctionParameter +; CHECK: [[A:%.+]] = OpFunctionParameter [[ARR]] +; CHECK: [[AGG_RET:%.+]] = OpFunctionCall [[TY3]] +; CHECK: [[GEP:%.+]] = OpInBoundsPtrAccessChain [[PTR_ARR]] [[PTR_AGG]] +; CHECK: [[EXTRACTV:%.+]] = OpCompositeExtract [[ARR]] [[AGG_RET]] 2 +; CHECK: OpStore [[GEP]] [[EXTRACTV]] >From f837bb69c73c38dc2c628fe1e83b87526bd8d4d8 Mon Sep 17 00:00:00 2001 From: Alex Voicu <[email protected]> Date: Mon, 15 Dec 2025 18:46:39 +0000 Subject: [PATCH 4/7] Fix formatting. --- llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp index dd2e3f1951850..77c4678bb2210 100644 --- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp @@ -3301,8 +3301,9 @@ bool SPIRVInstructionSelector::selectExtractVal(Register ResVReg, StringRef ResName; if (GR.findValueAttrs(&I, MaybeResTy, ResName) && MaybeResTy != GR.getTypeForSPIRVType(ResType)) { - assert(!MaybeResTy || MaybeResTy->isAggregateType() && - "Expected aggregate type for extractv instruction"); + assert(!MaybeResTy || + MaybeResTy->isAggregateType() && + "Expected aggregate type for extractv instruction"); ResType = GR.getOrCreateSPIRVType(MaybeResTy, I, SPIRV::AccessQualifier::ReadWrite, false); GR.assignSPIRVTypeToVReg(ResType, ResVReg, *I.getMF()); >From 610c2971b9c16e8ce2b75f5e4bd8430596926f64 Mon Sep 17 00:00:00 2001 From: Alex Voicu <[email protected]> Date: Thu, 19 Mar 2026 00:25:37 +0000 Subject: [PATCH 5/7] Add `llvm.spv.named.boolean.spec.constant` intrinsic. --- llvm/include/llvm/IR/IntrinsicsSPIRV.td | 5 +++++ .../Target/SPIRV/SPIRVInstructionSelector.cpp | 14 +++++++++++++ .../CodeGen/SPIRV/constant/spec-constant.ll | 21 ++++++++++++++++++- 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td index 5d467adb08c3d..51cb430f4bd43 100644 --- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td +++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td @@ -43,6 +43,11 @@ let TargetPrefix = "spv" in { def int_spv_alloca_array : Intrinsic<[llvm_any_ty], [llvm_anyint_ty, llvm_i32_ty], [ImmArg<ArgIndex<1>>]>; def int_spv_undef : Intrinsic<[llvm_i32_ty], []>; def int_spv_inline_asm : Intrinsic<[], [llvm_metadata_ty, llvm_metadata_ty, llvm_vararg_ty]>; + def int_spv_named_boolean_spec_constant + : Intrinsic<[llvm_i1_ty], [llvm_i32_ty, llvm_i1_ty, llvm_metadata_ty], + [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>]>; + // TODO: possibly add intrinsics for other types of Spec Constants and a + // corresponding Clang builtin. // Masked Gather/Scatter (SPV_INTEL_masked_gather_scatter) def int_spv_masked_gather : Intrinsic<[llvm_any_ty], diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp index eb30002d2e1a5..c045ab693e9ab 100644 --- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp @@ -4125,6 +4125,20 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg, MIB.constrainAllUses(TII, TRI, RBI); return true; } + case Intrinsic::spv_named_boolean_spec_constant: { + auto Opcode = I.getOperand(3).getImm() + ? SPIRV::OpSpecConstantTrue : SPIRV::OpSpecConstantFalse; + + auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(Opcode)) + .addDef(I.getOperand(0).getReg()) + .addUse(GR.getSPIRVTypeID(ResType)); + MIB.constrainAllUses(TII, TRI, RBI); + unsigned SpecId = I.getOperand(2).getImm(); + buildOpDecorate(I.getOperand(0).getReg(), *MIB.getInstr(), TII, + SPIRV::Decoration::SpecId, {SpecId}); + + return true; + } case Intrinsic::spv_const_composite: { // If no values are attached, the composite is null constant. bool IsNull = I.getNumExplicitDefs() + 1 == I.getNumExplicitOperands(); diff --git a/llvm/test/CodeGen/SPIRV/constant/spec-constant.ll b/llvm/test/CodeGen/SPIRV/constant/spec-constant.ll index 299d61d3bffde..5ca7a504addf7 100644 --- a/llvm/test/CodeGen/SPIRV/constant/spec-constant.ll +++ b/llvm/test/CodeGen/SPIRV/constant/spec-constant.ll @@ -8,6 +8,8 @@ ; CHECK-DAG: OpDecorate [[float_const:%[0-9]+]] SpecId 8 ; CHECK-DAG: OpDecorate [[double_const:%[0-9]+]] SpecId 9 ; CHECK-DAG: OpDecorate [[enum_const:%[0-9]+]] SpecId 10 +; CHECK-DAG: OpDecorate [[named_bool_const_true:%[0-9]+]] SpecId 11 +; CHECK-DAG: OpDecorate [[named_bool_const_false:%[0-9]+]] SpecId 12 ; CHECK-DAG: [[bool_const]] = OpSpecConstantTrue {{%[0-9]+}} ; CHECK-DAG: [[short_const]] = OpSpecConstant {{%[0-9]+}} 4 @@ -16,6 +18,8 @@ ; CHECK-DAG: [[float_const]] = OpSpecConstant {{%[0-9]+}} 1112014848 ; CHECK-DAG: [[double_const]] = OpSpecConstant {{%[0-9]+}} 0 1079574528 ; CHECK-DAG: [[enum_const]] = OpSpecConstant {{%[0-9]+}} 30 +; CHECK-DAG: [[named_bool_const_true:%[0-9]+]] = OpSpecConstantTrue {{%[0-9]+}} +; CHECK-DAG: [[named_bool_const_false:%[0-9]+]] = OpSpecConstantFalse {{%[0-9]+}} @_ZL10bool_const = internal addrspace(10) global i32 0, align 4 @_ZL11short_const = internal addrspace(10) global i16 0, align 2 @@ -58,6 +62,18 @@ entry: ; CHECK: OpStore {{%[0-9]+}} [[enum_const]] %18 = tail call spir_func i32 @_Z20__spirv_SpecConstantii(i32 10, i32 30) store i32 %18, ptr addrspace(10) @_ZL10enum_const, align 4 + + ; CHECK: [[bt:%[0-9]+]] = OpSelect {{%[0-9]+}} [[named_bool_const_true]] + ; CHECK: OpStore {{%[0-9]+}} [[bt]] + %19 = tail call spir_func i1 @llvm.spv.named.boolean.spec.constant(i32 11, i1 true, metadata !{}) + %zext_0 = zext i1 %19 to i32 + store i32 %zext_0, ptr addrspace(10) @_ZL10bool_const, align 4 + + ; CHECK: [[bf:%[0-9]+]] = OpSelect {{%[0-9]+}} [[named_bool_const_false]] + ; CHECK: OpStore {{%[0-9]+}} [[bf]] + %20 = tail call spir_func i1 @llvm.spv.named.boolean.spec.constant(i32 12, i1 false, metadata !{}) + %zext_1 = zext i1 %20 to i32 + store i32 %zext_1, ptr addrspace(10) @_ZL10bool_const, align 4 ret void } @@ -69,5 +85,8 @@ declare i32 @_Z20__spirv_SpecConstantii(i32, i32) declare i64 @_Z20__spirv_SpecConstantix(i32, i64) declare float @_Z20__spirv_SpecConstantif(i32, float) declare double @_Z20__spirv_SpecConstantid(i32, double) +declare i1 @llvm.spv.named.boolean.spec.constant(i32, i1, metadata) + +attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } -attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } \ No newline at end of file +!0 = !{ !"" } \ No newline at end of file >From 9544c96e85c5b7ff427f9b977ee8b704f8b81f93 Mon Sep 17 00:00:00 2001 From: Alex Voicu <[email protected]> Date: Thu, 19 Mar 2026 00:54:52 +0000 Subject: [PATCH 6/7] Fix formatting. --- llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp index c045ab693e9ab..88169df9ba61c 100644 --- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp @@ -4126,8 +4126,8 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg, return true; } case Intrinsic::spv_named_boolean_spec_constant: { - auto Opcode = I.getOperand(3).getImm() - ? SPIRV::OpSpecConstantTrue : SPIRV::OpSpecConstantFalse; + auto Opcode = I.getOperand(3).getImm() ? SPIRV::OpSpecConstantTrue + : SPIRV::OpSpecConstantFalse; auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(Opcode)) .addDef(I.getOperand(0).getReg()) >From aa1be1fb95eab1f854f3c2743f5d88bc7189ee6b Mon Sep 17 00:00:00 2001 From: Alex Voicu <[email protected]> Date: Tue, 14 Apr 2026 20:52:49 +0100 Subject: [PATCH 7/7] Define `__AMDGCN_UNSAFE_FP_ATOMICS__` for AMDGCN flavoured SPIR-V when required. --- clang/lib/Basic/Targets/SPIR.cpp | 3 +++ clang/test/Preprocessor/predefined-macros.c | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/clang/lib/Basic/Targets/SPIR.cpp b/clang/lib/Basic/Targets/SPIR.cpp index 19f160e279b21..7726c95cc7392 100644 --- a/clang/lib/Basic/Targets/SPIR.cpp +++ b/clang/lib/Basic/Targets/SPIR.cpp @@ -145,6 +145,9 @@ void SPIRV64AMDGCNTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__AMD__"); Builder.defineMacro("__AMDGPU__"); Builder.defineMacro("__AMDGCN__"); + + if (Opts.AtomicIgnoreDenormalMode) + Builder.defineMacro("__AMDGCN_UNSAFE_FP_ATOMICS__"); } void SPIRV64AMDGCNTargetInfo::setAuxTarget(const TargetInfo *Aux) { diff --git a/clang/test/Preprocessor/predefined-macros.c b/clang/test/Preprocessor/predefined-macros.c index da25b1efa3984..8dbb477be4c5d 100644 --- a/clang/test/Preprocessor/predefined-macros.c +++ b/clang/test/Preprocessor/predefined-macros.c @@ -240,14 +240,18 @@ // RUN: %clang_cc1 %s -E -dM -o - -x cl -triple spirv64-amd-amdhsa \ // RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-SPIRV64-AMDGCN +// RUN: %clang_cc1 %s -E -dM -o - -x cl -triple spirv64-amd-amdhsa -fatomic-ignore-denormal-mode \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-SPIRV64-AMDGCN-UNSAFE-FP-ATOMICS // CHECK-SPIRV64-AMDGCN-DAG: #define __IMAGE_SUPPORT__ 1 // CHECK-SPIRV64-AMDGCN-DAG: #define __SPIRV__ 1 // CHECK-SPIRV64-AMDGCN-DAG: #define __SPIRV64__ 1 // CHECK-SPIRV64-AMDGCN-DAG: #define __AMD__ 1 // CHECK-SPIRV64-AMDGCN-DAG: #define __AMDGCN__ 1 // CHECK-SPIRV64-AMDGCN-DAG: #define __AMDGPU__ 1 +// CHECK-SPIRV64-AMDGCN-NOT: #define __AMDGCN_UNSAFE_FP_ATOMICS__ // CHECK-SPIRV64-AMDGCN-NOT: #define __SPIRV32__ 1 // CHECK-SPIRV64-AMDGCN-NOT: #define __spirv__ 1 +// CHECK-SPIRV64-AMDGCN-UNSAFE-FP-ATOMICS: #define __AMDGCN_UNSAFE_FP_ATOMICS__ 1 // RUN: %clang_cc1 %s -E -dM -o - -x hip -triple x86_64-unknown-linux-gnu \ // RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-HIP _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
