[clang] [llvm] [DXIL][SPIRV] Lower `WaveActiveCountBits` intrinsic (PR #113382)
https://github.com/inbelic closed https://github.com/llvm/llvm-project/pull/113382 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL][SPIRV] Lower `WaveActiveCountBits` intrinsic (PR #113382)
https://github.com/inbelic updated https://github.com/llvm/llvm-project/pull/113382 >From 35731658c1769453f86dde6063b137a2c5aeca32 Mon Sep 17 00:00:00 2001 From: Finn Plummer Date: Fri, 18 Oct 2024 15:48:29 -0700 Subject: [PATCH 1/4] [DXIL][SPIRV] Lower WaveActiveCountBits intrinsic - add codegen for llvm builtin to spirv/directx intrinsic in CGBuiltin.cpp - add lowering of spirv intrinsic to spirv backend in SPIRVInstructionSelector.cpp - add lowering of directx intrinsic to dxil op in DXIL.td - add test cases to illustrate passes - add test case for semantic analysis --- clang/lib/CodeGen/CGBuiltin.cpp | 7 clang/lib/CodeGen/CGHLSLRuntime.h | 1 + .../builtins/WaveActiveCountBits.hlsl | 22 +++ .../BuiltIns/WaveActiveCountBits-errors.hlsl | 18 + llvm/include/llvm/IR/IntrinsicsDirectX.td | 1 + llvm/include/llvm/IR/IntrinsicsSPIRV.td | 1 + llvm/lib/Target/DirectX/DXIL.td | 9 + .../Target/SPIRV/SPIRVInstructionSelector.cpp | 37 +++ .../CodeGen/DirectX/WaveActiveCountBits.ll| 10 + .../hlsl-intrinsics/WaveActiveCountBits.ll| 19 ++ 10 files changed, 125 insertions(+) create mode 100755 clang/test/CodeGenHLSL/builtins/WaveActiveCountBits.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/WaveActiveCountBits-errors.hlsl create mode 100644 llvm/test/CodeGen/DirectX/WaveActiveCountBits.ll create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveCountBits.ll diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 0ef9058640db6a..db6b8f80195691 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -19056,6 +19056,13 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: { /*ReturnType=*/Op0->getType(), CGM.getHLSLRuntime().getStepIntrinsic(), ArrayRef{Op0, Op1}, nullptr, "hlsl.step"); } + case Builtin::BI__builtin_hlsl_wave_active_count_bits: { +Value *OpExpr = EmitScalarExpr(E->getArg(0)); +Intrinsic::ID ID = CGM.getHLSLRuntime().getWaveActiveCountBitsIntrinsic(); +return EmitRuntimeCall( +Intrinsic::getOrInsertDeclaration(&CGM.getModule(), ID), +ArrayRef{OpExpr}); + } 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 caf8777fd95a9f..167cc04baf159f 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -91,6 +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(WaveActiveCountBits, wave_active_countbits) GENERATE_HLSL_INTRINSIC_FUNCTION(WaveIsFirstLane, wave_is_first_lane) GENERATE_HLSL_INTRINSIC_FUNCTION(WaveReadLaneAt, wave_readlane) GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitUHigh, firstbituhigh) diff --git a/clang/test/CodeGenHLSL/builtins/WaveActiveCountBits.hlsl b/clang/test/CodeGenHLSL/builtins/WaveActiveCountBits.hlsl new file mode 100755 index 00..3e1f8fcaace9c2 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/WaveActiveCountBits.hlsl @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -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 -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. + +// CHECK-LABEL: test_bool +int test_bool(bool expr) { + // CHECK-SPIRV: %[[#entry_tok:]] = call token @llvm.experimental.convergence.entry() + // CHECK-SPIRV: %[[RET:.*]] = call spir_func i32 @llvm.spv.wave.active.countbits(i1 %{{.*}}) [ "convergencectrl"(token %[[#entry_tok]]) ] + // CHECK-DXIL: %[[RET:.*]] = call i32 @llvm.dx.wave.active.countbits(i1 %{{.*}}) + // CHECK: ret i32 %[[RET]] + return WaveActiveCountBits(expr); +} + +// CHECK-DXIL: declare i32 @llvm.dx.wave.active.countbits(i1) #[[#attr:]] +// CHECK-SPIRV: declare i32 @llvm.spv.wave.active.countbits(i1) #[[#attr:]] + +// CHECK: attributes #[[#attr]] = {{{.*}} convergent {{.*}}} diff --git a/clang/test/SemaHLSL/BuiltIns/WaveActiveCountBits-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/WaveActiveCountBits-errors.hlsl new file mode 100644 index 00..02f45eb30b377a --- /dev/null +++ b/clang/test/SemaHLSL/BuiltIns/WaveActiveCountBits-errors.hlsl @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-s
[clang] [llvm] [DXIL][SPIRV] Lower `WaveActiveCountBits` intrinsic (PR #113382)
https://github.com/s-perron approved this pull request. https://github.com/llvm/llvm-project/pull/113382 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL][SPIRV] Lower `WaveActiveCountBits` intrinsic (PR #113382)
https://github.com/inbelic updated https://github.com/llvm/llvm-project/pull/113382 >From 35731658c1769453f86dde6063b137a2c5aeca32 Mon Sep 17 00:00:00 2001 From: Finn Plummer Date: Fri, 18 Oct 2024 15:48:29 -0700 Subject: [PATCH 1/4] [DXIL][SPIRV] Lower WaveActiveCountBits intrinsic - add codegen for llvm builtin to spirv/directx intrinsic in CGBuiltin.cpp - add lowering of spirv intrinsic to spirv backend in SPIRVInstructionSelector.cpp - add lowering of directx intrinsic to dxil op in DXIL.td - add test cases to illustrate passes - add test case for semantic analysis --- clang/lib/CodeGen/CGBuiltin.cpp | 7 clang/lib/CodeGen/CGHLSLRuntime.h | 1 + .../builtins/WaveActiveCountBits.hlsl | 22 +++ .../BuiltIns/WaveActiveCountBits-errors.hlsl | 18 + llvm/include/llvm/IR/IntrinsicsDirectX.td | 1 + llvm/include/llvm/IR/IntrinsicsSPIRV.td | 1 + llvm/lib/Target/DirectX/DXIL.td | 9 + .../Target/SPIRV/SPIRVInstructionSelector.cpp | 37 +++ .../CodeGen/DirectX/WaveActiveCountBits.ll| 10 + .../hlsl-intrinsics/WaveActiveCountBits.ll| 19 ++ 10 files changed, 125 insertions(+) create mode 100755 clang/test/CodeGenHLSL/builtins/WaveActiveCountBits.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/WaveActiveCountBits-errors.hlsl create mode 100644 llvm/test/CodeGen/DirectX/WaveActiveCountBits.ll create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveCountBits.ll diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 0ef9058640db6a..db6b8f80195691 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -19056,6 +19056,13 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: { /*ReturnType=*/Op0->getType(), CGM.getHLSLRuntime().getStepIntrinsic(), ArrayRef{Op0, Op1}, nullptr, "hlsl.step"); } + case Builtin::BI__builtin_hlsl_wave_active_count_bits: { +Value *OpExpr = EmitScalarExpr(E->getArg(0)); +Intrinsic::ID ID = CGM.getHLSLRuntime().getWaveActiveCountBitsIntrinsic(); +return EmitRuntimeCall( +Intrinsic::getOrInsertDeclaration(&CGM.getModule(), ID), +ArrayRef{OpExpr}); + } 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 caf8777fd95a9f..167cc04baf159f 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -91,6 +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(WaveActiveCountBits, wave_active_countbits) GENERATE_HLSL_INTRINSIC_FUNCTION(WaveIsFirstLane, wave_is_first_lane) GENERATE_HLSL_INTRINSIC_FUNCTION(WaveReadLaneAt, wave_readlane) GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitUHigh, firstbituhigh) diff --git a/clang/test/CodeGenHLSL/builtins/WaveActiveCountBits.hlsl b/clang/test/CodeGenHLSL/builtins/WaveActiveCountBits.hlsl new file mode 100755 index 00..3e1f8fcaace9c2 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/WaveActiveCountBits.hlsl @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -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 -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. + +// CHECK-LABEL: test_bool +int test_bool(bool expr) { + // CHECK-SPIRV: %[[#entry_tok:]] = call token @llvm.experimental.convergence.entry() + // CHECK-SPIRV: %[[RET:.*]] = call spir_func i32 @llvm.spv.wave.active.countbits(i1 %{{.*}}) [ "convergencectrl"(token %[[#entry_tok]]) ] + // CHECK-DXIL: %[[RET:.*]] = call i32 @llvm.dx.wave.active.countbits(i1 %{{.*}}) + // CHECK: ret i32 %[[RET]] + return WaveActiveCountBits(expr); +} + +// CHECK-DXIL: declare i32 @llvm.dx.wave.active.countbits(i1) #[[#attr:]] +// CHECK-SPIRV: declare i32 @llvm.spv.wave.active.countbits(i1) #[[#attr:]] + +// CHECK: attributes #[[#attr]] = {{{.*}} convergent {{.*}}} diff --git a/clang/test/SemaHLSL/BuiltIns/WaveActiveCountBits-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/WaveActiveCountBits-errors.hlsl new file mode 100644 index 00..02f45eb30b377a --- /dev/null +++ b/clang/test/SemaHLSL/BuiltIns/WaveActiveCountBits-errors.hlsl @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-s
[clang] [llvm] [DXIL][SPIRV] Lower `WaveActiveCountBits` intrinsic (PR #113382)
inbelic wrote: Rebased to resolve conflicts. https://github.com/llvm/llvm-project/pull/113382 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL][SPIRV] Lower `WaveActiveCountBits` intrinsic (PR #113382)
https://github.com/inbelic updated https://github.com/llvm/llvm-project/pull/113382 >From 35731658c1769453f86dde6063b137a2c5aeca32 Mon Sep 17 00:00:00 2001 From: Finn Plummer Date: Fri, 18 Oct 2024 15:48:29 -0700 Subject: [PATCH 1/4] [DXIL][SPIRV] Lower WaveActiveCountBits intrinsic - add codegen for llvm builtin to spirv/directx intrinsic in CGBuiltin.cpp - add lowering of spirv intrinsic to spirv backend in SPIRVInstructionSelector.cpp - add lowering of directx intrinsic to dxil op in DXIL.td - add test cases to illustrate passes - add test case for semantic analysis --- clang/lib/CodeGen/CGBuiltin.cpp | 7 clang/lib/CodeGen/CGHLSLRuntime.h | 1 + .../builtins/WaveActiveCountBits.hlsl | 22 +++ .../BuiltIns/WaveActiveCountBits-errors.hlsl | 18 + llvm/include/llvm/IR/IntrinsicsDirectX.td | 1 + llvm/include/llvm/IR/IntrinsicsSPIRV.td | 1 + llvm/lib/Target/DirectX/DXIL.td | 9 + .../Target/SPIRV/SPIRVInstructionSelector.cpp | 37 +++ .../CodeGen/DirectX/WaveActiveCountBits.ll| 10 + .../hlsl-intrinsics/WaveActiveCountBits.ll| 19 ++ 10 files changed, 125 insertions(+) create mode 100755 clang/test/CodeGenHLSL/builtins/WaveActiveCountBits.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/WaveActiveCountBits-errors.hlsl create mode 100644 llvm/test/CodeGen/DirectX/WaveActiveCountBits.ll create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveCountBits.ll diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 0ef9058640db6a..db6b8f80195691 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -19056,6 +19056,13 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: { /*ReturnType=*/Op0->getType(), CGM.getHLSLRuntime().getStepIntrinsic(), ArrayRef{Op0, Op1}, nullptr, "hlsl.step"); } + case Builtin::BI__builtin_hlsl_wave_active_count_bits: { +Value *OpExpr = EmitScalarExpr(E->getArg(0)); +Intrinsic::ID ID = CGM.getHLSLRuntime().getWaveActiveCountBitsIntrinsic(); +return EmitRuntimeCall( +Intrinsic::getOrInsertDeclaration(&CGM.getModule(), ID), +ArrayRef{OpExpr}); + } 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 caf8777fd95a9f..167cc04baf159f 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -91,6 +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(WaveActiveCountBits, wave_active_countbits) GENERATE_HLSL_INTRINSIC_FUNCTION(WaveIsFirstLane, wave_is_first_lane) GENERATE_HLSL_INTRINSIC_FUNCTION(WaveReadLaneAt, wave_readlane) GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitUHigh, firstbituhigh) diff --git a/clang/test/CodeGenHLSL/builtins/WaveActiveCountBits.hlsl b/clang/test/CodeGenHLSL/builtins/WaveActiveCountBits.hlsl new file mode 100755 index 00..3e1f8fcaace9c2 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/WaveActiveCountBits.hlsl @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -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 -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. + +// CHECK-LABEL: test_bool +int test_bool(bool expr) { + // CHECK-SPIRV: %[[#entry_tok:]] = call token @llvm.experimental.convergence.entry() + // CHECK-SPIRV: %[[RET:.*]] = call spir_func i32 @llvm.spv.wave.active.countbits(i1 %{{.*}}) [ "convergencectrl"(token %[[#entry_tok]]) ] + // CHECK-DXIL: %[[RET:.*]] = call i32 @llvm.dx.wave.active.countbits(i1 %{{.*}}) + // CHECK: ret i32 %[[RET]] + return WaveActiveCountBits(expr); +} + +// CHECK-DXIL: declare i32 @llvm.dx.wave.active.countbits(i1) #[[#attr:]] +// CHECK-SPIRV: declare i32 @llvm.spv.wave.active.countbits(i1) #[[#attr:]] + +// CHECK: attributes #[[#attr]] = {{{.*}} convergent {{.*}}} diff --git a/clang/test/SemaHLSL/BuiltIns/WaveActiveCountBits-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/WaveActiveCountBits-errors.hlsl new file mode 100644 index 00..02f45eb30b377a --- /dev/null +++ b/clang/test/SemaHLSL/BuiltIns/WaveActiveCountBits-errors.hlsl @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-s
[clang] [llvm] [DXIL][SPIRV] Lower `WaveActiveCountBits` intrinsic (PR #113382)
@@ -1762,6 +1765,37 @@ bool SPIRVInstructionSelector::selectSign(Register ResVReg, return Result; } +bool SPIRVInstructionSelector::selectWaveActiveCountBits( +Register ResVReg, const SPIRVType *ResType, MachineInstr &I) const { + assert(I.getNumOperands() == 3); + assert(I.getOperand(2).isReg()); + MachineBasicBlock &BB = *I.getParent(); + + Register BallotReg = MRI->createVirtualRegister(&SPIRV::IDRegClass); inbelic wrote: Good catch. Changed to using `GR.getRegClass(BallotType)`. https://github.com/llvm/llvm-project/pull/113382 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL][SPIRV] Lower `WaveActiveCountBits` intrinsic (PR #113382)
https://github.com/spall approved this pull request. https://github.com/llvm/llvm-project/pull/113382 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL][SPIRV] Lower `WaveActiveCountBits` intrinsic (PR #113382)
@@ -1762,6 +1765,37 @@ bool SPIRVInstructionSelector::selectSign(Register ResVReg, return Result; } +bool SPIRVInstructionSelector::selectWaveActiveCountBits( +Register ResVReg, const SPIRVType *ResType, MachineInstr &I) const { + assert(I.getNumOperands() == 3); + assert(I.getOperand(2).isReg()); + MachineBasicBlock &BB = *I.getParent(); + + Register BallotReg = MRI->createVirtualRegister(&SPIRV::IDRegClass); spall wrote: Is SPIRV::IDRegClass just a register class for all types? Because there are others like SPIRV::vIDRegClass, which is for vectors. https://github.com/llvm/llvm-project/pull/113382 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL][SPIRV] Lower `WaveActiveCountBits` intrinsic (PR #113382)
https://github.com/inbelic edited https://github.com/llvm/llvm-project/pull/113382 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL][SPIRV] Lower WaveActiveCountBits intrinsic (PR #113382)
https://github.com/inbelic edited https://github.com/llvm/llvm-project/pull/113382 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL][SPIRV] Lower WaveActiveCountBits intrinsic (PR #113382)
https://github.com/inbelic deleted https://github.com/llvm/llvm-project/pull/113382 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL][SPIRV] Lower WaveActiveCountBits intrinsic (PR #113382)
@@ -820,3 +820,12 @@ def WaveGetLaneIndex : DXILOp<111, waveGetLaneIndex> { let stages = [Stages]; let attributes = [Attributes]; } + +def WaveAllBitCount : DXILOp<135, waveAllOp> { + let Doc = "returns the count of bits set to 1 across the wave"; + let LLVMIntrinsic = int_dx_wave_active_countbits; + let arguments = [Int1Ty]; + let result = Int32Ty; + let stages = [Stages]; + let attributes = [Attributes]; inbelic wrote: @pow2clk Just want to ping to double check these attributes are okay. `ReadNone` is not in `hctdb.py` but it would seem to be applicable. Should `IsWave` be added now or will we add them all at once in a separate commit? https://github.com/llvm/llvm-project/pull/113382 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL][SPIRV] Lower WaveActiveCountBits intrinsic (PR #113382)
https://github.com/pow2clk edited https://github.com/llvm/llvm-project/pull/113382 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL][SPIRV] Lower WaveActiveCountBits intrinsic (PR #113382)
@@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -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 -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. + +// CHECK-LABEL: test_bool +int test_bool(bool expr) { + // CHECK-SPIRV: %[[#entry_tok:]] = call token @llvm.experimental.convergence.entry() + // CHECK-SPIRV: %[[RET:.*]] = call spir_func i32 @llvm.spv.wave.active.countbits(i1 %{{.*}}) [ "convergencectrl"(token %[[#entry_tok]]) ] inbelic wrote: I guess when the change to add the convergence token was first introduced it was important to check that the convergence token was correctly generated for the appropriate spirv operations. But now it is probably quite redundant to add that on each test, and checking for the convergent attribute is sufficient. Will update to use `-DTARGET` as suggested. https://github.com/llvm/llvm-project/pull/113382 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL][SPIRV] Lower WaveActiveCountBits intrinsic (PR #113382)
@@ -1762,6 +1765,36 @@ bool SPIRVInstructionSelector::selectSign(Register ResVReg, return Result; } +bool SPIRVInstructionSelector::selectWaveActiveCountBits( +Register ResVReg, const SPIRVType *ResType, MachineInstr &I) const { + assert(I.getNumOperands() == 3); + assert(I.getOperand(2).isReg()); + MachineBasicBlock &BB = *I.getParent(); + + Register BallotReg = MRI->createVirtualRegister(&SPIRV::IDRegClass); + SPIRVType *IntTy = GR.getOrCreateSPIRVIntegerType(32, I, TII); + SPIRVType *BallotType = GR.getOrCreateSPIRVVectorType(IntTy, 4, I, TII); + + bool Result = + BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpGroupNonUniformBallot)) + .addDef(BallotReg) + .addUse(GR.getSPIRVTypeID(BallotType)) + .addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy, TII)) + .addUse(I.getOperand(2).getReg()); + + Result |= + BuildMI(BB, I, I.getDebugLoc(), + TII.get(SPIRV::OpGroupNonUniformBallotBitCount)) + .addDef(ResVReg) + .addUse(GR.getSPIRVTypeID(ResType)) + .addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy, TII)) + .addImm(0) pow2clk wrote: Do I understand that you'll do this before submitting this PR? https://github.com/llvm/llvm-project/pull/113382 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL][SPIRV] Lower WaveActiveCountBits intrinsic (PR #113382)
@@ -1762,6 +1765,36 @@ bool SPIRVInstructionSelector::selectSign(Register ResVReg, return Result; } +bool SPIRVInstructionSelector::selectWaveActiveCountBits( +Register ResVReg, const SPIRVType *ResType, MachineInstr &I) const { + assert(I.getNumOperands() == 3); + assert(I.getOperand(2).isReg()); + MachineBasicBlock &BB = *I.getParent(); + + Register BallotReg = MRI->createVirtualRegister(&SPIRV::IDRegClass); + SPIRVType *IntTy = GR.getOrCreateSPIRVIntegerType(32, I, TII); + SPIRVType *BallotType = GR.getOrCreateSPIRVVectorType(IntTy, 4, I, TII); + + bool Result = + BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpGroupNonUniformBallot)) + .addDef(BallotReg) + .addUse(GR.getSPIRVTypeID(BallotType)) + .addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy, TII)) + .addUse(I.getOperand(2).getReg()); pow2clk wrote: You're missing a `constrainAllUses` call on the end here. `AddUse` returns a reference to `MachineInstrBuilder`, which I'm not really sure how gets converted to a bool, but I don't want to rely on it. https://github.com/llvm/llvm-project/pull/113382 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL][SPIRV] Lower WaveActiveCountBits intrinsic (PR #113382)
@@ -820,3 +820,12 @@ def WaveGetLaneIndex : DXILOp<111, waveGetLaneIndex> { let stages = [Stages]; let attributes = [Attributes]; } + +def WaveAllBitCount : DXILOp<135, waveAllOp> { pow2clk wrote: Initially, I thought this couldn't be right since the latter name `waveAllOp` mismatches the former `WaveAllBitCount` in more than just capitalization, but though DXIL.rst makes no mention of waveAllOp, that is the name of the actual DXIL op. Weird, but consistent. https://github.com/llvm/llvm-project/pull/113382 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL][SPIRV] Lower WaveActiveCountBits intrinsic (PR #113382)
https://github.com/inbelic edited https://github.com/llvm/llvm-project/pull/113382 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL][SPIRV] Lower WaveActiveCountBits intrinsic (PR #113382)
https://github.com/inbelic updated https://github.com/llvm/llvm-project/pull/113382 >From a9b7602da0f38aeef41ce4e0a8c6a4a6e0d71b0a Mon Sep 17 00:00:00 2001 From: Finn Plummer Date: Fri, 18 Oct 2024 15:48:29 -0700 Subject: [PATCH 1/3] [DXIL][SPIRV] Lower WaveActiveCountBits intrinsic - add codegen for llvm builtin to spirv/directx intrinsic in CGBuiltin.cpp - add lowering of spirv intrinsic to spirv backend in SPIRVInstructionSelector.cpp - add lowering of directx intrinsic to dxil op in DXIL.td - add test cases to illustrate passes - add test case for semantic analysis --- clang/lib/CodeGen/CGBuiltin.cpp | 7 clang/lib/CodeGen/CGHLSLRuntime.h | 1 + .../builtins/WaveActiveCountBits.hlsl | 22 +++ .../BuiltIns/WaveActiveCountBits-errors.hlsl | 18 + llvm/include/llvm/IR/IntrinsicsDirectX.td | 1 + llvm/include/llvm/IR/IntrinsicsSPIRV.td | 1 + llvm/lib/Target/DirectX/DXIL.td | 9 + .../Target/SPIRV/SPIRVInstructionSelector.cpp | 37 +++ .../CodeGen/DirectX/WaveActiveCountBits.ll| 10 + .../hlsl-intrinsics/WaveActiveCountBits.ll| 19 ++ 10 files changed, 125 insertions(+) create mode 100755 clang/test/CodeGenHLSL/builtins/WaveActiveCountBits.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/WaveActiveCountBits-errors.hlsl create mode 100644 llvm/test/CodeGen/DirectX/WaveActiveCountBits.ll create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveCountBits.ll diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 1ad950798c2118..64c3ff08eea442 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18879,6 +18879,13 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: { /*ReturnType=*/Op0->getType(), CGM.getHLSLRuntime().getStepIntrinsic(), ArrayRef{Op0, Op1}, nullptr, "hlsl.step"); } + case Builtin::BI__builtin_hlsl_wave_active_count_bits: { +Value *OpExpr = EmitScalarExpr(E->getArg(0)); +Intrinsic::ID ID = CGM.getHLSLRuntime().getWaveActiveCountBitsIntrinsic(); +return EmitRuntimeCall( +Intrinsic::getOrInsertDeclaration(&CGM.getModule(), ID), +ArrayRef{OpExpr}); + } 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 ff7df41b5c62e7..ada57b070783c6 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(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/WaveActiveCountBits.hlsl b/clang/test/CodeGenHLSL/builtins/WaveActiveCountBits.hlsl new file mode 100755 index 00..3e1f8fcaace9c2 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/WaveActiveCountBits.hlsl @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -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 -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. + +// CHECK-LABEL: test_bool +int test_bool(bool expr) { + // CHECK-SPIRV: %[[#entry_tok:]] = call token @llvm.experimental.convergence.entry() + // CHECK-SPIRV: %[[RET:.*]] = call spir_func i32 @llvm.spv.wave.active.countbits(i1 %{{.*}}) [ "convergencectrl"(token %[[#entry_tok]]) ] + // CHECK-DXIL: %[[RET:.*]] = call i32 @llvm.dx.wave.active.countbits(i1 %{{.*}}) + // CHECK: ret i32 %[[RET]] + return WaveActiveCountBits(expr); +} + +// CHECK-DXIL: declare i32 @llvm.dx.wave.active.countbits(i1) #[[#attr:]] +// CHECK-SPIRV: declare i32 @llvm.spv.wave.active.countbits(i1) #[[#attr:]] + +// CHECK: attributes #[[#attr]] = {{{.*}} convergent {{.*}}} diff --git a/clang/test/SemaHLSL/BuiltIns/WaveActiveCountBits-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/WaveActiveCountBits-errors.hlsl new file mode 100644 index 00..02f45eb30b377a --- /dev/null +++ b/clang/test/SemaHLSL/BuiltIns/WaveActiveCountBits-errors.hlsl @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -emit-llvm-only -disable-llvm-passes -verify + +int test_too_few_arg() { + return __
[clang] [llvm] [DXIL][SPIRV] Lower WaveActiveCountBits intrinsic (PR #113382)
@@ -1762,6 +1765,36 @@ bool SPIRVInstructionSelector::selectSign(Register ResVReg, return Result; } +bool SPIRVInstructionSelector::selectWaveActiveCountBits( +Register ResVReg, const SPIRVType *ResType, MachineInstr &I) const { + assert(I.getNumOperands() == 3); + assert(I.getOperand(2).isReg()); + MachineBasicBlock &BB = *I.getParent(); + + Register BallotReg = MRI->createVirtualRegister(&SPIRV::IDRegClass); + SPIRVType *IntTy = GR.getOrCreateSPIRVIntegerType(32, I, TII); + SPIRVType *BallotType = GR.getOrCreateSPIRVVectorType(IntTy, 4, I, TII); + + bool Result = + BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpGroupNonUniformBallot)) + .addDef(BallotReg) + .addUse(GR.getSPIRVTypeID(BallotType)) + .addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy, TII)) + .addUse(I.getOperand(2).getReg()); + + Result |= + BuildMI(BB, I, I.getDebugLoc(), + TII.get(SPIRV::OpGroupNonUniformBallotBitCount)) + .addDef(ResVReg) + .addUse(GR.getSPIRVTypeID(ResType)) + .addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy, TII)) + .addImm(0) inbelic wrote: Yep, have it added for when the other review comments are addressed. https://github.com/llvm/llvm-project/pull/113382 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL][SPIRV] Lower WaveActiveCountBits intrinsic (PR #113382)
https://github.com/pow2clk commented: Looks good! The only change I think is essential is the missing `constrainAllUses` https://github.com/llvm/llvm-project/pull/113382 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL][SPIRV] Lower WaveActiveCountBits intrinsic (PR #113382)
@@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -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 -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. + +// CHECK-LABEL: test_bool +int test_bool(bool expr) { + // CHECK-SPIRV: %[[#entry_tok:]] = call token @llvm.experimental.convergence.entry() + // CHECK-SPIRV: %[[RET:.*]] = call spir_func i32 @llvm.spv.wave.active.countbits(i1 %{{.*}}) [ "convergencectrl"(token %[[#entry_tok]]) ] pow2clk wrote: I'm not saying this needs to change, but just in case you're unaware, the CHECK line doesn't have to match every character on that line. Youl could cut it off after the closing paren of `countbits` and match the specificity of the DXIL check and also give the opportunity to create a filecheck define that would be either `dx` or `spv` depending that you could check on the same common check line. https://github.com/llvm/llvm-project/pull/113382 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL][SPIRV] Lower WaveActiveCountBits intrinsic (PR #113382)
inbelic wrote: Failing testcase is unrelated. Will need to rebase on review changes. https://github.com/llvm/llvm-project/pull/113382 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL][SPIRV] Lower WaveActiveCountBits intrinsic (PR #113382)
@@ -1762,6 +1765,36 @@ bool SPIRVInstructionSelector::selectSign(Register ResVReg, return Result; } +bool SPIRVInstructionSelector::selectWaveActiveCountBits( +Register ResVReg, const SPIRVType *ResType, MachineInstr &I) const { + assert(I.getNumOperands() == 3); + assert(I.getOperand(2).isReg()); + MachineBasicBlock &BB = *I.getParent(); + + Register BallotReg = MRI->createVirtualRegister(&SPIRV::IDRegClass); + SPIRVType *IntTy = GR.getOrCreateSPIRVIntegerType(32, I, TII); + SPIRVType *BallotType = GR.getOrCreateSPIRVVectorType(IntTy, 4, I, TII); + + bool Result = + BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpGroupNonUniformBallot)) + .addDef(BallotReg) + .addUse(GR.getSPIRVTypeID(BallotType)) + .addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy, TII)) + .addUse(I.getOperand(2).getReg()); + + Result |= + BuildMI(BB, I, I.getDebugLoc(), + TII.get(SPIRV::OpGroupNonUniformBallotBitCount)) + .addDef(ResVReg) + .addUse(GR.getSPIRVTypeID(ResType)) + .addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy, TII)) + .addImm(0) inbelic wrote: Will update to use the `SPIRV::OperationGroup` enum https://github.com/llvm/llvm-project/pull/113382 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL][SPIRV] Lower WaveActiveCountBits intrinsic (PR #113382)
llvmbot wrote: @llvm/pr-subscribers-clang-codegen Author: Finn Plummer (inbelic) Changes - add codegen for llvm builtin to spirv/directx intrinsic in CGBuiltin.cpp - add lowering of spirv intrinsic to spirv backend in SPIRVInstructionSelector.cpp - add lowering of directx intrinsic to dxil op in DXIL.td - add test cases to illustrate passes - add test case for semantic analysis --- Full diff: https://github.com/llvm/llvm-project/pull/113382.diff 10 Files Affected: - (modified) clang/lib/CodeGen/CGBuiltin.cpp (+7) - (modified) clang/lib/CodeGen/CGHLSLRuntime.h (+1) - (added) clang/test/CodeGenHLSL/builtins/WaveActiveCountBits.hlsl (+22) - (added) clang/test/SemaHLSL/BuiltIns/WaveActiveCountBits-errors.hlsl (+18) - (modified) llvm/include/llvm/IR/IntrinsicsDirectX.td (+1) - (modified) llvm/include/llvm/IR/IntrinsicsSPIRV.td (+1) - (modified) llvm/lib/Target/DirectX/DXIL.td (+9) - (modified) llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp (+35) - (added) llvm/test/CodeGen/DirectX/WaveActiveCountBits.ll (+10) - (added) llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveCountBits.ll (+19) ``diff diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 28f28c70b5ae52..f178499156eb1f 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18879,6 +18879,13 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: { /*ReturnType=*/Op0->getType(), CGM.getHLSLRuntime().getStepIntrinsic(), ArrayRef{Op0, Op1}, nullptr, "hlsl.step"); } + case Builtin::BI__builtin_hlsl_wave_active_count_bits: { +Value *OpExpr = EmitScalarExpr(E->getArg(0)); +Intrinsic::ID ID = CGM.getHLSLRuntime().getWaveActiveCountBitsIntrinsic(); +return EmitRuntimeCall( +Intrinsic::getOrInsertDeclaration(&CGM.getModule(), ID), +ArrayRef{OpExpr}); + } 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 ff7df41b5c62e7..ada57b070783c6 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(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/WaveActiveCountBits.hlsl b/clang/test/CodeGenHLSL/builtins/WaveActiveCountBits.hlsl new file mode 100755 index 00..3e1f8fcaace9c2 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/WaveActiveCountBits.hlsl @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -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 -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. + +// CHECK-LABEL: test_bool +int test_bool(bool expr) { + // CHECK-SPIRV: %[[#entry_tok:]] = call token @llvm.experimental.convergence.entry() + // CHECK-SPIRV: %[[RET:.*]] = call spir_func i32 @llvm.spv.wave.active.countbits(i1 %{{.*}}) [ "convergencectrl"(token %[[#entry_tok]]) ] + // CHECK-DXIL: %[[RET:.*]] = call i32 @llvm.dx.wave.active.countbits(i1 %{{.*}}) + // CHECK: ret i32 %[[RET]] + return WaveActiveCountBits(expr); +} + +// CHECK-DXIL: declare i32 @llvm.dx.wave.active.countbits(i1) #[[#attr:]] +// CHECK-SPIRV: declare i32 @llvm.spv.wave.active.countbits(i1) #[[#attr:]] + +// CHECK: attributes #[[#attr]] = {{{.*}} convergent {{.*}}} diff --git a/clang/test/SemaHLSL/BuiltIns/WaveActiveCountBits-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/WaveActiveCountBits-errors.hlsl new file mode 100644 index 00..02f45eb30b377a --- /dev/null +++ b/clang/test/SemaHLSL/BuiltIns/WaveActiveCountBits-errors.hlsl @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -emit-llvm-only -disable-llvm-passes -verify + +int test_too_few_arg() { + return __builtin_hlsl_wave_active_count_bits(); + // expected-error@-1 {{too few arguments to function call, expected 1, have 0}} +} + +int test_too_many_arg(bool x) { + return __builtin_hlsl_wave_active_count_bits(x, x); + // expected-error@-1 {{too many arguments to function call, expected 1, have 2}} +} + +struct S { float f; }; + +int test_bad_conversion(S x) { + return __builtin_hlsl_wave_
[clang] [llvm] [DXIL][SPIRV] Lower WaveActiveCountBits intrinsic (PR #113382)
https://github.com/inbelic ready_for_review https://github.com/llvm/llvm-project/pull/113382 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL][SPIRV] Lower WaveActiveCountBits intrinsic (PR #113382)
https://github.com/inbelic updated https://github.com/llvm/llvm-project/pull/113382 >From 68c16dc2e21d3a78a388fdb883551f32b902db11 Mon Sep 17 00:00:00 2001 From: Finn Plummer Date: Fri, 18 Oct 2024 15:48:29 -0700 Subject: [PATCH 1/2] [DXIL][SPIRV] Lower WaveActiveCountBits intrinsic - add codegen for llvm builtin to spirv/directx intrinsic in CGBuiltin.cpp - add lowering of spirv intrinsic to spirv backend in SPIRVInstructionSelector.cpp - add lowering of directx intrinsic to dxil op in DXIL.td - add test cases to illustrate passes - add test case for semantic analysis --- clang/lib/CodeGen/CGBuiltin.cpp | 7 clang/lib/CodeGen/CGHLSLRuntime.h | 1 + .../builtins/WaveActiveCountBits.hlsl | 22 +++ .../BuiltIns/WaveActiveCountBits-errors.hlsl | 18 + llvm/include/llvm/IR/IntrinsicsDirectX.td | 1 + llvm/include/llvm/IR/IntrinsicsSPIRV.td | 1 + llvm/lib/Target/DirectX/DXIL.td | 9 + .../Target/SPIRV/SPIRVInstructionSelector.cpp | 37 +++ .../CodeGen/DirectX/WaveActiveCountBits.ll| 10 + .../hlsl-intrinsics/WaveActiveCountBits.ll| 19 ++ 10 files changed, 125 insertions(+) create mode 100755 clang/test/CodeGenHLSL/builtins/WaveActiveCountBits.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/WaveActiveCountBits-errors.hlsl create mode 100644 llvm/test/CodeGen/DirectX/WaveActiveCountBits.ll create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveCountBits.ll diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 28f28c70b5ae52..f178499156eb1f 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18879,6 +18879,13 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: { /*ReturnType=*/Op0->getType(), CGM.getHLSLRuntime().getStepIntrinsic(), ArrayRef{Op0, Op1}, nullptr, "hlsl.step"); } + case Builtin::BI__builtin_hlsl_wave_active_count_bits: { +Value *OpExpr = EmitScalarExpr(E->getArg(0)); +Intrinsic::ID ID = CGM.getHLSLRuntime().getWaveActiveCountBitsIntrinsic(); +return EmitRuntimeCall( +Intrinsic::getOrInsertDeclaration(&CGM.getModule(), ID), +ArrayRef{OpExpr}); + } 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 ff7df41b5c62e7..ada57b070783c6 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(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/WaveActiveCountBits.hlsl b/clang/test/CodeGenHLSL/builtins/WaveActiveCountBits.hlsl new file mode 100755 index 00..3e1f8fcaace9c2 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/WaveActiveCountBits.hlsl @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -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 -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. + +// CHECK-LABEL: test_bool +int test_bool(bool expr) { + // CHECK-SPIRV: %[[#entry_tok:]] = call token @llvm.experimental.convergence.entry() + // CHECK-SPIRV: %[[RET:.*]] = call spir_func i32 @llvm.spv.wave.active.countbits(i1 %{{.*}}) [ "convergencectrl"(token %[[#entry_tok]]) ] + // CHECK-DXIL: %[[RET:.*]] = call i32 @llvm.dx.wave.active.countbits(i1 %{{.*}}) + // CHECK: ret i32 %[[RET]] + return WaveActiveCountBits(expr); +} + +// CHECK-DXIL: declare i32 @llvm.dx.wave.active.countbits(i1) #[[#attr:]] +// CHECK-SPIRV: declare i32 @llvm.spv.wave.active.countbits(i1) #[[#attr:]] + +// CHECK: attributes #[[#attr]] = {{{.*}} convergent {{.*}}} diff --git a/clang/test/SemaHLSL/BuiltIns/WaveActiveCountBits-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/WaveActiveCountBits-errors.hlsl new file mode 100644 index 00..02f45eb30b377a --- /dev/null +++ b/clang/test/SemaHLSL/BuiltIns/WaveActiveCountBits-errors.hlsl @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -emit-llvm-only -disable-llvm-passes -verify + +int test_too_few_arg() { + return __
[clang] [llvm] [DXIL][SPIRV] Lower WaveActiveCountBits intrinsic (PR #113382)
https://github.com/inbelic created https://github.com/llvm/llvm-project/pull/113382 - add codegen for llvm builtin to spirv/directx intrinsic in CGBuiltin.cpp - add lowering of spirv intrinsic to spirv backend in SPIRVInstructionSelector.cpp - add lowering of directx intrinsic to dxil op in DXIL.td - add test cases to illustrate passes - add test case for semantic analysis >From 68c16dc2e21d3a78a388fdb883551f32b902db11 Mon Sep 17 00:00:00 2001 From: Finn Plummer Date: Fri, 18 Oct 2024 15:48:29 -0700 Subject: [PATCH] [DXIL][SPIRV] Lower WaveActiveCountBits intrinsic - add codegen for llvm builtin to spirv/directx intrinsic in CGBuiltin.cpp - add lowering of spirv intrinsic to spirv backend in SPIRVInstructionSelector.cpp - add lowering of directx intrinsic to dxil op in DXIL.td - add test cases to illustrate passes - add test case for semantic analysis --- clang/lib/CodeGen/CGBuiltin.cpp | 7 clang/lib/CodeGen/CGHLSLRuntime.h | 1 + .../builtins/WaveActiveCountBits.hlsl | 22 +++ .../BuiltIns/WaveActiveCountBits-errors.hlsl | 18 + llvm/include/llvm/IR/IntrinsicsDirectX.td | 1 + llvm/include/llvm/IR/IntrinsicsSPIRV.td | 1 + llvm/lib/Target/DirectX/DXIL.td | 9 + .../Target/SPIRV/SPIRVInstructionSelector.cpp | 37 +++ .../CodeGen/DirectX/WaveActiveCountBits.ll| 10 + .../hlsl-intrinsics/WaveActiveCountBits.ll| 19 ++ 10 files changed, 125 insertions(+) create mode 100755 clang/test/CodeGenHLSL/builtins/WaveActiveCountBits.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/WaveActiveCountBits-errors.hlsl create mode 100644 llvm/test/CodeGen/DirectX/WaveActiveCountBits.ll create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveCountBits.ll diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 28f28c70b5ae52..f178499156eb1f 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18879,6 +18879,13 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: { /*ReturnType=*/Op0->getType(), CGM.getHLSLRuntime().getStepIntrinsic(), ArrayRef{Op0, Op1}, nullptr, "hlsl.step"); } + case Builtin::BI__builtin_hlsl_wave_active_count_bits: { +Value *OpExpr = EmitScalarExpr(E->getArg(0)); +Intrinsic::ID ID = CGM.getHLSLRuntime().getWaveActiveCountBitsIntrinsic(); +return EmitRuntimeCall( +Intrinsic::getOrInsertDeclaration(&CGM.getModule(), ID), +ArrayRef{OpExpr}); + } 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 ff7df41b5c62e7..ada57b070783c6 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(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/WaveActiveCountBits.hlsl b/clang/test/CodeGenHLSL/builtins/WaveActiveCountBits.hlsl new file mode 100755 index 00..3e1f8fcaace9c2 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/WaveActiveCountBits.hlsl @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -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 -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. + +// CHECK-LABEL: test_bool +int test_bool(bool expr) { + // CHECK-SPIRV: %[[#entry_tok:]] = call token @llvm.experimental.convergence.entry() + // CHECK-SPIRV: %[[RET:.*]] = call spir_func i32 @llvm.spv.wave.active.countbits(i1 %{{.*}}) [ "convergencectrl"(token %[[#entry_tok]]) ] + // CHECK-DXIL: %[[RET:.*]] = call i32 @llvm.dx.wave.active.countbits(i1 %{{.*}}) + // CHECK: ret i32 %[[RET]] + return WaveActiveCountBits(expr); +} + +// CHECK-DXIL: declare i32 @llvm.dx.wave.active.countbits(i1) #[[#attr:]] +// CHECK-SPIRV: declare i32 @llvm.spv.wave.active.countbits(i1) #[[#attr:]] + +// CHECK: attributes #[[#attr]] = {{{.*}} convergent {{.*}}} diff --git a/clang/test/SemaHLSL/BuiltIns/WaveActiveCountBits-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/WaveActiveCountBits-errors.hlsl new file mode 100644 index 0