[clang] [llvm] [DXIL][SPIRV] Lower `WaveActiveCountBits` intrinsic (PR #113382)

2024-11-07 Thread Finn Plummer via cfe-commits

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)

2024-11-07 Thread Finn Plummer via cfe-commits

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)

2024-11-07 Thread Steven Perron via cfe-commits

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)

2024-11-07 Thread Finn Plummer via cfe-commits

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)

2024-11-07 Thread Finn Plummer via cfe-commits

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)

2024-11-07 Thread Finn Plummer via cfe-commits

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)

2024-11-07 Thread Finn Plummer via cfe-commits


@@ -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)

2024-11-07 Thread Sarah Spall via cfe-commits

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)

2024-11-07 Thread Sarah Spall via cfe-commits


@@ -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)

2024-11-04 Thread Finn Plummer via cfe-commits

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)

2024-11-04 Thread Finn Plummer via cfe-commits

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)

2024-11-04 Thread Finn Plummer via cfe-commits

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)

2024-10-29 Thread Finn Plummer via cfe-commits


@@ -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)

2024-10-25 Thread Greg Roth via cfe-commits

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)

2024-10-25 Thread Finn Plummer via cfe-commits


@@ -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)

2024-10-24 Thread Greg Roth via cfe-commits


@@ -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)

2024-10-24 Thread Greg Roth via cfe-commits


@@ -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)

2024-10-24 Thread Greg Roth via cfe-commits


@@ -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)

2024-10-24 Thread Finn Plummer via cfe-commits

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)

2024-10-24 Thread Finn Plummer via cfe-commits

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)

2024-10-24 Thread Finn Plummer via cfe-commits


@@ -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)

2024-10-24 Thread Greg Roth via cfe-commits

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)

2024-10-24 Thread Greg Roth via cfe-commits


@@ -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)

2024-10-22 Thread Finn Plummer via cfe-commits

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)

2024-10-22 Thread Finn Plummer via cfe-commits


@@ -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)

2024-10-22 Thread via cfe-commits

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)

2024-10-22 Thread Finn Plummer via cfe-commits

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)

2024-10-22 Thread Finn Plummer via cfe-commits

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)

2024-10-22 Thread Finn Plummer via cfe-commits

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