[clang] [llvm] [HLSL] Implement WaveActiveAnyTrue intrinsic (PR #115902)

Ashley Coleman via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 14 16:43:50 PST 2024


https://github.com/V-FEXrt updated https://github.com/llvm/llvm-project/pull/115902

>From 845256b2ed971a4e42f7f871e8b51e711486261a Mon Sep 17 00:00:00 2001
From: Ashley Coleman <ascoleman at microsoft.com>
Date: Mon, 11 Nov 2024 16:34:23 -0700
Subject: [PATCH 01/11] [HLSL] Implement WaveActiveAnyTrue intrinsic

---
 clang/include/clang/Basic/Builtins.td         |  6 +++++
 clang/lib/CodeGen/CGBuiltin.cpp               | 13 ++++++++++
 clang/lib/CodeGen/CGHLSLRuntime.h             |  1 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h      |  9 +++++++
 clang/lib/Sema/SemaHLSL.cpp                   |  6 +++++
 .../builtins/WaveActiveAnyTrue.hlsl           | 17 +++++++++++++
 .../BuiltIns/WaveActiveAnyTrue-errors.hlsl    | 21 ++++++++++++++++
 llvm/include/llvm/IR/IntrinsicsDirectX.td     |  1 +
 llvm/include/llvm/IR/IntrinsicsSPIRV.td       |  1 +
 llvm/lib/Target/DirectX/DXIL.td               | 10 ++++++++
 .../Target/SPIRV/SPIRVInstructionSelector.cpp | 24 +++++++++++++++++++
 .../test/CodeGen/DirectX/WaveActiveAnyTrue.ll | 10 ++++++++
 .../hlsl-intrinsics/WaveActiveAnyTrue.ll      | 17 +++++++++++++
 13 files changed, 136 insertions(+)
 create mode 100644 clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/WaveActiveAnyTrue-errors.hlsl
 create mode 100644 llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll

diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index 9bd67e0cefebc3..496b6739724295 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4744,6 +4744,12 @@ def HLSLAny : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "bool(...)";
 }
 
+def HLSLWaveActiveAnyTrue : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_wave_active_any_true"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "bool(bool)";
+}
+
 def HLSLWaveActiveCountBits : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_wave_active_count_bits"];
   let Attributes = [NoThrow, Const];
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 65d7f5c54a1913..c4a6a9abee63cc 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -18960,6 +18960,19 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: {
         /*ReturnType=*/Op0->getType(), CGM.getHLSLRuntime().getStepIntrinsic(),
         ArrayRef<Value *>{Op0, Op1}, nullptr, "hlsl.step");
   }
+  case Builtin::BI__builtin_hlsl_wave_active_any_true: {
+    // Assert Op->getType() == Bool
+
+    // FIXME: PR Question: Can this be simpler? Looks like Int1Ty isn't  predefined
+    IntegerType* Int1Ty = llvm::Type::getInt1Ty(CGM.getTypes().getLLVMContext());
+    Value *Op = EmitScalarExpr(E->getArg(0));
+    assert(Op->getType() == Int1Ty && "wave_active_any_true operand must be a bool");
+
+    // FIXME: PR Question: Re Style SingleRef vs {SingleRef} vs ArrayRef{SingleRef}
+    llvm::FunctionType *FT = llvm::FunctionType::get(Int1Ty, {Int1Ty}, /*isVarArg=*/false);
+    llvm::StringRef Name = Intrinsic::getName(CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic());
+    return EmitRuntimeCall(CGM.CreateRuntimeFunction(FT, Name, {}, /*Local=*/false, /*AssumeConvergent=*/true), {Op}, "hlsl.wave.activeanytrue");
+  }
   case Builtin::BI__builtin_hlsl_wave_get_lane_index: {
     // We don't define a SPIR-V intrinsic, instead it is a SPIR-V built-in
     // defined in SPIRVBuiltins.td. So instead we manually get the matching name
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h
index cd533cad84e9fb..c3b689ea44fcb8 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -89,6 +89,7 @@ class CGHLSLRuntime {
   GENERATE_HLSL_INTRINSIC_FUNCTION(FDot, fdot)
   GENERATE_HLSL_INTRINSIC_FUNCTION(SDot, sdot)
   GENERATE_HLSL_INTRINSIC_FUNCTION(UDot, udot)
+  GENERATE_HLSL_INTRINSIC_FUNCTION(WaveActiveAnyTrue, wave_activeanytrue)
   GENERATE_HLSL_INTRINSIC_FUNCTION(WaveIsFirstLane, wave_is_first_lane)
   GENERATE_HLSL_INTRINSIC_FUNCTION(WaveReadLaneAt, wave_readlane)
 
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 8ade4b27f360fb..90991e95d6565a 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -2096,6 +2096,15 @@ float4 trunc(float4);
 // Wave* builtins
 //===----------------------------------------------------------------------===//
 
+/// \brief Returns true if the expression is true in any active lane in the
+/// current wave.
+///
+/// \param Val The boolean expression to evaluate.
+/// \return True if the expression is true in any lane.
+_HLSL_AVAILABILITY(shadermodel, 6.0)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_any_true)
+__attribute__((convergent)) bool WaveActiveAnyTrue(bool Val);
+
 /// \brief Counts the number of boolean variables which evaluate to true across
 /// all active lanes in the current wave.
 ///
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index a472538236e2d9..e12a4ce1e75bd6 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2066,6 +2066,12 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
       return true;
     break;
   }
+  case Builtin::BI__builtin_hlsl_wave_active_any_true: {
+      if (SemaRef.checkArgCount(TheCall, 1))
+        return true;
+
+      break;
+  }
   case Builtin::BI__builtin_hlsl_wave_read_lane_at: {
     if (SemaRef.checkArgCount(TheCall, 2))
       return true;
diff --git a/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl b/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl
new file mode 100644
index 00000000000000..d8233c45e0ff2d
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -fnative-half-type -triple \
+// RUN:   dxil-pc-shadermodel6.3-compute %s -emit-llvm -disable-llvm-passes -o - | \
+// RUN:   FileCheck %s --check-prefixes=CHECK,CHECK-DXIL
+// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -fnative-half-type -triple \
+// RUN:   spirv-pc-vulkan-compute %s -emit-llvm -disable-llvm-passes -o - | \
+// RUN:   FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV
+
+// Test basic lowering to runtime function call for int values.
+
+// CHECK-LABEL: test
+bool test(bool p1) {
+  // CHECK-SPIRV: %[[#entry_tok0:]] = call token @llvm.experimental.convergence.entry()
+  // CHECK-SPIRV:  %[[RET:.*]] = call spir_func i1 @llvm.spv.wave.activeanytrue(i1 %{{[a-zA-Z0-9]+}}) [ "convergencectrl"(token %[[#entry_tok0]]) ]
+  // CHECK-DXIL:  %[[RET:.*]] = call i1 @llvm.dx.wave.activeanytrue(i1 %{{[a-zA-Z0-9]+}})
+  // CHECK:  ret i1 %[[RET]]
+  return WaveActiveAnyTrue(p1);
+}
diff --git a/clang/test/SemaHLSL/BuiltIns/WaveActiveAnyTrue-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/WaveActiveAnyTrue-errors.hlsl
new file mode 100644
index 00000000000000..48fda7b571fca7
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/WaveActiveAnyTrue-errors.hlsl
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -emit-llvm-only -disable-llvm-passes -verify
+
+bool test_too_few_arg() {
+  return __builtin_hlsl_wave_active_any_true();
+  // expected-error at -1 {{too few arguments to function call, expected 1, have 0}}
+}
+
+bool test_too_many_arg(bool p0) {
+  return __builtin_hlsl_wave_active_any_true(p0, p0);
+  // expected-error at -1 {{too many arguments to function call, expected 1, have 2}}
+}
+
+struct Foo
+{
+  int a;
+};
+
+bool test_type_check_2(Foo p0) {
+  return __builtin_hlsl_wave_active_any_true(p0);
+  // expected-error at -1 {{no viable conversion from 'Foo' to 'bool'}}
+}
diff --git a/llvm/include/llvm/IR/IntrinsicsDirectX.td b/llvm/include/llvm/IR/IntrinsicsDirectX.td
index e30d37f69f781e..7c21dc8f41f169 100644
--- a/llvm/include/llvm/IR/IntrinsicsDirectX.td
+++ b/llvm/include/llvm/IR/IntrinsicsDirectX.td
@@ -86,6 +86,7 @@ def int_dx_normalize : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_
 def int_dx_rsqrt  : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
 def int_dx_wave_getlaneindex : DefaultAttrsIntrinsic<[llvm_i32_ty], [], [IntrConvergent, IntrNoMem]>;
 def int_dx_wave_is_first_lane : DefaultAttrsIntrinsic<[llvm_i1_ty], [], [IntrConvergent]>;
+def int_dx_wave_activeanytrue : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_i1_ty], [IntrConvergent]>;
 def int_dx_wave_readlane : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>, llvm_i32_ty], [IntrConvergent, IntrNoMem]>;
 def int_dx_sign : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_any_ty], [IntrNoMem]>;
 def int_dx_step : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty, LLVMMatchType<0>], [IntrNoMem]>;
diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
index 6df2eb156a0774..c5e93aa4cfe01d 100644
--- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td
+++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
@@ -85,6 +85,7 @@ let TargetPrefix = "spv" in {
     [IntrNoMem, Commutative] >;
   def int_spv_wave_is_first_lane : DefaultAttrsIntrinsic<[llvm_i1_ty], [], [IntrConvergent]>;
   def int_spv_wave_readlane : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>, llvm_i32_ty], [IntrConvergent, IntrNoMem]>;
+  def int_spv_wave_activeanytrue : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_i1_ty], [IntrConvergent]>;
   def int_spv_sign : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_any_ty], [IntrNoMem]>;
   def int_spv_radians : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty], [IntrNoMem]>;
 
diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td
index 68ae5de06423c2..9657d249f9170a 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -202,6 +202,7 @@ defset list<DXILOpClass> OpClasses = {
   def unpack4x8 : DXILOpClass;
   def viewID : DXILOpClass;
   def waveActiveAllEqual : DXILOpClass;
+  def waveActiveAnyTrue : DXILOpClass;
   def waveActiveBallot : DXILOpClass;
   def waveActiveBit : DXILOpClass;
   def waveActiveOp : DXILOpClass;
@@ -803,6 +804,15 @@ def CreateHandleFromBinding : DXILOp<218, createHandleFromBinding> {
   let stages = [Stages<DXIL1_6, [all_stages]>];
 }
 
+def WaveActiveAnyTrue : DXILOp<113, waveActiveAnyTrue> {
+  let Doc = "returns true if the expression is true in any of the active lanes in the current wave";
+  let LLVMIntrinsic = int_dx_wave_activeanytrue;
+  let arguments = [Int1Ty];
+  let result = Int1Ty;
+  let stages = [Stages<DXIL1_0, [all_stages]>];
+  let attributes = [Attributes<DXIL1_0, [ReadNone]>];
+}
+
 def WaveIsFirstLane :  DXILOp<110, waveIsFirstLane> {
   let Doc = "returns 1 for the first lane in the wave";
   let LLVMIntrinsic = int_dx_wave_is_first_lane;
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index d9377fe4b91a1a..8d4faedd1c6210 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -230,6 +230,9 @@ class SPIRVInstructionSelector : public InstructionSelector {
   bool selectSpvThreadId(Register ResVReg, const SPIRVType *ResType,
                          MachineInstr &I) const;
 
+  bool selectWaveActiveAnyTrue(Register ResVReg, const SPIRVType *ResType,
+                               MachineInstr &I) const;
+
   bool selectWaveReadLaneAt(Register ResVReg, const SPIRVType *ResType,
                             MachineInstr &I) const;
 
@@ -1762,6 +1765,25 @@ bool SPIRVInstructionSelector::selectSign(Register ResVReg,
   return Result;
 }
 
+bool SPIRVInstructionSelector::selectWaveActiveAnyTrue(Register ResVReg,
+                                                    const SPIRVType *ResType,
+                                                    MachineInstr &I) const {
+  assert(I.getNumOperands() == 3);
+  assert(I.getOperand(2).isReg());
+
+  // IntTy is used to define the execution scope, set to 3 to denote a
+  // cross-lane interaction equivalent to a SPIR-V subgroup.
+  MachineBasicBlock &BB = *I.getParent();
+  SPIRVType *IntTy = GR.getOrCreateSPIRVIntegerType(32, I, TII);
+
+  return BuildMI(BB, I, I.getDebugLoc(),
+                 TII.get(SPIRV::OpGroupNonUniformAny))
+      .addDef(ResVReg)
+      .addUse(GR.getSPIRVTypeID(ResType))
+      .addUse(GR.getOrCreateConstInt(3, I, IntTy, TII))
+      .addUse(I.getOperand(2).getReg());
+}
+
 bool SPIRVInstructionSelector::selectWaveReadLaneAt(Register ResVReg,
                                                     const SPIRVType *ResType,
                                                     MachineInstr &I) const {
@@ -2567,6 +2589,8 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
         .addUse(GR.getSPIRVTypeID(ResType))
         .addUse(GR.getOrCreateConstInt(3, I, IntTy, TII));
   }
+  case Intrinsic::spv_wave_activeanytrue:
+    return selectWaveActiveAnyTrue(ResVReg, ResType, I);
   case Intrinsic::spv_wave_readlane:
     return selectWaveReadLaneAt(ResVReg, ResType, I);
   case Intrinsic::spv_step:
diff --git a/llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll b/llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll
new file mode 100644
index 00000000000000..cc97eb2eedcd60
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll
@@ -0,0 +1,10 @@
+; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-compute %s | FileCheck %s
+
+define noundef i1 @wave_aat_simple(i1 noundef %p1) {
+entry:
+; CHECK: call i1 @dx.op.waveActiveAnyTrue(i32 113, i1 %p1)
+  %ret = call i1 @llvm.dx.wave.activeanytrue(i1 %p1)
+  ret i1 %ret
+}
+
+declare i1 @llvm.dx.wave.activeanytrue(i1)
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll
new file mode 100644
index 00000000000000..8b56b60f1da4da
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll
@@ -0,0 +1,17 @@
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32v1.3-vulkan-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32v1.3-vulkan-unknown %s -o - -filetype=obj | spirv-val %}
+
+; CHECK: %[[#bool:]] = OpTypeBool
+; CHECK: %[[#uint:]] = OpTypeInt 32 0
+; CHECK: %[[#scope:]] = OpConstant %[[#uint]] 3
+
+; CHECK-LABEL: Begin function test_wave_aat
+define i1 @test_wave_aat(i1 %p1) {
+entry:
+; CHECK: %[[#param:]] = OpFunctionParameter %[[#bool]]
+; CHECK: %[[#ret:]] = OpGroupNonUniformAny %[[#bool]] %[[#scope]] %[[#param]]
+  %ret = call i1 @llvm.spv.wave.activeanytrue(i1 %p1)
+  ret i1 %ret
+}
+
+declare i1 @llvm.spv.wave.activeanytrue(i1)

>From 3b63a3a3135026114ca25143484a7d0187cbc020 Mon Sep 17 00:00:00 2001
From: Ashley Coleman <ascoleman at microsoft.com>
Date: Tue, 12 Nov 2024 09:38:34 -0700
Subject: [PATCH 02/11] formatting

---
 clang/lib/CodeGen/CGBuiltin.cpp               | 25 +++++++++++++------
 clang/lib/Sema/SemaHLSL.cpp                   |  6 ++---
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |  7 +++---
 3 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index c4a6a9abee63cc..23b89c446213da 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -18963,15 +18963,24 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: {
   case Builtin::BI__builtin_hlsl_wave_active_any_true: {
     // Assert Op->getType() == Bool
 
-    // FIXME: PR Question: Can this be simpler? Looks like Int1Ty isn't  predefined
-    IntegerType* Int1Ty = llvm::Type::getInt1Ty(CGM.getTypes().getLLVMContext());
+    // FIXME: PR Question: Can this be simpler? Looks like Int1Ty isn't
+    // predefined
+    IntegerType *Int1Ty =
+        llvm::Type::getInt1Ty(CGM.getTypes().getLLVMContext());
     Value *Op = EmitScalarExpr(E->getArg(0));
-    assert(Op->getType() == Int1Ty && "wave_active_any_true operand must be a bool");
-
-    // FIXME: PR Question: Re Style SingleRef vs {SingleRef} vs ArrayRef{SingleRef}
-    llvm::FunctionType *FT = llvm::FunctionType::get(Int1Ty, {Int1Ty}, /*isVarArg=*/false);
-    llvm::StringRef Name = Intrinsic::getName(CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic());
-    return EmitRuntimeCall(CGM.CreateRuntimeFunction(FT, Name, {}, /*Local=*/false, /*AssumeConvergent=*/true), {Op}, "hlsl.wave.activeanytrue");
+    assert(Op->getType() == Int1Ty &&
+           "wave_active_any_true operand must be a bool");
+
+    // FIXME: PR Question: Re Style SingleRef vs {SingleRef} vs
+    // ArrayRef{SingleRef}
+    llvm::FunctionType *FT =
+        llvm::FunctionType::get(Int1Ty, {Int1Ty}, /*isVarArg=*/false);
+    llvm::StringRef Name = Intrinsic::getName(
+        CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic());
+    return EmitRuntimeCall(CGM.CreateRuntimeFunction(FT, Name, {},
+                                                     /*Local=*/false,
+                                                     /*AssumeConvergent=*/true),
+                           {Op}, "hlsl.wave.activeanytrue");
   }
   case Builtin::BI__builtin_hlsl_wave_get_lane_index: {
     // We don't define a SPIR-V intrinsic, instead it is a SPIR-V built-in
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index e12a4ce1e75bd6..0377f46dcf1991 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2067,10 +2067,10 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
     break;
   }
   case Builtin::BI__builtin_hlsl_wave_active_any_true: {
-      if (SemaRef.checkArgCount(TheCall, 1))
-        return true;
+    if (SemaRef.checkArgCount(TheCall, 1))
+      return true;
 
-      break;
+    break;
   }
   case Builtin::BI__builtin_hlsl_wave_read_lane_at: {
     if (SemaRef.checkArgCount(TheCall, 2))
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 8d4faedd1c6210..47538da068ec0a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -1766,8 +1766,8 @@ bool SPIRVInstructionSelector::selectSign(Register ResVReg,
 }
 
 bool SPIRVInstructionSelector::selectWaveActiveAnyTrue(Register ResVReg,
-                                                    const SPIRVType *ResType,
-                                                    MachineInstr &I) const {
+                                                       const SPIRVType *ResType,
+                                                       MachineInstr &I) const {
   assert(I.getNumOperands() == 3);
   assert(I.getOperand(2).isReg());
 
@@ -1776,8 +1776,7 @@ bool SPIRVInstructionSelector::selectWaveActiveAnyTrue(Register ResVReg,
   MachineBasicBlock &BB = *I.getParent();
   SPIRVType *IntTy = GR.getOrCreateSPIRVIntegerType(32, I, TII);
 
-  return BuildMI(BB, I, I.getDebugLoc(),
-                 TII.get(SPIRV::OpGroupNonUniformAny))
+  return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpGroupNonUniformAny))
       .addDef(ResVReg)
       .addUse(GR.getSPIRVTypeID(ResType))
       .addUse(GR.getOrCreateConstInt(3, I, IntTy, TII))

>From 37fbd29b7032de3172cf4e372ab0e4674ee76e96 Mon Sep 17 00:00:00 2001
From: Ashley Coleman <ascoleman at microsoft.com>
Date: Tue, 12 Nov 2024 09:41:29 -0700
Subject: [PATCH 03/11] cleanup

---
 clang/lib/CodeGen/CGBuiltin.cpp | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 23b89c446213da..cc1995cd2382c8 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -18961,18 +18961,12 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: {
         ArrayRef<Value *>{Op0, Op1}, nullptr, "hlsl.step");
   }
   case Builtin::BI__builtin_hlsl_wave_active_any_true: {
-    // Assert Op->getType() == Bool
-
-    // FIXME: PR Question: Can this be simpler? Looks like Int1Ty isn't
-    // predefined
     IntegerType *Int1Ty =
         llvm::Type::getInt1Ty(CGM.getTypes().getLLVMContext());
     Value *Op = EmitScalarExpr(E->getArg(0));
     assert(Op->getType() == Int1Ty &&
            "wave_active_any_true operand must be a bool");
 
-    // FIXME: PR Question: Re Style SingleRef vs {SingleRef} vs
-    // ArrayRef{SingleRef}
     llvm::FunctionType *FT =
         llvm::FunctionType::get(Int1Ty, {Int1Ty}, /*isVarArg=*/false);
     llvm::StringRef Name = Intrinsic::getName(

>From fcd1949d0e82d39c2808700bbd3b0ecd0bdc199d Mon Sep 17 00:00:00 2001
From: Ashley Coleman <ascoleman at microsoft.com>
Date: Tue, 12 Nov 2024 16:47:38 -0700
Subject: [PATCH 04/11] Address comments

---
 clang/lib/CodeGen/CGBuiltin.cpp                          | 9 ++++-----
 clang/lib/Sema/SemaHLSL.cpp                              | 6 ------
 clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl   | 4 ++--
 llvm/lib/Target/DirectX/DXIL.td                          | 3 +--
 llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp       | 6 ++----
 llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll           | 2 +-
 .../CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll   | 4 ++--
 7 files changed, 12 insertions(+), 22 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 88960bffe0bee7..b2261f650616d3 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -19109,20 +19109,19 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: {
         ArrayRef<Value *>{Op0, Op1}, nullptr, "hlsl.step");
   }
   case Builtin::BI__builtin_hlsl_wave_active_any_true: {
-    IntegerType *Int1Ty =
-        llvm::Type::getInt1Ty(CGM.getTypes().getLLVMContext());
     Value *Op = EmitScalarExpr(E->getArg(0));
-    assert(Op->getType() == Int1Ty &&
-           "wave_active_any_true operand must be a bool");
+    llvm::Type *Ty = Op->getType();
+    assert(Ty->isIntegerTy(1) && "wave_active_any_true operand must be a bool");
 
     llvm::FunctionType *FT =
-        llvm::FunctionType::get(Int1Ty, {Int1Ty}, /*isVarArg=*/false);
+        llvm::FunctionType::get(Ty, {Ty}, /*isVarArg=*/false);
     llvm::StringRef Name = Intrinsic::getName(
         CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic());
     return EmitRuntimeCall(CGM.CreateRuntimeFunction(FT, Name, {},
                                                      /*Local=*/false,
                                                      /*AssumeConvergent=*/true),
                            {Op}, "hlsl.wave.activeanytrue");
+  }
   case Builtin::BI__builtin_hlsl_wave_active_count_bits: {
     Value *OpExpr = EmitScalarExpr(E->getArg(0));
     Intrinsic::ID ID = CGM.getHLSLRuntime().getWaveActiveCountBitsIntrinsic();
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 8aa0b7520b05eb..65b0d9cd65637f 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2091,12 +2091,6 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
       return true;
     break;
   }
-  case Builtin::BI__builtin_hlsl_wave_active_any_true: {
-    if (SemaRef.checkArgCount(TheCall, 1))
-      return true;
-
-    break;
-  }
   case Builtin::BI__builtin_hlsl_wave_read_lane_at: {
     if (SemaRef.checkArgCount(TheCall, 2))
       return true;
diff --git a/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl b/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl
index d8233c45e0ff2d..dd7a9dee5c3f1e 100644
--- a/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -fnative-half-type -triple \
+// RUN: %clang_cc1 -finclude-default-header -fnative-half-type -triple \
 // RUN:   dxil-pc-shadermodel6.3-compute %s -emit-llvm -disable-llvm-passes -o - | \
 // RUN:   FileCheck %s --check-prefixes=CHECK,CHECK-DXIL
-// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -fnative-half-type -triple \
+// RUN: %clang_cc1 -finclude-default-header -fnative-half-type -triple \
 // RUN:   spirv-pc-vulkan-compute %s -emit-llvm -disable-llvm-passes -o - | \
 // RUN:   FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV
 
diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td
index 9b5e2b5ce1e92a..cb0a0a17492bb5 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -202,7 +202,6 @@ defset list<DXILOpClass> OpClasses = {
   def unpack4x8 : DXILOpClass;
   def viewID : DXILOpClass;
   def waveActiveAllEqual : DXILOpClass;
-  def waveActiveAnyTrue : DXILOpClass;
   def waveActiveBallot : DXILOpClass;
   def waveActiveBit : DXILOpClass;
   def waveActiveOp : DXILOpClass;
@@ -854,7 +853,7 @@ def CreateHandleFromBinding : DXILOp<217, createHandleFromBinding> {
   let stages = [Stages<DXIL1_6, [all_stages]>];
 }
 
-def WaveActiveAnyTrue : DXILOp<113, waveActiveAnyTrue> {
+def WaveActiveAnyTrue : DXILOp<113, waveAnyTrue> {
   let Doc = "returns true if the expression is true in any of the active lanes in the current wave";
   let LLVMIntrinsic = int_dx_wave_activeanytrue;
   let arguments = [Int1Ty];
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 728880a855f1c5..98735c2582ffa2 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -1929,15 +1929,13 @@ bool SPIRVInstructionSelector::selectWaveActiveAnyTrue(Register ResVReg,
   assert(I.getNumOperands() == 3);
   assert(I.getOperand(2).isReg());
 
-  // IntTy is used to define the execution scope, set to 3 to denote a
-  // cross-lane interaction equivalent to a SPIR-V subgroup.
   MachineBasicBlock &BB = *I.getParent();
   SPIRVType *IntTy = GR.getOrCreateSPIRVIntegerType(32, I, TII);
 
   return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpGroupNonUniformAny))
       .addDef(ResVReg)
       .addUse(GR.getSPIRVTypeID(ResType))
-      .addUse(GR.getOrCreateConstInt(3, I, IntTy, TII))
+      .addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy, TII))
       .addUse(I.getOperand(2).getReg());
 }
 
@@ -1987,7 +1985,7 @@ bool SPIRVInstructionSelector::selectWaveReadLaneAt(Register ResVReg,
                  TII.get(SPIRV::OpGroupNonUniformShuffle))
       .addDef(ResVReg)
       .addUse(GR.getSPIRVTypeID(ResType))
-      .addUse(GR.getOrCreateConstInt(3, I, IntTy, TII))
+      .addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy, TII))
       .addUse(I.getOperand(2).getReg())
       .addUse(I.getOperand(3).getReg());
 }
diff --git a/llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll b/llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll
index cc97eb2eedcd60..8f7ae9ea7b370b 100644
--- a/llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll
+++ b/llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll
@@ -2,7 +2,7 @@
 
 define noundef i1 @wave_aat_simple(i1 noundef %p1) {
 entry:
-; CHECK: call i1 @dx.op.waveActiveAnyTrue(i32 113, i1 %p1)
+; CHECK: call i1 @dx.op.waveAnyTrue(i32 113, i1 %p1)
   %ret = call i1 @llvm.dx.wave.activeanytrue(i1 %p1)
   ret i1 %ret
 }
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll
index 8b56b60f1da4da..25d195a776ab73 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll
@@ -1,5 +1,5 @@
-; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32v1.3-vulkan-unknown %s -o - | FileCheck %s
-; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32v1.3-vulkan-unknown %s -o - -filetype=obj | spirv-val %}
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32v1.5-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32v1.5-unknown-unknown %s -o - -filetype=obj | spirv-val %}
 
 ; CHECK: %[[#bool:]] = OpTypeBool
 ; CHECK: %[[#uint:]] = OpTypeInt 32 0

>From dd6eff10aa8ec763edbfecb484a3130b4d8704e1 Mon Sep 17 00:00:00 2001
From: Ashley Coleman <ascoleman at microsoft.com>
Date: Wed, 13 Nov 2024 10:02:03 -0700
Subject: [PATCH 05/11] Address comments

---
 clang/lib/CodeGen/CGBuiltin.cpp                       | 11 +++--------
 .../test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl  |  1 +
 .../SemaHLSL/BuiltIns/WaveActiveAnyTrue-errors.hlsl   |  2 +-
 3 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index b2261f650616d3..ddff01acb134a0 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -19113,14 +19113,9 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: {
     llvm::Type *Ty = Op->getType();
     assert(Ty->isIntegerTy(1) && "wave_active_any_true operand must be a bool");
 
-    llvm::FunctionType *FT =
-        llvm::FunctionType::get(Ty, {Ty}, /*isVarArg=*/false);
-    llvm::StringRef Name = Intrinsic::getName(
-        CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic());
-    return EmitRuntimeCall(CGM.CreateRuntimeFunction(FT, Name, {},
-                                                     /*Local=*/false,
-                                                     /*AssumeConvergent=*/true),
-                           {Op}, "hlsl.wave.activeanytrue");
+    Intrinsic::ID ID = CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic();
+    return EmitRuntimeCall(
+        Intrinsic::getOrInsertDeclaration(&CGM.getModule(), ID), {Op});
   }
   case Builtin::BI__builtin_hlsl_wave_active_count_bits: {
     Value *OpExpr = EmitScalarExpr(E->getArg(0));
diff --git a/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl b/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl
index dd7a9dee5c3f1e..c8dc45aa396dec 100644
--- a/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl
@@ -13,5 +13,6 @@ bool test(bool p1) {
   // CHECK-SPIRV:  %[[RET:.*]] = call spir_func i1 @llvm.spv.wave.activeanytrue(i1 %{{[a-zA-Z0-9]+}}) [ "convergencectrl"(token %[[#entry_tok0]]) ]
   // CHECK-DXIL:  %[[RET:.*]] = call i1 @llvm.dx.wave.activeanytrue(i1 %{{[a-zA-Z0-9]+}})
   // CHECK:  ret i1 %[[RET]]
+  // CHECK: fex
   return WaveActiveAnyTrue(p1);
 }
diff --git a/clang/test/SemaHLSL/BuiltIns/WaveActiveAnyTrue-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/WaveActiveAnyTrue-errors.hlsl
index 48fda7b571fca7..875aae06517020 100644
--- a/clang/test/SemaHLSL/BuiltIns/WaveActiveAnyTrue-errors.hlsl
+++ b/clang/test/SemaHLSL/BuiltIns/WaveActiveAnyTrue-errors.hlsl
@@ -15,7 +15,7 @@ struct Foo
   int a;
 };
 
-bool test_type_check_2(Foo p0) {
+bool test_type_check(Foo p0) {
   return __builtin_hlsl_wave_active_any_true(p0);
   // expected-error at -1 {{no viable conversion from 'Foo' to 'bool'}}
 }

>From 9c43edfa9ea48383748d3e919f37f7337e048465 Mon Sep 17 00:00:00 2001
From: Ashley Coleman <ascoleman at microsoft.com>
Date: Wed, 13 Nov 2024 10:09:52 -0700
Subject: [PATCH 06/11] cleanup

---
 clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl | 1 -
 1 file changed, 1 deletion(-)

diff --git a/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl b/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl
index c8dc45aa396dec..dd7a9dee5c3f1e 100644
--- a/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl
@@ -13,6 +13,5 @@ bool test(bool p1) {
   // CHECK-SPIRV:  %[[RET:.*]] = call spir_func i1 @llvm.spv.wave.activeanytrue(i1 %{{[a-zA-Z0-9]+}}) [ "convergencectrl"(token %[[#entry_tok0]]) ]
   // CHECK-DXIL:  %[[RET:.*]] = call i1 @llvm.dx.wave.activeanytrue(i1 %{{[a-zA-Z0-9]+}})
   // CHECK:  ret i1 %[[RET]]
-  // CHECK: fex
   return WaveActiveAnyTrue(p1);
 }

>From 7823ce6bc12b7ab88e4d64608b3c27129d6d01aa Mon Sep 17 00:00:00 2001
From: Ashley Coleman <ascoleman at microsoft.com>
Date: Thu, 14 Nov 2024 14:59:36 -0700
Subject: [PATCH 07/11] Rename intrinsic

---
 clang/lib/CodeGen/CGHLSLRuntime.h                         | 2 +-
 clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl    | 4 ++--
 llvm/include/llvm/IR/IntrinsicsDirectX.td                 | 2 +-
 llvm/include/llvm/IR/IntrinsicsSPIRV.td                   | 2 +-
 llvm/lib/Target/DirectX/DXIL.td                           | 2 +-
 llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp        | 4 ++--
 llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll            | 6 +++---
 .../CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll    | 8 ++++----
 8 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h
index e8413a5baa32e9..a8e0ed42b79a35 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -91,7 +91,7 @@ class CGHLSLRuntime {
   GENERATE_HLSL_INTRINSIC_FUNCTION(UDot, udot)
   GENERATE_HLSL_INTRINSIC_FUNCTION(Dot4AddI8Packed, dot4add_i8packed)
   GENERATE_HLSL_INTRINSIC_FUNCTION(Dot4AddU8Packed, dot4add_u8packed)
-  GENERATE_HLSL_INTRINSIC_FUNCTION(WaveActiveAnyTrue, wave_activeanytrue)
+  GENERATE_HLSL_INTRINSIC_FUNCTION(WaveActiveAnyTrue, wave_any)
   GENERATE_HLSL_INTRINSIC_FUNCTION(WaveActiveCountBits, wave_active_countbits)
   GENERATE_HLSL_INTRINSIC_FUNCTION(WaveIsFirstLane, wave_is_first_lane)
   GENERATE_HLSL_INTRINSIC_FUNCTION(WaveReadLaneAt, wave_readlane)
diff --git a/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl b/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl
index dd7a9dee5c3f1e..d657a3f8357b08 100644
--- a/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/WaveActiveAnyTrue.hlsl
@@ -10,8 +10,8 @@
 // CHECK-LABEL: test
 bool test(bool p1) {
   // CHECK-SPIRV: %[[#entry_tok0:]] = call token @llvm.experimental.convergence.entry()
-  // CHECK-SPIRV:  %[[RET:.*]] = call spir_func i1 @llvm.spv.wave.activeanytrue(i1 %{{[a-zA-Z0-9]+}}) [ "convergencectrl"(token %[[#entry_tok0]]) ]
-  // CHECK-DXIL:  %[[RET:.*]] = call i1 @llvm.dx.wave.activeanytrue(i1 %{{[a-zA-Z0-9]+}})
+  // CHECK-SPIRV:  %[[RET:.*]] = call spir_func i1 @llvm.spv.wave.any(i1 %{{[a-zA-Z0-9]+}}) [ "convergencectrl"(token %[[#entry_tok0]]) ]
+  // CHECK-DXIL:  %[[RET:.*]] = call i1 @llvm.dx.wave.any(i1 %{{[a-zA-Z0-9]+}})
   // CHECK:  ret i1 %[[RET]]
   return WaveActiveAnyTrue(p1);
 }
diff --git a/llvm/include/llvm/IR/IntrinsicsDirectX.td b/llvm/include/llvm/IR/IntrinsicsDirectX.td
index 8ed81e9852c863..58e5f44789c9cf 100644
--- a/llvm/include/llvm/IR/IntrinsicsDirectX.td
+++ b/llvm/include/llvm/IR/IntrinsicsDirectX.td
@@ -91,9 +91,9 @@ def int_dx_umad : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLV
 def int_dx_normalize : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty], [IntrNoMem]>;
 def int_dx_rsqrt  : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
 def int_dx_wave_active_countbits : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i1_ty], [IntrConvergent, IntrNoMem]>;
+def int_dx_wave_any : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_i1_ty], [IntrConvergent]>;
 def int_dx_wave_getlaneindex : DefaultAttrsIntrinsic<[llvm_i32_ty], [], [IntrConvergent, IntrNoMem]>;
 def int_dx_wave_is_first_lane : DefaultAttrsIntrinsic<[llvm_i1_ty], [], [IntrConvergent]>;
-def int_dx_wave_activeanytrue : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_i1_ty], [IntrConvergent]>;
 def int_dx_wave_readlane : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>, llvm_i32_ty], [IntrConvergent, IntrNoMem]>;
 def int_dx_sign : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_any_ty], [IntrNoMem]>;
 def int_dx_step : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty, LLVMMatchType<0>], [IntrNoMem]>;
diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
index 02f9acc3401555..8dfdcf01e0d757 100644
--- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td
+++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
@@ -86,9 +86,9 @@ let TargetPrefix = "spv" in {
   def int_spv_dot4add_i8packed : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
   def int_spv_dot4add_u8packed : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
   def int_spv_wave_active_countbits : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i1_ty], [IntrConvergent, IntrNoMem]>;
+  def int_spv_wave_any : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_i1_ty], [IntrConvergent]>;
   def int_spv_wave_is_first_lane : DefaultAttrsIntrinsic<[llvm_i1_ty], [], [IntrConvergent]>;
   def int_spv_wave_readlane : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>, llvm_i32_ty], [IntrConvergent, IntrNoMem]>;
-  def int_spv_wave_activeanytrue : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_i1_ty], [IntrConvergent]>;
   def int_spv_sign : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_any_ty], [IntrNoMem]>;
   def int_spv_radians : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty], [IntrNoMem]>;
   def int_spv_group_memory_barrier_with_group_sync : DefaultAttrsIntrinsic<[], [], []>;
diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td
index cb0a0a17492bb5..04fee894a46b06 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -855,7 +855,7 @@ def CreateHandleFromBinding : DXILOp<217, createHandleFromBinding> {
 
 def WaveActiveAnyTrue : DXILOp<113, waveAnyTrue> {
   let Doc = "returns true if the expression is true in any of the active lanes in the current wave";
-  let LLVMIntrinsic = int_dx_wave_activeanytrue;
+  let LLVMIntrinsic = int_dx_wave_any;
   let arguments = [Int1Ty];
   let result = Int1Ty;
   let stages = [Stages<DXIL1_0, [all_stages]>];
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 98735c2582ffa2..23ba5f4b3282ef 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -2800,6 +2800,8 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
     return selectExtInst(ResVReg, ResType, I, CL::s_clamp, GL::SClamp);
   case Intrinsic::spv_wave_active_countbits:
     return selectWaveActiveCountBits(ResVReg, ResType, I);
+  case Intrinsic::spv_wave_any:
+    return selectWaveActiveAnyTrue(ResVReg, ResType, I);
   case Intrinsic::spv_wave_is_first_lane: {
     SPIRVType *IntTy = GR.getOrCreateSPIRVIntegerType(32, I, TII);
     return BuildMI(BB, I, I.getDebugLoc(),
@@ -2808,8 +2810,6 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
         .addUse(GR.getSPIRVTypeID(ResType))
         .addUse(GR.getOrCreateConstInt(3, I, IntTy, TII));
   }
-  case Intrinsic::spv_wave_activeanytrue:
-    return selectWaveActiveAnyTrue(ResVReg, ResType, I);
   case Intrinsic::spv_wave_readlane:
     return selectWaveReadLaneAt(ResVReg, ResType, I);
   case Intrinsic::spv_step:
diff --git a/llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll b/llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll
index 8f7ae9ea7b370b..5adf050a76c98f 100644
--- a/llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll
+++ b/llvm/test/CodeGen/DirectX/WaveActiveAnyTrue.ll
@@ -1,10 +1,10 @@
 ; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-compute %s | FileCheck %s
 
-define noundef i1 @wave_aat_simple(i1 noundef %p1) {
+define noundef i1 @wave_any_simple(i1 noundef %p1) {
 entry:
 ; CHECK: call i1 @dx.op.waveAnyTrue(i32 113, i1 %p1)
-  %ret = call i1 @llvm.dx.wave.activeanytrue(i1 %p1)
+  %ret = call i1 @llvm.dx.wave.any(i1 %p1)
   ret i1 %ret
 }
 
-declare i1 @llvm.dx.wave.activeanytrue(i1)
+declare i1 @llvm.dx.wave.any(i1)
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll
index 25d195a776ab73..39418bd35ff4c3 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll
@@ -5,13 +5,13 @@
 ; CHECK: %[[#uint:]] = OpTypeInt 32 0
 ; CHECK: %[[#scope:]] = OpConstant %[[#uint]] 3
 
-; CHECK-LABEL: Begin function test_wave_aat
-define i1 @test_wave_aat(i1 %p1) {
+; CHECK-LABEL: Begin function test_wave_any
+define i1 @test_wave_any(i1 %p1) {
 entry:
 ; CHECK: %[[#param:]] = OpFunctionParameter %[[#bool]]
 ; CHECK: %[[#ret:]] = OpGroupNonUniformAny %[[#bool]] %[[#scope]] %[[#param]]
-  %ret = call i1 @llvm.spv.wave.activeanytrue(i1 %p1)
+  %ret = call i1 @llvm.spv.wave.any(i1 %p1)
   ret i1 %ret
 }
 
-declare i1 @llvm.spv.wave.activeanytrue(i1)
+declare i1 @llvm.spv.wave.any(i1)

>From dfeb3276bf4b67022e4b39919a8a2e8e353c9777 Mon Sep 17 00:00:00 2001
From: Ashley Coleman <ascoleman at microsoft.com>
Date: Thu, 14 Nov 2024 15:40:25 -0700
Subject: [PATCH 08/11] address comments

---
 llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp                | 4 +++-
 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll | 4 ++--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index e8641b3a105dec..17912a398b982f 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -630,6 +630,9 @@ void RequirementHandler::initAvailableCapabilities(const SPIRVSubtarget &ST) {
   addAvailableCaps({Capability::Shader, Capability::Linkage, Capability::Int8,
                     Capability::Int16});
 
+  if (ST.isAtLeastSPIRVVer(VersionTuple(1, 3)))
+    addAvailableCaps({Capability::GroupNonUniformVote});
+
   if (ST.isAtLeastSPIRVVer(VersionTuple(1, 6)))
     addAvailableCaps({Capability::DotProduct, Capability::DotProductInputAll,
                       Capability::DotProductInput4x8Bit,
@@ -675,7 +678,6 @@ void RequirementHandler::initAvailableCapabilitiesForOpenCL(
     addAvailableCaps({Capability::SubgroupDispatch, Capability::PipeStorage});
   if (ST.isAtLeastSPIRVVer(VersionTuple(1, 3)))
     addAvailableCaps({Capability::GroupNonUniform,
-                      Capability::GroupNonUniformVote,
                       Capability::GroupNonUniformArithmetic,
                       Capability::GroupNonUniformBallot,
                       Capability::GroupNonUniformClustered,
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll
index 39418bd35ff4c3..66bc9619fb74f9 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveAnyTrue.ll
@@ -1,5 +1,5 @@
-; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32v1.5-unknown-unknown %s -o - | FileCheck %s
-; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32v1.5-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %}
 
 ; CHECK: %[[#bool:]] = OpTypeBool
 ; CHECK: %[[#uint:]] = OpTypeInt 32 0

>From 66848d80e6da2e433bdc332562c862ef1bf4e3e7 Mon Sep 17 00:00:00 2001
From: Ashley Coleman <me at ashleycoleman.me>
Date: Thu, 14 Nov 2024 16:44:57 -0700
Subject: [PATCH 09/11] Apply suggestions from code review

Co-authored-by: Finn Plummer <50529406+inbelic at users.noreply.github.com>
---
 clang/lib/CodeGen/CGBuiltin.cpp           | 2 +-
 llvm/include/llvm/IR/IntrinsicsDirectX.td | 2 +-
 llvm/include/llvm/IR/IntrinsicsSPIRV.td   | 2 +-
 llvm/lib/Target/DirectX/DXIL.td           | 1 -
 4 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 0602bcf85e5574..af03d477f13509 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -19123,7 +19123,7 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: {
   case Builtin::BI__builtin_hlsl_wave_active_any_true: {
     Value *Op = EmitScalarExpr(E->getArg(0));
     llvm::Type *Ty = Op->getType();
-    assert(Ty->isIntegerTy(1) && "wave_active_any_true operand must be a bool");
+    assert(Ty->isIntegerTy(1) && "Intrinsic WaveActiveAnyTrue operand must be a bool");
 
     Intrinsic::ID ID = CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic();
     return EmitRuntimeCall(
diff --git a/llvm/include/llvm/IR/IntrinsicsDirectX.td b/llvm/include/llvm/IR/IntrinsicsDirectX.td
index 52f3845ecba6df..a5fe1e55f5cc13 100644
--- a/llvm/include/llvm/IR/IntrinsicsDirectX.td
+++ b/llvm/include/llvm/IR/IntrinsicsDirectX.td
@@ -94,7 +94,7 @@ def int_dx_umad : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLV
 def int_dx_normalize : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty], [IntrNoMem]>;
 def int_dx_rsqrt  : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
 def int_dx_wave_active_countbits : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i1_ty], [IntrConvergent, IntrNoMem]>;
-def int_dx_wave_any : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_i1_ty], [IntrConvergent]>;
+def int_dx_wave_any : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_i1_ty], [IntrConvergent, IntrNoMem]>;
 def int_dx_wave_getlaneindex : DefaultAttrsIntrinsic<[llvm_i32_ty], [], [IntrConvergent, IntrNoMem]>;
 def int_dx_wave_is_first_lane : DefaultAttrsIntrinsic<[llvm_i1_ty], [], [IntrConvergent]>;
 def int_dx_wave_readlane : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>, llvm_i32_ty], [IntrConvergent, IntrNoMem]>;
diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
index 9af8ae70646283..28db6fd8117790 100644
--- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td
+++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
@@ -86,7 +86,7 @@ let TargetPrefix = "spv" in {
   def int_spv_dot4add_i8packed : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
   def int_spv_dot4add_u8packed : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
   def int_spv_wave_active_countbits : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i1_ty], [IntrConvergent, IntrNoMem]>;
-  def int_spv_wave_any : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_i1_ty], [IntrConvergent]>;
+  def int_spv_wave_any : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_i1_ty], [IntrConvergent, IntrNoMem]>;
   def int_spv_wave_is_first_lane : DefaultAttrsIntrinsic<[llvm_i1_ty], [], [IntrConvergent]>;
   def int_spv_wave_readlane : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>, llvm_i32_ty], [IntrConvergent, IntrNoMem]>;
   def int_spv_sign : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_any_ty], [IntrNoMem]>;
diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td
index 5c1891e855d977..2a499b1d9b75c0 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -859,7 +859,6 @@ def WaveActiveAnyTrue : DXILOp<113, waveAnyTrue> {
   let arguments = [Int1Ty];
   let result = Int1Ty;
   let stages = [Stages<DXIL1_0, [all_stages]>];
-  let attributes = [Attributes<DXIL1_0, [ReadNone]>];
 }
 
 def WaveIsFirstLane :  DXILOp<110, waveIsFirstLane> {

>From 883b2a80002b8e0d0c5222bd302c716df642ba76 Mon Sep 17 00:00:00 2001
From: Ashley Coleman <ascoleman at microsoft.com>
Date: Thu, 14 Nov 2024 16:50:08 -0700
Subject: [PATCH 10/11] format

---
 clang/lib/CodeGen/CGBuiltin.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index af03d477f13509..d6e90e7821ceec 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -19123,7 +19123,8 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: {
   case Builtin::BI__builtin_hlsl_wave_active_any_true: {
     Value *Op = EmitScalarExpr(E->getArg(0));
     llvm::Type *Ty = Op->getType();
-    assert(Ty->isIntegerTy(1) && "Intrinsic WaveActiveAnyTrue operand must be a bool");
+    assert(Ty->isIntegerTy(1) &&
+           "Intrinsic WaveActiveAnyTrue operand must be a bool");
 
     Intrinsic::ID ID = CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic();
     return EmitRuntimeCall(

>From 4dd242a1abbe2a402e7ed6e4bca522357286f980 Mon Sep 17 00:00:00 2001
From: Ashley Coleman <ascoleman at microsoft.com>
Date: Thu, 14 Nov 2024 16:54:52 -0700
Subject: [PATCH 11/11] Address comments

---
 llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index 3e887a3b03150c..3093521b962fd3 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -631,7 +631,13 @@ void RequirementHandler::initAvailableCapabilities(const SPIRVSubtarget &ST) {
                     Capability::Int16});
 
   if (ST.isAtLeastSPIRVVer(VersionTuple(1, 3)))
-    addAvailableCaps({Capability::GroupNonUniformVote});
+    addAvailableCaps({Capability::GroupNonUniform,
+                      Capability::GroupNonUniformVote,
+                      Capability::GroupNonUniformArithmetic,
+                      Capability::GroupNonUniformBallot,
+                      Capability::GroupNonUniformClustered,
+                      Capability::GroupNonUniformShuffle,
+                      Capability::GroupNonUniformShuffleRelative});
 
   if (ST.isAtLeastSPIRVVer(VersionTuple(1, 6)))
     addAvailableCaps({Capability::DotProduct, Capability::DotProductInputAll,
@@ -677,13 +683,6 @@ void RequirementHandler::initAvailableCapabilitiesForOpenCL(
   if (ST.isAtLeastSPIRVVer(VersionTuple(1, 1)) &&
       ST.isAtLeastOpenCLVer(VersionTuple(2, 2)))
     addAvailableCaps({Capability::SubgroupDispatch, Capability::PipeStorage});
-  if (ST.isAtLeastSPIRVVer(VersionTuple(1, 3)))
-    addAvailableCaps({Capability::GroupNonUniform,
-                      Capability::GroupNonUniformArithmetic,
-                      Capability::GroupNonUniformBallot,
-                      Capability::GroupNonUniformClustered,
-                      Capability::GroupNonUniformShuffle,
-                      Capability::GroupNonUniformShuffleRelative});
   if (ST.isAtLeastSPIRVVer(VersionTuple(1, 4)))
     addAvailableCaps({Capability::DenormPreserve, Capability::DenormFlushToZero,
                       Capability::SignedZeroInfNanPreserve,



More information about the cfe-commits mailing list