https://github.com/V-FEXrt updated https://github.com/llvm/llvm-project/pull/115902
>From 845256b2ed971a4e42f7f871e8b51e711486261a Mon Sep 17 00:00:00 2001 From: Ashley Coleman <ascole...@microsoft.com> Date: Mon, 11 Nov 2024 16:34:23 -0700 Subject: [PATCH 01/11] [HLSL] Implement WaveActiveAnyTrue intrinsic --- clang/include/clang/Basic/Builtins.td | 6 +++++ clang/lib/CodeGen/CGBuiltin.cpp | 13 ++++++++++ clang/lib/CodeGen/CGHLSLRuntime.h | 1 + clang/lib/Headers/hlsl/hlsl_intrinsics.h | 9 +++++++ clang/lib/Sema/SemaHLSL.cpp | 6 +++++ .../builtins/WaveActiveAnyTrue.hlsl | 17 +++++++++++++ .../BuiltIns/WaveActiveAnyTrue-errors.hlsl | 21 ++++++++++++++++ llvm/include/llvm/IR/IntrinsicsDirectX.td | 1 + llvm/include/llvm/IR/IntrinsicsSPIRV.td | 1 + llvm/lib/Target/DirectX/DXIL.td | 10 ++++++++ .../Target/SPIRV/SPIRVInstructionSelector.cpp | 24 +++++++++++++++++++ .../test/CodeGen/DirectX/WaveActiveAnyTrue.ll | 10 ++++++++ .../hlsl-intrinsics/WaveActiveAnyTrue.ll | 17 +++++++++++++ 13 files changed, 136 insertions(+) create mode 100644 clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/WaveActiveAnyTrue-errors.hlsl create mode 100644 llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 9bd67e0cefebc3..496b6739724295 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4744,6 +4744,12 @@ def HLSLAny : LangBuiltin<"HLSL_LANG"> { let Prototype = "bool(...)"; } +def HLSLWaveActiveAnyTrue : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_wave_active_any_true"]; + let Attributes = [NoThrow, Const]; + let Prototype = "bool(bool)"; +} + def HLSLWaveActiveCountBits : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_wave_active_count_bits"]; let Attributes = [NoThrow, Const]; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 65d7f5c54a1913..c4a6a9abee63cc 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18960,6 +18960,19 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: { /*ReturnType=*/Op0->getType(), CGM.getHLSLRuntime().getStepIntrinsic(), ArrayRef<Value *>{Op0, Op1}, nullptr, "hlsl.step"); } + case Builtin::BI__builtin_hlsl_wave_active_any_true: { + // Assert Op->getType() == Bool + + // FIXME: PR Question: Can this be simpler? Looks like Int1Ty isn't predefined + IntegerType* Int1Ty = llvm::Type::getInt1Ty(CGM.getTypes().getLLVMContext()); + Value *Op = EmitScalarExpr(E->getArg(0)); + assert(Op->getType() == Int1Ty && "wave_active_any_true operand must be a bool"); + + // FIXME: PR Question: Re Style SingleRef vs {SingleRef} vs ArrayRef{SingleRef} + llvm::FunctionType *FT = llvm::FunctionType::get(Int1Ty, {Int1Ty}, /*isVarArg=*/false); + llvm::StringRef Name = Intrinsic::getName(CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic()); + return EmitRuntimeCall(CGM.CreateRuntimeFunction(FT, Name, {}, /*Local=*/false, /*AssumeConvergent=*/true), {Op}, "hlsl.wave.activeanytrue"); + } case Builtin::BI__builtin_hlsl_wave_get_lane_index: { // We don't define a SPIR-V intrinsic, instead it is a SPIR-V built-in // defined in SPIRVBuiltins.td. So instead we manually get the matching name diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h index cd533cad84e9fb..c3b689ea44fcb8 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -89,6 +89,7 @@ class CGHLSLRuntime { GENERATE_HLSL_INTRINSIC_FUNCTION(FDot, fdot) GENERATE_HLSL_INTRINSIC_FUNCTION(SDot, sdot) GENERATE_HLSL_INTRINSIC_FUNCTION(UDot, udot) + GENERATE_HLSL_INTRINSIC_FUNCTION(WaveActiveAnyTrue, wave_activeanytrue) GENERATE_HLSL_INTRINSIC_FUNCTION(WaveIsFirstLane, wave_is_first_lane) GENERATE_HLSL_INTRINSIC_FUNCTION(WaveReadLaneAt, wave_readlane) diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 8ade4b27f360fb..90991e95d6565a 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -2096,6 +2096,15 @@ float4 trunc(float4); // Wave* builtins //===----------------------------------------------------------------------===// +/// \brief Returns true if the expression is true in any active lane in the +/// current wave. +/// +/// \param Val The boolean expression to evaluate. +/// \return True if the expression is true in any lane. +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_any_true) +__attribute__((convergent)) bool WaveActiveAnyTrue(bool Val); + /// \brief Counts the number of boolean variables which evaluate to true across /// all active lanes in the current wave. /// diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index a472538236e2d9..e12a4ce1e75bd6 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -2066,6 +2066,12 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return true; break; } + case Builtin::BI__builtin_hlsl_wave_active_any_true: { + if (SemaRef.checkArgCount(TheCall, 1)) + return true; + + break; + } case Builtin::BI__builtin_hlsl_wave_read_lane_at: { if (SemaRef.checkArgCount(TheCall, 2)) return true; diff --git a/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl b/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl new file mode 100644 index 00000000000000..d8233c45e0ff2d --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -fnative-half-type -triple \ +// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -disable-llvm-passes -o - | \ +// RUN: FileCheck %s --check-prefixes=CHECK,CHECK-DXIL +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -fnative-half-type -triple \ +// RUN: spirv-pc-vulkan-compute %s -emit-llvm -disable-llvm-passes -o - | \ +// RUN: FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV + +// Test basic lowering to runtime function call for int values. + +// CHECK-LABEL: test +bool test(bool p1) { + // CHECK-SPIRV: %[[#entry_tok0:]] = call token @llvm.experimental.convergence.entry() + // CHECK-SPIRV: %[[RET:.*]] = call spir_func i1 @llvm.spv.wave.activeanytrue(i1 %{{[a-zA-Z0-9]+}}) [ "convergencectrl"(token %[[#entry_tok0]]) ] + // CHECK-DXIL: %[[RET:.*]] = call i1 @llvm.dx.wave.activeanytrue(i1 %{{[a-zA-Z0-9]+}}) + // CHECK: ret i1 %[[RET]] + return WaveActiveAnyTrue(p1); +} diff --git a/clang/test/SemaHLSL/BuiltIns/WaveActiveAnyTrue-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/WaveActiveAnyTrue-errors.hlsl new file mode 100644 index 00000000000000..48fda7b571fca7 --- /dev/null +++ b/clang/test/SemaHLSL/BuiltIns/WaveActiveAnyTrue-errors.hlsl @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -emit-llvm-only -disable-llvm-passes -verify + +bool test_too_few_arg() { + return __builtin_hlsl_wave_active_any_true(); + // expected-error@-1 {{too few arguments to function call, expected 1, have 0}} +} + +bool test_too_many_arg(bool p0) { + return __builtin_hlsl_wave_active_any_true(p0, p0); + // expected-error@-1 {{too many arguments to function call, expected 1, have 2}} +} + +struct Foo +{ + int a; +}; + +bool test_type_check_2(Foo p0) { + return __builtin_hlsl_wave_active_any_true(p0); + // expected-error@-1 {{no viable conversion from 'Foo' to 'bool'}} +} diff --git a/llvm/include/llvm/IR/IntrinsicsDirectX.td b/llvm/include/llvm/IR/IntrinsicsDirectX.td index e30d37f69f781e..7c21dc8f41f169 100644 --- a/llvm/include/llvm/IR/IntrinsicsDirectX.td +++ b/llvm/include/llvm/IR/IntrinsicsDirectX.td @@ -86,6 +86,7 @@ def int_dx_normalize : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ def int_dx_rsqrt : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>; def int_dx_wave_getlaneindex : DefaultAttrsIntrinsic<[llvm_i32_ty], [], [IntrConvergent, IntrNoMem]>; def int_dx_wave_is_first_lane : DefaultAttrsIntrinsic<[llvm_i1_ty], [], [IntrConvergent]>; +def int_dx_wave_activeanytrue : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_i1_ty], [IntrConvergent]>; def int_dx_wave_readlane : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>, llvm_i32_ty], [IntrConvergent, IntrNoMem]>; def int_dx_sign : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_any_ty], [IntrNoMem]>; def int_dx_step : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty, LLVMMatchType<0>], [IntrNoMem]>; diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td index 6df2eb156a0774..c5e93aa4cfe01d 100644 --- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td +++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td @@ -85,6 +85,7 @@ let TargetPrefix = "spv" in { [IntrNoMem, Commutative] >; def int_spv_wave_is_first_lane : DefaultAttrsIntrinsic<[llvm_i1_ty], [], [IntrConvergent]>; def int_spv_wave_readlane : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>, llvm_i32_ty], [IntrConvergent, IntrNoMem]>; + def int_spv_wave_activeanytrue : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_i1_ty], [IntrConvergent]>; def int_spv_sign : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_any_ty], [IntrNoMem]>; def int_spv_radians : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty], [IntrNoMem]>; diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td index 68ae5de06423c2..9657d249f9170a 100644 --- a/llvm/lib/Target/DirectX/DXIL.td +++ b/llvm/lib/Target/DirectX/DXIL.td @@ -202,6 +202,7 @@ defset list<DXILOpClass> OpClasses = { def unpack4x8 : DXILOpClass; def viewID : DXILOpClass; def waveActiveAllEqual : DXILOpClass; + def waveActiveAnyTrue : DXILOpClass; def waveActiveBallot : DXILOpClass; def waveActiveBit : DXILOpClass; def waveActiveOp : DXILOpClass; @@ -803,6 +804,15 @@ def CreateHandleFromBinding : DXILOp<218, createHandleFromBinding> { let stages = [Stages<DXIL1_6, [all_stages]>]; } +def WaveActiveAnyTrue : DXILOp<113, waveActiveAnyTrue> { + let Doc = "returns true if the expression is true in any of the active lanes in the current wave"; + let LLVMIntrinsic = int_dx_wave_activeanytrue; + let arguments = [Int1Ty]; + let result = Int1Ty; + let stages = [Stages<DXIL1_0, [all_stages]>]; + let attributes = [Attributes<DXIL1_0, [ReadNone]>]; +} + def WaveIsFirstLane : DXILOp<110, waveIsFirstLane> { let Doc = "returns 1 for the first lane in the wave"; let LLVMIntrinsic = int_dx_wave_is_first_lane; diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp index d9377fe4b91a1a..8d4faedd1c6210 100644 --- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp @@ -230,6 +230,9 @@ class SPIRVInstructionSelector : public InstructionSelector { bool selectSpvThreadId(Register ResVReg, const SPIRVType *ResType, MachineInstr &I) const; + bool selectWaveActiveAnyTrue(Register ResVReg, const SPIRVType *ResType, + MachineInstr &I) const; + bool selectWaveReadLaneAt(Register ResVReg, const SPIRVType *ResType, MachineInstr &I) const; @@ -1762,6 +1765,25 @@ bool SPIRVInstructionSelector::selectSign(Register ResVReg, return Result; } +bool SPIRVInstructionSelector::selectWaveActiveAnyTrue(Register ResVReg, + const SPIRVType *ResType, + MachineInstr &I) const { + assert(I.getNumOperands() == 3); + assert(I.getOperand(2).isReg()); + + // IntTy is used to define the execution scope, set to 3 to denote a + // cross-lane interaction equivalent to a SPIR-V subgroup. + MachineBasicBlock &BB = *I.getParent(); + SPIRVType *IntTy = GR.getOrCreateSPIRVIntegerType(32, I, TII); + + return BuildMI(BB, I, I.getDebugLoc(), + TII.get(SPIRV::OpGroupNonUniformAny)) + .addDef(ResVReg) + .addUse(GR.getSPIRVTypeID(ResType)) + .addUse(GR.getOrCreateConstInt(3, I, IntTy, TII)) + .addUse(I.getOperand(2).getReg()); +} + bool SPIRVInstructionSelector::selectWaveReadLaneAt(Register ResVReg, const SPIRVType *ResType, MachineInstr &I) const { @@ -2567,6 +2589,8 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg, .addUse(GR.getSPIRVTypeID(ResType)) .addUse(GR.getOrCreateConstInt(3, I, IntTy, TII)); } + case Intrinsic::spv_wave_activeanytrue: + return selectWaveActiveAnyTrue(ResVReg, ResType, I); case Intrinsic::spv_wave_readlane: return selectWaveReadLaneAt(ResVReg, ResType, I); case Intrinsic::spv_step: diff --git a/llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll b/llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll new file mode 100644 index 00000000000000..cc97eb2eedcd60 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll @@ -0,0 +1,10 @@ +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-compute %s | FileCheck %s + +define noundef i1 @wave_aat_simple(i1 noundef %p1) { +entry: +; CHECK: call i1 @dx.op.waveActiveAnyTrue(i32 113, i1 %p1) + %ret = call i1 @llvm.dx.wave.activeanytrue(i1 %p1) + ret i1 %ret +} + +declare i1 @llvm.dx.wave.activeanytrue(i1) diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll new file mode 100644 index 00000000000000..8b56b60f1da4da --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll @@ -0,0 +1,17 @@ +; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32v1.3-vulkan-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32v1.3-vulkan-unknown %s -o - -filetype=obj | spirv-val %} + +; CHECK: %[[#bool:]] = OpTypeBool +; CHECK: %[[#uint:]] = OpTypeInt 32 0 +; CHECK: %[[#scope:]] = OpConstant %[[#uint]] 3 + +; CHECK-LABEL: Begin function test_wave_aat +define i1 @test_wave_aat(i1 %p1) { +entry: +; CHECK: %[[#param:]] = OpFunctionParameter %[[#bool]] +; CHECK: %[[#ret:]] = OpGroupNonUniformAny %[[#bool]] %[[#scope]] %[[#param]] + %ret = call i1 @llvm.spv.wave.activeanytrue(i1 %p1) + ret i1 %ret +} + +declare i1 @llvm.spv.wave.activeanytrue(i1) >From 3b63a3a3135026114ca25143484a7d0187cbc020 Mon Sep 17 00:00:00 2001 From: Ashley Coleman <ascole...@microsoft.com> Date: Tue, 12 Nov 2024 09:38:34 -0700 Subject: [PATCH 02/11] formatting --- clang/lib/CodeGen/CGBuiltin.cpp | 25 +++++++++++++------ clang/lib/Sema/SemaHLSL.cpp | 6 ++--- .../Target/SPIRV/SPIRVInstructionSelector.cpp | 7 +++--- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index c4a6a9abee63cc..23b89c446213da 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18963,15 +18963,24 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: { case Builtin::BI__builtin_hlsl_wave_active_any_true: { // Assert Op->getType() == Bool - // FIXME: PR Question: Can this be simpler? Looks like Int1Ty isn't predefined - IntegerType* Int1Ty = llvm::Type::getInt1Ty(CGM.getTypes().getLLVMContext()); + // FIXME: PR Question: Can this be simpler? Looks like Int1Ty isn't + // predefined + IntegerType *Int1Ty = + llvm::Type::getInt1Ty(CGM.getTypes().getLLVMContext()); Value *Op = EmitScalarExpr(E->getArg(0)); - assert(Op->getType() == Int1Ty && "wave_active_any_true operand must be a bool"); - - // FIXME: PR Question: Re Style SingleRef vs {SingleRef} vs ArrayRef{SingleRef} - llvm::FunctionType *FT = llvm::FunctionType::get(Int1Ty, {Int1Ty}, /*isVarArg=*/false); - llvm::StringRef Name = Intrinsic::getName(CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic()); - return EmitRuntimeCall(CGM.CreateRuntimeFunction(FT, Name, {}, /*Local=*/false, /*AssumeConvergent=*/true), {Op}, "hlsl.wave.activeanytrue"); + assert(Op->getType() == Int1Ty && + "wave_active_any_true operand must be a bool"); + + // FIXME: PR Question: Re Style SingleRef vs {SingleRef} vs + // ArrayRef{SingleRef} + llvm::FunctionType *FT = + llvm::FunctionType::get(Int1Ty, {Int1Ty}, /*isVarArg=*/false); + llvm::StringRef Name = Intrinsic::getName( + CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic()); + return EmitRuntimeCall(CGM.CreateRuntimeFunction(FT, Name, {}, + /*Local=*/false, + /*AssumeConvergent=*/true), + {Op}, "hlsl.wave.activeanytrue"); } case Builtin::BI__builtin_hlsl_wave_get_lane_index: { // We don't define a SPIR-V intrinsic, instead it is a SPIR-V built-in diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index e12a4ce1e75bd6..0377f46dcf1991 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -2067,10 +2067,10 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { break; } case Builtin::BI__builtin_hlsl_wave_active_any_true: { - if (SemaRef.checkArgCount(TheCall, 1)) - return true; + if (SemaRef.checkArgCount(TheCall, 1)) + return true; - break; + break; } case Builtin::BI__builtin_hlsl_wave_read_lane_at: { if (SemaRef.checkArgCount(TheCall, 2)) diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp index 8d4faedd1c6210..47538da068ec0a 100644 --- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp @@ -1766,8 +1766,8 @@ bool SPIRVInstructionSelector::selectSign(Register ResVReg, } bool SPIRVInstructionSelector::selectWaveActiveAnyTrue(Register ResVReg, - const SPIRVType *ResType, - MachineInstr &I) const { + const SPIRVType *ResType, + MachineInstr &I) const { assert(I.getNumOperands() == 3); assert(I.getOperand(2).isReg()); @@ -1776,8 +1776,7 @@ bool SPIRVInstructionSelector::selectWaveActiveAnyTrue(Register ResVReg, MachineBasicBlock &BB = *I.getParent(); SPIRVType *IntTy = GR.getOrCreateSPIRVIntegerType(32, I, TII); - return BuildMI(BB, I, I.getDebugLoc(), - TII.get(SPIRV::OpGroupNonUniformAny)) + return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpGroupNonUniformAny)) .addDef(ResVReg) .addUse(GR.getSPIRVTypeID(ResType)) .addUse(GR.getOrCreateConstInt(3, I, IntTy, TII)) >From 37fbd29b7032de3172cf4e372ab0e4674ee76e96 Mon Sep 17 00:00:00 2001 From: Ashley Coleman <ascole...@microsoft.com> Date: Tue, 12 Nov 2024 09:41:29 -0700 Subject: [PATCH 03/11] cleanup --- clang/lib/CodeGen/CGBuiltin.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 23b89c446213da..cc1995cd2382c8 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18961,18 +18961,12 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: { ArrayRef<Value *>{Op0, Op1}, nullptr, "hlsl.step"); } case Builtin::BI__builtin_hlsl_wave_active_any_true: { - // Assert Op->getType() == Bool - - // FIXME: PR Question: Can this be simpler? Looks like Int1Ty isn't - // predefined IntegerType *Int1Ty = llvm::Type::getInt1Ty(CGM.getTypes().getLLVMContext()); Value *Op = EmitScalarExpr(E->getArg(0)); assert(Op->getType() == Int1Ty && "wave_active_any_true operand must be a bool"); - // FIXME: PR Question: Re Style SingleRef vs {SingleRef} vs - // ArrayRef{SingleRef} llvm::FunctionType *FT = llvm::FunctionType::get(Int1Ty, {Int1Ty}, /*isVarArg=*/false); llvm::StringRef Name = Intrinsic::getName( >From fcd1949d0e82d39c2808700bbd3b0ecd0bdc199d Mon Sep 17 00:00:00 2001 From: Ashley Coleman <ascole...@microsoft.com> Date: Tue, 12 Nov 2024 16:47:38 -0700 Subject: [PATCH 04/11] Address comments --- clang/lib/CodeGen/CGBuiltin.cpp | 9 ++++----- clang/lib/Sema/SemaHLSL.cpp | 6 ------ clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl | 4 ++-- llvm/lib/Target/DirectX/DXIL.td | 3 +-- llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp | 6 ++---- llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll | 2 +- .../CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll | 4 ++-- 7 files changed, 12 insertions(+), 22 deletions(-) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 88960bffe0bee7..b2261f650616d3 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -19109,20 +19109,19 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: { ArrayRef<Value *>{Op0, Op1}, nullptr, "hlsl.step"); } case Builtin::BI__builtin_hlsl_wave_active_any_true: { - IntegerType *Int1Ty = - llvm::Type::getInt1Ty(CGM.getTypes().getLLVMContext()); Value *Op = EmitScalarExpr(E->getArg(0)); - assert(Op->getType() == Int1Ty && - "wave_active_any_true operand must be a bool"); + llvm::Type *Ty = Op->getType(); + assert(Ty->isIntegerTy(1) && "wave_active_any_true operand must be a bool"); llvm::FunctionType *FT = - llvm::FunctionType::get(Int1Ty, {Int1Ty}, /*isVarArg=*/false); + llvm::FunctionType::get(Ty, {Ty}, /*isVarArg=*/false); llvm::StringRef Name = Intrinsic::getName( CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic()); return EmitRuntimeCall(CGM.CreateRuntimeFunction(FT, Name, {}, /*Local=*/false, /*AssumeConvergent=*/true), {Op}, "hlsl.wave.activeanytrue"); + } case Builtin::BI__builtin_hlsl_wave_active_count_bits: { Value *OpExpr = EmitScalarExpr(E->getArg(0)); Intrinsic::ID ID = CGM.getHLSLRuntime().getWaveActiveCountBitsIntrinsic(); diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 8aa0b7520b05eb..65b0d9cd65637f 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -2091,12 +2091,6 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return true; break; } - case Builtin::BI__builtin_hlsl_wave_active_any_true: { - if (SemaRef.checkArgCount(TheCall, 1)) - return true; - - break; - } case Builtin::BI__builtin_hlsl_wave_read_lane_at: { if (SemaRef.checkArgCount(TheCall, 2)) return true; diff --git a/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl b/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl index d8233c45e0ff2d..dd7a9dee5c3f1e 100644 --- a/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl +++ b/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -fnative-half-type -triple \ +// RUN: %clang_cc1 -finclude-default-header -fnative-half-type -triple \ // RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -disable-llvm-passes -o - | \ // RUN: FileCheck %s --check-prefixes=CHECK,CHECK-DXIL -// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -fnative-half-type -triple \ +// RUN: %clang_cc1 -finclude-default-header -fnative-half-type -triple \ // RUN: spirv-pc-vulkan-compute %s -emit-llvm -disable-llvm-passes -o - | \ // RUN: FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td index 9b5e2b5ce1e92a..cb0a0a17492bb5 100644 --- a/llvm/lib/Target/DirectX/DXIL.td +++ b/llvm/lib/Target/DirectX/DXIL.td @@ -202,7 +202,6 @@ defset list<DXILOpClass> OpClasses = { def unpack4x8 : DXILOpClass; def viewID : DXILOpClass; def waveActiveAllEqual : DXILOpClass; - def waveActiveAnyTrue : DXILOpClass; def waveActiveBallot : DXILOpClass; def waveActiveBit : DXILOpClass; def waveActiveOp : DXILOpClass; @@ -854,7 +853,7 @@ def CreateHandleFromBinding : DXILOp<217, createHandleFromBinding> { let stages = [Stages<DXIL1_6, [all_stages]>]; } -def WaveActiveAnyTrue : DXILOp<113, waveActiveAnyTrue> { +def WaveActiveAnyTrue : DXILOp<113, waveAnyTrue> { let Doc = "returns true if the expression is true in any of the active lanes in the current wave"; let LLVMIntrinsic = int_dx_wave_activeanytrue; let arguments = [Int1Ty]; diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp index 728880a855f1c5..98735c2582ffa2 100644 --- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp @@ -1929,15 +1929,13 @@ bool SPIRVInstructionSelector::selectWaveActiveAnyTrue(Register ResVReg, assert(I.getNumOperands() == 3); assert(I.getOperand(2).isReg()); - // IntTy is used to define the execution scope, set to 3 to denote a - // cross-lane interaction equivalent to a SPIR-V subgroup. MachineBasicBlock &BB = *I.getParent(); SPIRVType *IntTy = GR.getOrCreateSPIRVIntegerType(32, I, TII); return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpGroupNonUniformAny)) .addDef(ResVReg) .addUse(GR.getSPIRVTypeID(ResType)) - .addUse(GR.getOrCreateConstInt(3, I, IntTy, TII)) + .addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy, TII)) .addUse(I.getOperand(2).getReg()); } @@ -1987,7 +1985,7 @@ bool SPIRVInstructionSelector::selectWaveReadLaneAt(Register ResVReg, TII.get(SPIRV::OpGroupNonUniformShuffle)) .addDef(ResVReg) .addUse(GR.getSPIRVTypeID(ResType)) - .addUse(GR.getOrCreateConstInt(3, I, IntTy, TII)) + .addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy, TII)) .addUse(I.getOperand(2).getReg()) .addUse(I.getOperand(3).getReg()); } diff --git a/llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll b/llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll index cc97eb2eedcd60..8f7ae9ea7b370b 100644 --- a/llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll +++ b/llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll @@ -2,7 +2,7 @@ define noundef i1 @wave_aat_simple(i1 noundef %p1) { entry: -; CHECK: call i1 @dx.op.waveActiveAnyTrue(i32 113, i1 %p1) +; CHECK: call i1 @dx.op.waveAnyTrue(i32 113, i1 %p1) %ret = call i1 @llvm.dx.wave.activeanytrue(i1 %p1) ret i1 %ret } diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll index 8b56b60f1da4da..25d195a776ab73 100644 --- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll +++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll @@ -1,5 +1,5 @@ -; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32v1.3-vulkan-unknown %s -o - | FileCheck %s -; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32v1.3-vulkan-unknown %s -o - -filetype=obj | spirv-val %} +; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32v1.5-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32v1.5-unknown-unknown %s -o - -filetype=obj | spirv-val %} ; CHECK: %[[#bool:]] = OpTypeBool ; CHECK: %[[#uint:]] = OpTypeInt 32 0 >From dd6eff10aa8ec763edbfecb484a3130b4d8704e1 Mon Sep 17 00:00:00 2001 From: Ashley Coleman <ascole...@microsoft.com> Date: Wed, 13 Nov 2024 10:02:03 -0700 Subject: [PATCH 05/11] Address comments --- clang/lib/CodeGen/CGBuiltin.cpp | 11 +++-------- .../test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl | 1 + .../SemaHLSL/BuiltIns/WaveActiveAnyTrue-errors.hlsl | 2 +- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index b2261f650616d3..ddff01acb134a0 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -19113,14 +19113,9 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: { llvm::Type *Ty = Op->getType(); assert(Ty->isIntegerTy(1) && "wave_active_any_true operand must be a bool"); - llvm::FunctionType *FT = - llvm::FunctionType::get(Ty, {Ty}, /*isVarArg=*/false); - llvm::StringRef Name = Intrinsic::getName( - CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic()); - return EmitRuntimeCall(CGM.CreateRuntimeFunction(FT, Name, {}, - /*Local=*/false, - /*AssumeConvergent=*/true), - {Op}, "hlsl.wave.activeanytrue"); + Intrinsic::ID ID = CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic(); + return EmitRuntimeCall( + Intrinsic::getOrInsertDeclaration(&CGM.getModule(), ID), {Op}); } case Builtin::BI__builtin_hlsl_wave_active_count_bits: { Value *OpExpr = EmitScalarExpr(E->getArg(0)); diff --git a/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl b/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl index dd7a9dee5c3f1e..c8dc45aa396dec 100644 --- a/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl +++ b/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl @@ -13,5 +13,6 @@ bool test(bool p1) { // CHECK-SPIRV: %[[RET:.*]] = call spir_func i1 @llvm.spv.wave.activeanytrue(i1 %{{[a-zA-Z0-9]+}}) [ "convergencectrl"(token %[[#entry_tok0]]) ] // CHECK-DXIL: %[[RET:.*]] = call i1 @llvm.dx.wave.activeanytrue(i1 %{{[a-zA-Z0-9]+}}) // CHECK: ret i1 %[[RET]] + // CHECK: fex return WaveActiveAnyTrue(p1); } diff --git a/clang/test/SemaHLSL/BuiltIns/WaveActiveAnyTrue-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/WaveActiveAnyTrue-errors.hlsl index 48fda7b571fca7..875aae06517020 100644 --- a/clang/test/SemaHLSL/BuiltIns/WaveActiveAnyTrue-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/WaveActiveAnyTrue-errors.hlsl @@ -15,7 +15,7 @@ struct Foo int a; }; -bool test_type_check_2(Foo p0) { +bool test_type_check(Foo p0) { return __builtin_hlsl_wave_active_any_true(p0); // expected-error@-1 {{no viable conversion from 'Foo' to 'bool'}} } >From 9c43edfa9ea48383748d3e919f37f7337e048465 Mon Sep 17 00:00:00 2001 From: Ashley Coleman <ascole...@microsoft.com> Date: Wed, 13 Nov 2024 10:09:52 -0700 Subject: [PATCH 06/11] cleanup --- clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl | 1 - 1 file changed, 1 deletion(-) diff --git a/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl b/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl index c8dc45aa396dec..dd7a9dee5c3f1e 100644 --- a/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl +++ b/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl @@ -13,6 +13,5 @@ bool test(bool p1) { // CHECK-SPIRV: %[[RET:.*]] = call spir_func i1 @llvm.spv.wave.activeanytrue(i1 %{{[a-zA-Z0-9]+}}) [ "convergencectrl"(token %[[#entry_tok0]]) ] // CHECK-DXIL: %[[RET:.*]] = call i1 @llvm.dx.wave.activeanytrue(i1 %{{[a-zA-Z0-9]+}}) // CHECK: ret i1 %[[RET]] - // CHECK: fex return WaveActiveAnyTrue(p1); } >From 7823ce6bc12b7ab88e4d64608b3c27129d6d01aa Mon Sep 17 00:00:00 2001 From: Ashley Coleman <ascole...@microsoft.com> Date: Thu, 14 Nov 2024 14:59:36 -0700 Subject: [PATCH 07/11] Rename intrinsic --- clang/lib/CodeGen/CGHLSLRuntime.h | 2 +- clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl | 4 ++-- llvm/include/llvm/IR/IntrinsicsDirectX.td | 2 +- llvm/include/llvm/IR/IntrinsicsSPIRV.td | 2 +- llvm/lib/Target/DirectX/DXIL.td | 2 +- llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp | 4 ++-- llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll | 6 +++--- .../CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll | 8 ++++---- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h index e8413a5baa32e9..a8e0ed42b79a35 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -91,7 +91,7 @@ class CGHLSLRuntime { GENERATE_HLSL_INTRINSIC_FUNCTION(UDot, udot) GENERATE_HLSL_INTRINSIC_FUNCTION(Dot4AddI8Packed, dot4add_i8packed) GENERATE_HLSL_INTRINSIC_FUNCTION(Dot4AddU8Packed, dot4add_u8packed) - GENERATE_HLSL_INTRINSIC_FUNCTION(WaveActiveAnyTrue, wave_activeanytrue) + GENERATE_HLSL_INTRINSIC_FUNCTION(WaveActiveAnyTrue, wave_any) GENERATE_HLSL_INTRINSIC_FUNCTION(WaveActiveCountBits, wave_active_countbits) GENERATE_HLSL_INTRINSIC_FUNCTION(WaveIsFirstLane, wave_is_first_lane) GENERATE_HLSL_INTRINSIC_FUNCTION(WaveReadLaneAt, wave_readlane) diff --git a/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl b/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl index dd7a9dee5c3f1e..d657a3f8357b08 100644 --- a/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl +++ b/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl @@ -10,8 +10,8 @@ // CHECK-LABEL: test bool test(bool p1) { // CHECK-SPIRV: %[[#entry_tok0:]] = call token @llvm.experimental.convergence.entry() - // CHECK-SPIRV: %[[RET:.*]] = call spir_func i1 @llvm.spv.wave.activeanytrue(i1 %{{[a-zA-Z0-9]+}}) [ "convergencectrl"(token %[[#entry_tok0]]) ] - // CHECK-DXIL: %[[RET:.*]] = call i1 @llvm.dx.wave.activeanytrue(i1 %{{[a-zA-Z0-9]+}}) + // CHECK-SPIRV: %[[RET:.*]] = call spir_func i1 @llvm.spv.wave.any(i1 %{{[a-zA-Z0-9]+}}) [ "convergencectrl"(token %[[#entry_tok0]]) ] + // CHECK-DXIL: %[[RET:.*]] = call i1 @llvm.dx.wave.any(i1 %{{[a-zA-Z0-9]+}}) // CHECK: ret i1 %[[RET]] return WaveActiveAnyTrue(p1); } diff --git a/llvm/include/llvm/IR/IntrinsicsDirectX.td b/llvm/include/llvm/IR/IntrinsicsDirectX.td index 8ed81e9852c863..58e5f44789c9cf 100644 --- a/llvm/include/llvm/IR/IntrinsicsDirectX.td +++ b/llvm/include/llvm/IR/IntrinsicsDirectX.td @@ -91,9 +91,9 @@ def int_dx_umad : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLV def int_dx_normalize : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty], [IntrNoMem]>; def int_dx_rsqrt : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>; def int_dx_wave_active_countbits : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i1_ty], [IntrConvergent, IntrNoMem]>; +def int_dx_wave_any : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_i1_ty], [IntrConvergent]>; def int_dx_wave_getlaneindex : DefaultAttrsIntrinsic<[llvm_i32_ty], [], [IntrConvergent, IntrNoMem]>; def int_dx_wave_is_first_lane : DefaultAttrsIntrinsic<[llvm_i1_ty], [], [IntrConvergent]>; -def int_dx_wave_activeanytrue : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_i1_ty], [IntrConvergent]>; def int_dx_wave_readlane : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>, llvm_i32_ty], [IntrConvergent, IntrNoMem]>; def int_dx_sign : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_any_ty], [IntrNoMem]>; def int_dx_step : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty, LLVMMatchType<0>], [IntrNoMem]>; diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td index 02f9acc3401555..8dfdcf01e0d757 100644 --- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td +++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td @@ -86,9 +86,9 @@ let TargetPrefix = "spv" in { def int_spv_dot4add_i8packed : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; def int_spv_dot4add_u8packed : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; def int_spv_wave_active_countbits : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i1_ty], [IntrConvergent, IntrNoMem]>; + def int_spv_wave_any : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_i1_ty], [IntrConvergent]>; def int_spv_wave_is_first_lane : DefaultAttrsIntrinsic<[llvm_i1_ty], [], [IntrConvergent]>; def int_spv_wave_readlane : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>, llvm_i32_ty], [IntrConvergent, IntrNoMem]>; - def int_spv_wave_activeanytrue : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_i1_ty], [IntrConvergent]>; def int_spv_sign : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_any_ty], [IntrNoMem]>; def int_spv_radians : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty], [IntrNoMem]>; def int_spv_group_memory_barrier_with_group_sync : DefaultAttrsIntrinsic<[], [], []>; diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td index cb0a0a17492bb5..04fee894a46b06 100644 --- a/llvm/lib/Target/DirectX/DXIL.td +++ b/llvm/lib/Target/DirectX/DXIL.td @@ -855,7 +855,7 @@ def CreateHandleFromBinding : DXILOp<217, createHandleFromBinding> { def WaveActiveAnyTrue : DXILOp<113, waveAnyTrue> { let Doc = "returns true if the expression is true in any of the active lanes in the current wave"; - let LLVMIntrinsic = int_dx_wave_activeanytrue; + let LLVMIntrinsic = int_dx_wave_any; let arguments = [Int1Ty]; let result = Int1Ty; let stages = [Stages<DXIL1_0, [all_stages]>]; diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp index 98735c2582ffa2..23ba5f4b3282ef 100644 --- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp @@ -2800,6 +2800,8 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg, return selectExtInst(ResVReg, ResType, I, CL::s_clamp, GL::SClamp); case Intrinsic::spv_wave_active_countbits: return selectWaveActiveCountBits(ResVReg, ResType, I); + case Intrinsic::spv_wave_any: + return selectWaveActiveAnyTrue(ResVReg, ResType, I); case Intrinsic::spv_wave_is_first_lane: { SPIRVType *IntTy = GR.getOrCreateSPIRVIntegerType(32, I, TII); return BuildMI(BB, I, I.getDebugLoc(), @@ -2808,8 +2810,6 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg, .addUse(GR.getSPIRVTypeID(ResType)) .addUse(GR.getOrCreateConstInt(3, I, IntTy, TII)); } - case Intrinsic::spv_wave_activeanytrue: - return selectWaveActiveAnyTrue(ResVReg, ResType, I); case Intrinsic::spv_wave_readlane: return selectWaveReadLaneAt(ResVReg, ResType, I); case Intrinsic::spv_step: diff --git a/llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll b/llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll index 8f7ae9ea7b370b..5adf050a76c98f 100644 --- a/llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll +++ b/llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll @@ -1,10 +1,10 @@ ; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-compute %s | FileCheck %s -define noundef i1 @wave_aat_simple(i1 noundef %p1) { +define noundef i1 @wave_any_simple(i1 noundef %p1) { entry: ; CHECK: call i1 @dx.op.waveAnyTrue(i32 113, i1 %p1) - %ret = call i1 @llvm.dx.wave.activeanytrue(i1 %p1) + %ret = call i1 @llvm.dx.wave.any(i1 %p1) ret i1 %ret } -declare i1 @llvm.dx.wave.activeanytrue(i1) +declare i1 @llvm.dx.wave.any(i1) diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll index 25d195a776ab73..39418bd35ff4c3 100644 --- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll +++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll @@ -5,13 +5,13 @@ ; CHECK: %[[#uint:]] = OpTypeInt 32 0 ; CHECK: %[[#scope:]] = OpConstant %[[#uint]] 3 -; CHECK-LABEL: Begin function test_wave_aat -define i1 @test_wave_aat(i1 %p1) { +; CHECK-LABEL: Begin function test_wave_any +define i1 @test_wave_any(i1 %p1) { entry: ; CHECK: %[[#param:]] = OpFunctionParameter %[[#bool]] ; CHECK: %[[#ret:]] = OpGroupNonUniformAny %[[#bool]] %[[#scope]] %[[#param]] - %ret = call i1 @llvm.spv.wave.activeanytrue(i1 %p1) + %ret = call i1 @llvm.spv.wave.any(i1 %p1) ret i1 %ret } -declare i1 @llvm.spv.wave.activeanytrue(i1) +declare i1 @llvm.spv.wave.any(i1) >From dfeb3276bf4b67022e4b39919a8a2e8e353c9777 Mon Sep 17 00:00:00 2001 From: Ashley Coleman <ascole...@microsoft.com> Date: Thu, 14 Nov 2024 15:40:25 -0700 Subject: [PATCH 08/11] address comments --- llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp | 4 +++- llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp index e8641b3a105dec..17912a398b982f 100644 --- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp @@ -630,6 +630,9 @@ void RequirementHandler::initAvailableCapabilities(const SPIRVSubtarget &ST) { addAvailableCaps({Capability::Shader, Capability::Linkage, Capability::Int8, Capability::Int16}); + if (ST.isAtLeastSPIRVVer(VersionTuple(1, 3))) + addAvailableCaps({Capability::GroupNonUniformVote}); + if (ST.isAtLeastSPIRVVer(VersionTuple(1, 6))) addAvailableCaps({Capability::DotProduct, Capability::DotProductInputAll, Capability::DotProductInput4x8Bit, @@ -675,7 +678,6 @@ void RequirementHandler::initAvailableCapabilitiesForOpenCL( addAvailableCaps({Capability::SubgroupDispatch, Capability::PipeStorage}); if (ST.isAtLeastSPIRVVer(VersionTuple(1, 3))) addAvailableCaps({Capability::GroupNonUniform, - Capability::GroupNonUniformVote, Capability::GroupNonUniformArithmetic, Capability::GroupNonUniformBallot, Capability::GroupNonUniformClustered, diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll index 39418bd35ff4c3..66bc9619fb74f9 100644 --- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll +++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll @@ -1,5 +1,5 @@ -; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32v1.5-unknown-unknown %s -o - | FileCheck %s -; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32v1.5-unknown-unknown %s -o - -filetype=obj | spirv-val %} +; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %} ; CHECK: %[[#bool:]] = OpTypeBool ; CHECK: %[[#uint:]] = OpTypeInt 32 0 >From 66848d80e6da2e433bdc332562c862ef1bf4e3e7 Mon Sep 17 00:00:00 2001 From: Ashley Coleman <m...@ashleycoleman.me> Date: Thu, 14 Nov 2024 16:44:57 -0700 Subject: [PATCH 09/11] Apply suggestions from code review Co-authored-by: Finn Plummer <50529406+inbe...@users.noreply.github.com> --- clang/lib/CodeGen/CGBuiltin.cpp | 2 +- llvm/include/llvm/IR/IntrinsicsDirectX.td | 2 +- llvm/include/llvm/IR/IntrinsicsSPIRV.td | 2 +- llvm/lib/Target/DirectX/DXIL.td | 1 - 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 0602bcf85e5574..af03d477f13509 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -19123,7 +19123,7 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: { case Builtin::BI__builtin_hlsl_wave_active_any_true: { Value *Op = EmitScalarExpr(E->getArg(0)); llvm::Type *Ty = Op->getType(); - assert(Ty->isIntegerTy(1) && "wave_active_any_true operand must be a bool"); + assert(Ty->isIntegerTy(1) && "Intrinsic WaveActiveAnyTrue operand must be a bool"); Intrinsic::ID ID = CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic(); return EmitRuntimeCall( diff --git a/llvm/include/llvm/IR/IntrinsicsDirectX.td b/llvm/include/llvm/IR/IntrinsicsDirectX.td index 52f3845ecba6df..a5fe1e55f5cc13 100644 --- a/llvm/include/llvm/IR/IntrinsicsDirectX.td +++ b/llvm/include/llvm/IR/IntrinsicsDirectX.td @@ -94,7 +94,7 @@ def int_dx_umad : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLV def int_dx_normalize : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty], [IntrNoMem]>; def int_dx_rsqrt : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>; def int_dx_wave_active_countbits : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i1_ty], [IntrConvergent, IntrNoMem]>; -def int_dx_wave_any : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_i1_ty], [IntrConvergent]>; +def int_dx_wave_any : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_i1_ty], [IntrConvergent, IntrNoMem]>; def int_dx_wave_getlaneindex : DefaultAttrsIntrinsic<[llvm_i32_ty], [], [IntrConvergent, IntrNoMem]>; def int_dx_wave_is_first_lane : DefaultAttrsIntrinsic<[llvm_i1_ty], [], [IntrConvergent]>; def int_dx_wave_readlane : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>, llvm_i32_ty], [IntrConvergent, IntrNoMem]>; diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td index 9af8ae70646283..28db6fd8117790 100644 --- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td +++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td @@ -86,7 +86,7 @@ let TargetPrefix = "spv" in { def int_spv_dot4add_i8packed : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; def int_spv_dot4add_u8packed : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; def int_spv_wave_active_countbits : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i1_ty], [IntrConvergent, IntrNoMem]>; - def int_spv_wave_any : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_i1_ty], [IntrConvergent]>; + def int_spv_wave_any : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_i1_ty], [IntrConvergent, IntrNoMem]>; def int_spv_wave_is_first_lane : DefaultAttrsIntrinsic<[llvm_i1_ty], [], [IntrConvergent]>; def int_spv_wave_readlane : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>, llvm_i32_ty], [IntrConvergent, IntrNoMem]>; def int_spv_sign : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_any_ty], [IntrNoMem]>; diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td index 5c1891e855d977..2a499b1d9b75c0 100644 --- a/llvm/lib/Target/DirectX/DXIL.td +++ b/llvm/lib/Target/DirectX/DXIL.td @@ -859,7 +859,6 @@ def WaveActiveAnyTrue : DXILOp<113, waveAnyTrue> { let arguments = [Int1Ty]; let result = Int1Ty; let stages = [Stages<DXIL1_0, [all_stages]>]; - let attributes = [Attributes<DXIL1_0, [ReadNone]>]; } def WaveIsFirstLane : DXILOp<110, waveIsFirstLane> { >From 883b2a80002b8e0d0c5222bd302c716df642ba76 Mon Sep 17 00:00:00 2001 From: Ashley Coleman <ascole...@microsoft.com> Date: Thu, 14 Nov 2024 16:50:08 -0700 Subject: [PATCH 10/11] format --- clang/lib/CodeGen/CGBuiltin.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index af03d477f13509..d6e90e7821ceec 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -19123,7 +19123,8 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: { case Builtin::BI__builtin_hlsl_wave_active_any_true: { Value *Op = EmitScalarExpr(E->getArg(0)); llvm::Type *Ty = Op->getType(); - assert(Ty->isIntegerTy(1) && "Intrinsic WaveActiveAnyTrue operand must be a bool"); + assert(Ty->isIntegerTy(1) && + "Intrinsic WaveActiveAnyTrue operand must be a bool"); Intrinsic::ID ID = CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic(); return EmitRuntimeCall( >From 4dd242a1abbe2a402e7ed6e4bca522357286f980 Mon Sep 17 00:00:00 2001 From: Ashley Coleman <ascole...@microsoft.com> Date: Thu, 14 Nov 2024 16:54:52 -0700 Subject: [PATCH 11/11] Address comments --- llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp index 3e887a3b03150c..3093521b962fd3 100644 --- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp @@ -631,7 +631,13 @@ void RequirementHandler::initAvailableCapabilities(const SPIRVSubtarget &ST) { Capability::Int16}); if (ST.isAtLeastSPIRVVer(VersionTuple(1, 3))) - addAvailableCaps({Capability::GroupNonUniformVote}); + addAvailableCaps({Capability::GroupNonUniform, + Capability::GroupNonUniformVote, + Capability::GroupNonUniformArithmetic, + Capability::GroupNonUniformBallot, + Capability::GroupNonUniformClustered, + Capability::GroupNonUniformShuffle, + Capability::GroupNonUniformShuffleRelative}); if (ST.isAtLeastSPIRVVer(VersionTuple(1, 6))) addAvailableCaps({Capability::DotProduct, Capability::DotProductInputAll, @@ -677,13 +683,6 @@ void RequirementHandler::initAvailableCapabilitiesForOpenCL( if (ST.isAtLeastSPIRVVer(VersionTuple(1, 1)) && ST.isAtLeastOpenCLVer(VersionTuple(2, 2))) addAvailableCaps({Capability::SubgroupDispatch, Capability::PipeStorage}); - if (ST.isAtLeastSPIRVVer(VersionTuple(1, 3))) - addAvailableCaps({Capability::GroupNonUniform, - Capability::GroupNonUniformArithmetic, - Capability::GroupNonUniformBallot, - Capability::GroupNonUniformClustered, - Capability::GroupNonUniformShuffle, - Capability::GroupNonUniformShuffleRelative}); if (ST.isAtLeastSPIRVVer(VersionTuple(1, 4))) addAvailableCaps({Capability::DenormPreserve, Capability::DenormFlushToZero, Capability::SignedZeroInfNanPreserve, _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits