https://github.com/bob80905 updated 
https://github.com/llvm/llvm-project/pull/236932

>From 0ce9b93b7ea0d23ed200ac932013286c7c9152e2 Mon Sep 17 00:00:00 2001
From: Joshua Batista <[email protected]>
Date: Thu, 29 Oct 2026 13:39:25 -0700
Subject: [PATCH 1/3] first attempt

---
 clang/include/clang/Basic/Builtins.td         |  6 ++++
 clang/include/clang/Basic/HLSLIntrinsics.td   | 11 ++++++
 clang/lib/CodeGen/CGHLSLBuiltins.cpp          |  5 +++
 clang/lib/CodeGen/CGHLSLRuntime.h             |  1 +
 clang/test/CodeGenHLSL/builtins/QuadAll.hlsl  | 24 +++++++++++++
 .../BuiltIns/QuadAll-availability.hlsl        | 13 +++++++
 .../SemaHLSL/BuiltIns/QuadAll-errors.hlsl     | 28 +++++++++++++++
 llvm/docs/SPIRVUsage.md                       |  3 ++
 llvm/include/llvm/IR/IntrinsicsDirectX.td     |  4 +++
 llvm/include/llvm/IR/IntrinsicsSPIRV.td       |  4 +++
 llvm/lib/Target/DirectX/DXIL.td               | 16 +++++++++
 llvm/lib/Target/DirectX/DXILShaderFlags.cpp   |  2 +-
 llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp    |  4 ++-
 llvm/lib/Target/SPIRV/SPIRVInstrInfo.td       |  5 +++
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |  7 ++++
 llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp | 16 +++++++++
 .../lib/Target/SPIRV/SPIRVSymbolicOperands.td |  3 ++
 llvm/test/CodeGen/DirectX/QuadAll-errors.ll   | 22 ++++++++++++
 llvm/test/CodeGen/DirectX/QuadAll.ll          | 20 +++++++++++
 .../CodeGen/DirectX/ShaderFlags/wave-ops.ll   |  7 ++++
 .../CodeGen/SPIRV/hlsl-intrinsics/QuadAll.ll  | 36 +++++++++++++++++++
 21 files changed, 235 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/QuadAll.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/QuadAll-availability.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/QuadAll-errors.hlsl
 create mode 100644 llvm/test/CodeGen/DirectX/QuadAll-errors.ll
 create mode 100644 llvm/test/CodeGen/DirectX/QuadAll.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/QuadAll.ll

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index d04fd899eb63a6..519bdbc9899def 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -5795,6 +5795,12 @@ def HLSLWavePrefixProduct : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void(...)";
 }
 
+def HLSLQuadAll : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_quad_all"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "bool(bool)";
+}
+
 def HLSLQuadReadAcrossX : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_quad_read_across_x"];
   let Attributes = [NoThrow, Const];
diff --git a/clang/include/clang/Basic/HLSLIntrinsics.td 
b/clang/include/clang/Basic/HLSLIntrinsics.td
index fd59e3477b8c79..05e7f63f4e2130 100644
--- a/clang/include/clang/Basic/HLSLIntrinsics.td
+++ b/clang/include/clang/Basic/HLSLIntrinsics.td
@@ -1368,6 +1368,17 @@ def hlsl_pow : HLSLTwoArgBuiltin<"pow", 
"__builtin_elementwise_pow"> {
   let VaryingLongVector = 1;
 }
 
+def hlsl_quad_all : HLSLBuiltin<"QuadAll", "__builtin_hlsl_quad_all"> {
+  let Doc = [{
+\brief Returns true if the condition is true in all active lanes in the quad.
+\param Cond The condition to evaluate.
+}];
+  let Args = [BoolTy];
+  let ReturnType = BoolTy;
+  let IsConvergent = 1;
+  let Availability = SM6_7;
+}
+
 // Reads the value from the lane across the X axis of the quad.
 def hlsl_quad_read_across_x :
     HLSLOneArgBuiltin<"QuadReadAcrossX",
diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp 
b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
index fc422918499ed2..a2737287b01a88 100644
--- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp
+++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
@@ -1728,6 +1728,11 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
     return EmitIntrinsicCall(IID, {OpExpr->getType()}, ArrayRef{OpExpr},
                              "hlsl.wave.prefix.product");
   }
+  case Builtin::BI__builtin_hlsl_quad_all: {
+    Value *Op = EmitScalarExpr(E->getArg(0));
+    Intrinsic::ID ID = CGM.getHLSLRuntime().getQuadAllIntrinsic();
+    return EmitIntrinsicCall(ID, {Op});
+  }
   case Builtin::BI__builtin_hlsl_quad_read_across_x: {
     Value *OpExpr = EmitScalarExpr(E->getArg(0));
     Intrinsic::ID ID = CGM.getHLSLRuntime().getQuadReadAcrossXIntrinsic();
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h 
b/clang/lib/CodeGen/CGHLSLRuntime.h
index 1957b946826d37..af2cda88318efd 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -159,6 +159,7 @@ class CGHLSLRuntime {
                                         subgroup_size)
   GENERATE_HLSL_INTRINSIC_FUNCTION(WaveReadLaneAt, wave_readlane)
   GENERATE_HLSL_INTRINSIC_FUNCTION(WaveReadLaneFirst, wave_readlane_first)
+  GENERATE_HLSL_INTRINSIC_FUNCTION(QuadAll, quad_all)
   GENERATE_HLSL_INTRINSIC_FUNCTION(QuadReadAcrossX, quad_read_across_x)
   GENERATE_HLSL_INTRINSIC_FUNCTION(QuadReadAcrossY, quad_read_across_y)
   GENERATE_HLSL_INTRINSIC_FUNCTION(QuadReadAcrossDiagonal,
diff --git a/clang/test/CodeGenHLSL/builtins/QuadAll.hlsl 
b/clang/test/CodeGenHLSL/builtins/QuadAll.hlsl
new file mode 100644
index 00000000000000..986178e8d9ab1f
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/QuadAll.hlsl
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN:   dxil-pc-shadermodel6.7-library %s -emit-llvm \
+// RUN:   -disable-llvm-passes -o - | FileCheck %s --check-prefixes=CHECK,DXIL
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN:   spirv-pc-vulkan-library %s -emit-llvm -disable-llvm-passes -o - | \
+// RUN:   FileCheck %s --check-prefixes=CHECK,SPIRV
+
+// CHECK-LABEL: define {{.*}}test_quad_all{{.*}}(
+// SPIRV: %[[TOKEN:.*]] = call token @llvm.experimental.convergence.entry()
+// DXIL: %[[RET:.*]] = call i1 @llvm.dx.quad.all(i1 %{{.*}})
+// SPIRV: %[[RET:.*]] = call i1 @llvm.spv.quad.all(i1 %{{.*}}) [ 
"convergencectrl"(token %[[TOKEN]]) ]
+// CHECK: ret i1 %[[RET]]
+bool test_quad_all(bool cond) {
+  return QuadAll(cond);
+}
+
+// CHECK-LABEL: define {{.*}}test_builtin{{.*}}(
+// SPIRV: %[[TOKEN:.*]] = call token @llvm.experimental.convergence.entry()
+// DXIL: %[[RET:.*]] = call i1 @llvm.dx.quad.all(i1 %{{.*}})
+// SPIRV: %[[RET:.*]] = call i1 @llvm.spv.quad.all(i1 %{{.*}}) [ 
"convergencectrl"(token %[[TOKEN]]) ]
+// CHECK: ret i1 %[[RET]]
+bool test_builtin(bool cond) {
+  return __builtin_hlsl_quad_all(cond);
+}
diff --git a/clang/test/SemaHLSL/BuiltIns/QuadAll-availability.hlsl 
b/clang/test/SemaHLSL/BuiltIns/QuadAll-availability.hlsl
new file mode 100644
index 00000000000000..c6b3bea64e760a
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/QuadAll-availability.hlsl
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN:   dxil-pc-shadermodel6.6-library %s -fhlsl-strict-availability \
+// RUN:   -fsyntax-only -verify -verify-ignore-unexpected=note
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN:   dxil-pc-shadermodel6.7-library %s -fhlsl-strict-availability \
+// RUN:   -fsyntax-only -verify=sm67
+
+// sm67-no-diagnostics
+
+bool test_availability(bool cond) {
+  // expected-error@+1 {{'QuadAll' is only available on Shader Model 6.7}}
+  return QuadAll(cond);
+}
diff --git a/clang/test/SemaHLSL/BuiltIns/QuadAll-errors.hlsl 
b/clang/test/SemaHLSL/BuiltIns/QuadAll-errors.hlsl
new file mode 100644
index 00000000000000..b12ca49e1e432f
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/QuadAll-errors.hlsl
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN:   dxil-pc-shadermodel6.7-library %s -fsyntax-only -verify
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN:   spirv-pc-vulkan-library %s -fsyntax-only -verify
+
+bool test_too_few_args() {
+  return __builtin_hlsl_quad_all();
+  // expected-error@-1 {{too few arguments to function call, expected 1}}
+}
+
+bool test_too_many_args(bool cond) {
+  return __builtin_hlsl_quad_all(cond, cond);
+  // expected-error@-1 {{too many arguments to function call, expected 1}}
+}
+
+struct Foo {
+  int value;
+};
+
+bool test_type(Foo value) {
+  return __builtin_hlsl_quad_all(value);
+  // expected-error@-1 {{cannot initialize a parameter of type 'bool'}}
+}
+
+bool test_vector(bool2 value) {
+  return __builtin_hlsl_quad_all(value);
+  // expected-warning@-1 {{implicit conversion turns vector to scalar}}
+}
diff --git a/llvm/docs/SPIRVUsage.md b/llvm/docs/SPIRVUsage.md
index 6f958b3ddffe7d..db41d8ce27a5c7 100644
--- a/llvm/docs/SPIRVUsage.md
+++ b/llvm/docs/SPIRVUsage.md
@@ -231,6 +231,9 @@ Below is a list of supported SPIR-V extensions, sorted 
alphabetically by their e
      - Adds predicated load and store instructions that conditionally read 
from or write to memory based on a boolean predicate.
    * - ``SPV_KHR_maximal_reconvergence``
      - Adds execution mode and capability to enable maximal reconvergence.
+   * - ``SPV_KHR_quad_control``
+     - Adds the quad vote instruction for HLSL `QuadAll`.
+       This instruction also requires `SPV_KHR_maximal_reconvergence`.
    * - ``SPV_ALTERA_blocking_pipes``
      - Adds new pipe read and write functions that have blocking semantics 
instead of the non-blocking semantics of the existing pipe read/write functions.
    * - ``SPV_ALTERA_arbitrary_precision_fixed_point``
diff --git a/llvm/include/llvm/IR/IntrinsicsDirectX.td 
b/llvm/include/llvm/IR/IntrinsicsDirectX.td
index b9b02aeb081916..20a73dda1d1d0b 100644
--- a/llvm/include/llvm/IR/IntrinsicsDirectX.td
+++ b/llvm/include/llvm/IR/IntrinsicsDirectX.td
@@ -488,6 +488,10 @@ let TargetPrefix = "dx" in {
                               [IntrConvergent, IntrNoMem,
                                IntrTriviallyScalarizable]>;
 
+  def int_dx_quad_all
+      : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_i1_ty],
+                              [IntrConvergent, IntrNoMem]>;
+
   def int_dx_quad_read_across_x
       : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>],
                               [IntrConvergent, IntrNoMem,
diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td 
b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
index f9319918694d7d..4213dfaf80dc28 100644
--- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td
+++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
@@ -388,6 +388,10 @@ let TargetPrefix = "spv" in {
                               [IntrConvergent, IntrNoMem,
                                IntrTriviallyScalarizable]>;
 
+  def int_spv_quad_all
+      : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_i1_ty],
+                              [IntrConvergent, IntrNoMem]>;
+
   def int_spv_quad_read_across_x
       : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>],
                               [IntrConvergent, IntrNoMem,
diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td
index 3f81e83b01ecba..9b2ed8b9a39012 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -329,6 +329,8 @@ defvar QuadOpKind_ReadAcrossX = 0;
 defvar QuadOpKind_ReadAcrossY = 1;
 defvar QuadOpKind_ReadAcrossDiagonal = 2;
 
+defvar QuadVoteOpKind_All = 1;
+
 // Intrinsic arg selection
 class IntrinArgSelectType;
 def IntrinArgSelect_Index : IntrinArgSelectType;
@@ -1562,6 +1564,20 @@ def CreateHandleFromHeap : DXILOp<218, 
createHandleFromHeap> {
   let attributes = [Attributes<DXIL1_0, [ReadNone]>];
 }
 
+def QuadVote : DXILOp<222, quadVote> {
+  let Doc = "compares a boolean condition across a quad";
+  let intrinsics = [
+    IntrinSelect<int_dx_quad_all,
+                 [IntrinArgIndex<0>, IntrinArgI8<QuadVoteOpKind_All>]>
+  ];
+  let arguments = [Int1Ty, Int8Ty];
+  let result = OverloadTy;
+  let overloads = [Overloads<DXIL1_7, [Int1Ty]>];
+  let stages = [
+    Stages<DXIL1_7, [library, compute, amplification, mesh, pixel, node]>
+  ];
+}
+
 def BarrierByMemoryType : DXILOp<244, barrierByMemoryType> {
   let Doc = "inserts a memory barrier for the specified memory types";
   let intrinsics = [IntrinSelect<int_dx_barrier_by_memory_type>];
diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp 
b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
index 59953c191497be..946c03f19fa043 100644
--- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
+++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
@@ -79,7 +79,6 @@ static bool checkWaveOps(Intrinsic::ID IID) {
   // case Intrinsic::dx_wave_match:
   // case Intrinsic::dx_wavemulti.*:
   // case Intrinsic::dx_wavemulti.ballot:
-  // case Intrinsic::dx_quad.vote:
   switch (IID) {
   default:
     return false;
@@ -112,6 +111,7 @@ static bool checkWaveOps(Intrinsic::ID IID) {
   case Intrinsic::dx_wave_prefix_product:
   case Intrinsic::dx_wave_prefix_uproduct:
     // Quad Op Variants
+  case Intrinsic::dx_quad_all:
   case Intrinsic::dx_quad_read_across_x:
   case Intrinsic::dx_quad_read_across_y:
   case Intrinsic::dx_quad_read_across_diagonal:
diff --git a/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp 
b/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
index 15f1f2b1b05b36..a430ad49fefb13 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
@@ -180,7 +180,9 @@ static const StringMap<SPIRV::Extension::Extension> 
SPIRVExtensionMap = {
      SPIRV::Extension::Extension::SPV_KHR_poison_freeze},
     {"SPV_KHR_untyped_pointers",
      SPIRV::Extension::Extension::SPV_KHR_untyped_pointers},
-    {"SPV_EXT_long_vector", SPIRV::Extension::Extension::SPV_EXT_long_vector}};
+    {"SPV_EXT_long_vector", SPIRV::Extension::Extension::SPV_EXT_long_vector},
+    {"SPV_KHR_quad_control",
+     SPIRV::Extension::Extension::SPV_KHR_quad_control}};
 
 bool SPIRVExtensionsParser::parse(cl::Option &O, StringRef ArgName,
                                   StringRef ArgValue, ExtensionSet &Vals) {
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td 
b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
index df9ff2c941c85b..56fddff7cfa0d5 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
+++ b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
@@ -901,6 +901,11 @@ def OpGroupNonUniformLogicalOr: 
OpGroupNUGroup<"LogicalOr", 363>;
 def OpGroupNonUniformLogicalXor: OpGroupNUGroup<"LogicalXor", 364>;
 def OpGroupNonUniformQuadSwap: OpGroupNU4<"QuadSwap", 366>;
 
+// SPV_KHR_quad_control
+def OpGroupNonUniformQuadAllKHR
+    : Op<5110, (outs ID:$res), (ins TYPE:$ty, ID:$pred),
+         "$res = OpGroupNonUniformQuadAllKHR $ty $pred">;
+
 // SPV_KHR_subgroup_rotate
 def OpGroupNonUniformRotateKHR: Op<4431, (outs ID:$res),
                   (ins TYPE:$type, ID:$scope, ID:$value, ID:$delta, 
variable_ops),
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp 
b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index b0f1445f6a10be..f07a8f7cea1f89 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -5788,6 +5788,13 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register 
ResVReg,
     return selectWaveExclusiveScanSum(ResVReg, ResType, I);
   case Intrinsic::spv_wave_prefix_product:
     return selectWaveExclusiveScanProduct(ResVReg, ResType, I);
+  case Intrinsic::spv_quad_all:
+    BuildMI(BB, I, I.getDebugLoc(), 
TII.get(SPIRV::OpGroupNonUniformQuadAllKHR))
+        .addDef(ResVReg)
+        .addUse(GR.getSPIRVTypeID(ResType))
+        .addUse(I.getOperand(2).getReg())
+        .constrainAllUses(TII, TRI, RBI);
+    return true;
   case Intrinsic::spv_quad_read_across_x: {
     return selectQuadSwap(ResVReg, ResType, I, /*Direction*/ 0);
   }
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp 
b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index 8f847c17e9d74b..4ae3708ac8e950 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -2138,6 +2138,22 @@ void addInstrRequirements(const MachineInstr &MI,
       Reqs.addCapability(SPIRV::Capability::FunctionPointersINTEL);
     }
     break;
+  case SPIRV::OpGroupNonUniformQuadAllKHR:
+    if (!ST.isAtLeastSPIRVVer(VersionTuple(1, 3)))
+      report_fatal_error("OpGroupNonUniformQuadAllKHR requires SPIR-V 1.3",
+                         false);
+    if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_quad_control))
+      report_fatal_error("OpGroupNonUniformQuadAllKHR instruction requires the 
"
+                         "following SPIR-V extension: SPV_KHR_quad_control",
+                         false);
+    if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_maximal_reconvergence))
+      report_fatal_error("SPV_KHR_quad_control requires the following SPIR-V "
+                         "extension: SPV_KHR_maximal_reconvergence",
+                         false);
+    Reqs.addExtension(SPIRV::Extension::SPV_KHR_quad_control);
+    Reqs.addExtension(SPIRV::Extension::SPV_KHR_maximal_reconvergence);
+    Reqs.addCapability(SPIRV::Capability::QuadControlKHR);
+    break;
   case SPIRV::OpGroupNonUniformRotateKHR:
     if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_subgroup_rotate))
       report_fatal_error("OpGroupNonUniformRotateKHR instruction requires the "
diff --git a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td 
b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
index 00bee6c9518453..8792431da11510 100644
--- a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
+++ b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
@@ -410,6 +410,7 @@ defm SPV_KHR_poison_freeze : ExtensionOperand<139, 
[EnvOpenCL]>;
 defm SPV_KHR_untyped_pointers : ExtensionOperand<140, [EnvOpenCL]>;
 defm SPV_EXT_long_vector : ExtensionOperand<141, [EnvOpenCL, EnvVulkan]>;
 defm SPV_KHR_relaxed_extended_instruction : ExtensionOperand<142, [EnvVulkan, 
EnvOpenCL]>;
+defm SPV_KHR_quad_control : ExtensionOperand<143, [EnvVulkan]>;
 
 
//===----------------------------------------------------------------------===//
 // Multiclass used to define Capabilities enum values and at the same time
@@ -576,6 +577,8 @@ defm ArbitraryPrecisionIntegersALTERA : 
CapabilityOperand<5844, 0, 0, [SPV_ALTER
 defm OptNoneINTEL : CapabilityOperand<6094, 0, 0, [SPV_INTEL_optnone], []>;
 defm OptNoneEXT : CapabilityOperand<6094, 0, 0, [SPV_EXT_optnone], []>;
 defm BitInstructions : CapabilityOperand<6025, 0, 0, 
[SPV_KHR_bit_instructions], []>;
+defm QuadControlKHR
+    : CapabilityOperand<5087, 0, 0, [SPV_KHR_quad_control], []>;
 defm ExpectAssumeKHR : CapabilityOperand<5629, 0, 0, [SPV_KHR_expect_assume], 
[]>;
 defm FunctionPointersINTEL : CapabilityOperand<5603, 0, 0, 
[SPV_INTEL_function_pointers], []>;
 defm IndirectReferencesINTEL : CapabilityOperand<5604, 0, 0, 
[SPV_INTEL_function_pointers], []>;
diff --git a/llvm/test/CodeGen/DirectX/QuadAll-errors.ll 
b/llvm/test/CodeGen/DirectX/QuadAll-errors.ll
new file mode 100644
index 00000000000000..47d649ab352134
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/QuadAll-errors.ll
@@ -0,0 +1,22 @@
+; RUN: not opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.6-compute \
+; RUN:   %s 2>&1 | FileCheck %s --check-prefix=VERSION
+; RUN: not opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.7-vertex \
+; RUN:   %s 2>&1 | FileCheck %s --check-prefix=STAGE
+; RUN: not opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.7-geometry \
+; RUN:   %s 2>&1 | FileCheck %s --check-prefix=STAGE
+; RUN: not opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.7-hull \
+; RUN:   %s 2>&1 | FileCheck %s --check-prefix=STAGE
+; RUN: not opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.7-domain \
+; RUN:   %s 2>&1 | FileCheck %s --check-prefix=STAGE
+; RUN: not opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.7-raygeneration 
\
+; RUN:   %s 2>&1 | FileCheck %s --check-prefix=STAGE
+
+; VERSION: Cannot create QuadVote operation: No valid overloads for DXIL 
version 1.6
+; STAGE: Cannot create QuadVote operation: Invalid stage
+
+define i1 @quad_all(i1 %cond) {
+  %ret = call i1 @llvm.dx.quad.all(i1 %cond)
+  ret i1 %ret
+}
+
+declare i1 @llvm.dx.quad.all(i1)
diff --git a/llvm/test/CodeGen/DirectX/QuadAll.ll 
b/llvm/test/CodeGen/DirectX/QuadAll.ll
new file mode 100644
index 00000000000000..383de1135adab9
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/QuadAll.ll
@@ -0,0 +1,20 @@
+; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.7-library %s \
+; RUN:   | FileCheck %s
+; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.7-compute %s \
+; RUN:   | FileCheck %s
+; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.7-pixel %s \
+; RUN:   | FileCheck %s
+; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.7-amplification %s \
+; RUN:   | FileCheck %s
+; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.7-mesh %s \
+; RUN:   | FileCheck %s
+
+; CHECK-LABEL: define i1 @quad_all(
+; CHECK: %[[RET:.*]] = call i1 @dx.op.quadVote.i1(i32 222, i1 %cond, i8 1)
+; CHECK-NEXT: ret i1 %[[RET]]
+define i1 @quad_all(i1 %cond) {
+  %ret = call i1 @llvm.dx.quad.all(i1 %cond)
+  ret i1 %ret
+}
+
+declare i1 @llvm.dx.quad.all(i1)
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/wave-ops.ll 
b/llvm/test/CodeGen/DirectX/ShaderFlags/wave-ops.ll
index 37a991e1c1fa8e..19591defcdb317 100644
--- a/llvm/test/CodeGen/DirectX/ShaderFlags/wave-ops.ll
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/wave-ops.ll
@@ -49,6 +49,13 @@ entry:
   ret i1 %ret
 }
 
+define noundef i1 @quad_all(i1 %x) {
+entry:
+  ; CHECK: Function quad_all : [[WAVE_FLAG]]
+  %ret = call i1 @llvm.dx.quad.all(i1 %x)
+  ret i1 %ret
+}
+
 define noundef i32 @wave_bit_or(i32 %x) {
 entry:
   ; CHECK: Function wave_bit_or : [[WAVE_FLAG]]
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/QuadAll.ll 
b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/QuadAll.ll
new file mode 100644
index 00000000000000..cd94b87181a6aa
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/QuadAll.ll
@@ -0,0 +1,36 @@
+; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv1.5-unknown-vulkan-library \
+; RUN:   --spirv-ext=+SPV_KHR_quad_control,+SPV_KHR_maximal_reconvergence \
+; RUN:   %s -o - | FileCheck %s
+; RUN: not llc -O0 -mtriple=spirv1.5-unknown-vulkan-library \
+; RUN:   %s -o - 2>&1 | FileCheck %s --check-prefix=NO-EXT
+; RUN: not llc -O0 -mtriple=spirv1.5-unknown-vulkan-library \
+; RUN:   --spirv-ext=+SPV_KHR_quad_control %s -o - 2>&1 \
+; RUN:   | FileCheck %s --check-prefix=NO-RECONVERGENCE
+; RUN: not llc -O0 -mtriple=spirv32v1.2-unknown-vulkan-library \
+; RUN:   --spirv-ext=+SPV_KHR_quad_control,+SPV_KHR_maximal_reconvergence \
+; RUN:   %s -o - 2>&1 | FileCheck %s --check-prefix=VERSION
+; RUN: %if spirv-tools %{ llc -O0 \
+; RUN:   -mtriple=spirv1.5-unknown-vulkan-library \
+; RUN:   --spirv-ext=+SPV_KHR_quad_control,+SPV_KHR_maximal_reconvergence \
+; RUN:   %s -o - -filetype=obj | spirv-val %}
+
+; NO-EXT: OpGroupNonUniformQuadAllKHR instruction requires the following 
SPIR-V extension: SPV_KHR_quad_control
+; NO-RECONVERGENCE: SPV_KHR_quad_control requires the following SPIR-V 
extension: SPV_KHR_maximal_reconvergence
+; VERSION: OpGroupNonUniformQuadAllKHR requires SPIR-V 1.3
+
+; CHECK-DAG: OpCapability QuadControlKHR
+; CHECK-DAG: OpExtension "SPV_KHR_quad_control"
+; CHECK-DAG: OpExtension "SPV_KHR_maximal_reconvergence"
+; CHECK-DAG: %[[#BOOL:]] = OpTypeBool
+
+; CHECK-LABEL: Begin function quad_all
+; CHECK: %[[#COND:]] = OpFunctionParameter %[[#BOOL]]
+; CHECK: %[[#RET:]] = OpGroupNonUniformQuadAllKHR %[[#BOOL]] %[[#COND]]
+; CHECK-NEXT: OpReturnValue %[[#RET]]
+define i1 @quad_all(i1 %cond) convergent {
+  %tok = call token @llvm.experimental.convergence.entry()
+  %ret = call i1 @llvm.spv.quad.all(i1 %cond) [ "convergencectrl"(token %tok) ]
+  ret i1 %ret
+}
+
+declare i1 @llvm.spv.quad.all(i1) convergent

>From 8c23445e2d73757abe82f14345e8ee946a029406 Mon Sep 17 00:00:00 2001
From: Joshua Batista <[email protected]>
Date: Thu, 29 Oct 2026 13:55:13 -0700
Subject: [PATCH 2/3] self review

---
 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/QuadAll.ll | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/QuadAll.ll 
b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/QuadAll.ll
index cd94b87181a6aa..512f98e0940517 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/QuadAll.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/QuadAll.ll
@@ -4,8 +4,8 @@
 ; RUN: not llc -O0 -mtriple=spirv1.5-unknown-vulkan-library \
 ; RUN:   %s -o - 2>&1 | FileCheck %s --check-prefix=NO-EXT
 ; RUN: not llc -O0 -mtriple=spirv1.5-unknown-vulkan-library \
-; RUN:   --spirv-ext=+SPV_KHR_quad_control %s -o - 2>&1 \
-; RUN:   | FileCheck %s --check-prefix=NO-RECONVERGENCE
+; RUN:   --spirv-ext=+SPV_KHR_quad_control,-SPV_KHR_maximal_reconvergence \
+; RUN:   %s -o - 2>&1 | FileCheck %s --check-prefix=NO-RECONVERGENCE
 ; RUN: not llc -O0 -mtriple=spirv32v1.2-unknown-vulkan-library \
 ; RUN:   --spirv-ext=+SPV_KHR_quad_control,+SPV_KHR_maximal_reconvergence \
 ; RUN:   %s -o - 2>&1 | FileCheck %s --check-prefix=VERSION

>From 9ec100dffab07d772e7d394ba0d2dd09c1ea1dfb Mon Sep 17 00:00:00 2001
From: Joshua Batista <[email protected]>
Date: Fri, 30 Oct 2026 15:45:41 -0700
Subject: [PATCH 3/3] address feedback

---
 llvm/docs/SPIRVUsage.md                       |  8 +++-
 llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp    |  5 ++-
 llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp | 43 ++++++++++++------
 .../lib/Target/SPIRV/SPIRVSymbolicOperands.td | 13 +++++-
 .../derivative-group-quads.ll                 | 30 +++++++++++++
 .../quad-all.ll                               | 44 +++++++++++++++++++
 .../quad-all-with-modes.ll                    | 37 ++++++++++++++++
 .../SPV_KHR_quad_control/quad-derivatives.ll  | 35 +++++++++++++++
 .../require-full-quads.ll                     | 35 +++++++++++++++
 .../CodeGen/SPIRV/hlsl-intrinsics/QuadAll.ll  |  3 +-
 10 files changed, 233 insertions(+), 20 deletions(-)
 create mode 100644 
llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_compute_shader_derivatives/derivative-group-quads.ll
 create mode 100644 
llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_compute_shader_derivatives/quad-all.ll
 create mode 100644 
llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_quad_control/quad-all-with-modes.ll
 create mode 100644 
llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_quad_control/quad-derivatives.ll
 create mode 100644 
llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_quad_control/require-full-quads.ll

diff --git a/llvm/docs/SPIRVUsage.md b/llvm/docs/SPIRVUsage.md
index db41d8ce27a5c7..df750bdcf23072 100644
--- a/llvm/docs/SPIRVUsage.md
+++ b/llvm/docs/SPIRVUsage.md
@@ -197,6 +197,9 @@ Below is a list of supported SPIR-V extensions, sorted 
alphabetically by their e
      - Adds a function-termination instruction that signals an abnormal error 
to the client API. Currently supported in OpenCL environments only.
    * - ``SPV_KHR_bit_instructions``
      - Enables bit instructions to be used by SPIR-V modules without requiring 
the Shader capability.
+   * - ``SPV_KHR_compute_shader_derivatives``
+     - Adds the `DerivativeGroupQuadsKHR` execution mode and the
+       `ComputeDerivativeGroupQuadsKHR` capability.
    * - ``SPV_KHR_expect_assume``
      - Provides additional information to a compiler, similar to the 
llvm.assume and llvm.expect intrinsics.
    * - ``SPV_KHR_float_controls``
@@ -232,8 +235,9 @@ Below is a list of supported SPIR-V extensions, sorted 
alphabetically by their e
    * - ``SPV_KHR_maximal_reconvergence``
      - Adds execution mode and capability to enable maximal reconvergence.
    * - ``SPV_KHR_quad_control``
-     - Adds the quad vote instruction for HLSL `QuadAll`.
-       This instruction also requires `SPV_KHR_maximal_reconvergence`.
+     - Adds the quad vote instruction for HLSL `QuadAll` and the
+       `QuadDerivativesKHR` and `RequireFullQuadsKHR` execution modes.
+       These features also require `SPV_KHR_maximal_reconvergence`.
    * - ``SPV_ALTERA_blocking_pipes``
      - Adds new pipe read and write functions that have blocking semantics 
instead of the non-blocking semantics of the existing pipe read/write functions.
    * - ``SPV_ALTERA_arbitrary_precision_fixed_point``
diff --git a/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp 
b/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
index a430ad49fefb13..14c9e8fecf0e47 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
@@ -181,8 +181,9 @@ static const StringMap<SPIRV::Extension::Extension> 
SPIRVExtensionMap = {
     {"SPV_KHR_untyped_pointers",
      SPIRV::Extension::Extension::SPV_KHR_untyped_pointers},
     {"SPV_EXT_long_vector", SPIRV::Extension::Extension::SPV_EXT_long_vector},
-    {"SPV_KHR_quad_control",
-     SPIRV::Extension::Extension::SPV_KHR_quad_control}};
+    {"SPV_KHR_quad_control", 
SPIRV::Extension::Extension::SPV_KHR_quad_control},
+    {"SPV_KHR_compute_shader_derivatives",
+     SPIRV::Extension::Extension::SPV_KHR_compute_shader_derivatives}};
 
 bool SPIRVExtensionsParser::parse(cl::Option &O, StringRef ArgName,
                                   StringRef ArgValue, ExtensionSet &Vals) {
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp 
b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index 4ae3708ac8e950..cb3fdc1aa21fc5 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -855,10 +855,39 @@ void 
SPIRVModuleAnalysisImpl::numberRegistersGlobally(const Module &M) {
   }
 }
 
+static void addQuadControlRequirements(SPIRV::RequirementHandler &Reqs,
+                                       const SPIRVSubtarget &ST,
+                                       StringRef Feature) {
+  if (!ST.isAtLeastSPIRVVer(VersionTuple(1, 3)))
+    report_fatal_error(Twine(Feature) + " requires SPIR-V 1.3", false);
+  if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_quad_control))
+    report_fatal_error(Twine(Feature) + " requires the following SPIR-V "
+                                        "extension: SPV_KHR_quad_control",
+                       false);
+  if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_maximal_reconvergence))
+    report_fatal_error("SPV_KHR_quad_control requires the following SPIR-V "
+                       "extension: SPV_KHR_maximal_reconvergence",
+                       false);
+  Reqs.addExtension(SPIRV::Extension::SPV_KHR_quad_control);
+  Reqs.addExtension(SPIRV::Extension::SPV_KHR_maximal_reconvergence);
+}
+
 // RequirementHandler implementations.
 void SPIRV::RequirementHandler::getAndAddRequirements(
     SPIRV::OperandCategory::OperandCategory Category, uint32_t i,
     const SPIRVSubtarget &ST) {
+  if (Category == SPIRV::OperandCategory::ExecutionModeOperand &&
+      (i == SPIRV::ExecutionMode::QuadDerivativesKHR ||
+       i == SPIRV::ExecutionMode::RequireFullQuadsKHR))
+    addQuadControlRequirements(*this, ST,
+                               getSymbolicOperandMnemonic(Category, i));
+  if (Category == SPIRV::OperandCategory::ExecutionModeOperand &&
+      i == SPIRV::ExecutionMode::DerivativeGroupQuadsKHR &&
+      
!ST.canUseExtension(SPIRV::Extension::SPV_KHR_compute_shader_derivatives))
+    report_fatal_error(
+        "DerivativeGroupQuadsKHR requires the following SPIR-V extension: "
+        "SPV_KHR_compute_shader_derivatives",
+        false);
   addRequirements(getSymbolicOperandRequirements(Category, i, ST, *this));
 }
 
@@ -2139,19 +2168,7 @@ void addInstrRequirements(const MachineInstr &MI,
     }
     break;
   case SPIRV::OpGroupNonUniformQuadAllKHR:
-    if (!ST.isAtLeastSPIRVVer(VersionTuple(1, 3)))
-      report_fatal_error("OpGroupNonUniformQuadAllKHR requires SPIR-V 1.3",
-                         false);
-    if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_quad_control))
-      report_fatal_error("OpGroupNonUniformQuadAllKHR instruction requires the 
"
-                         "following SPIR-V extension: SPV_KHR_quad_control",
-                         false);
-    if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_maximal_reconvergence))
-      report_fatal_error("SPV_KHR_quad_control requires the following SPIR-V "
-                         "extension: SPV_KHR_maximal_reconvergence",
-                         false);
-    Reqs.addExtension(SPIRV::Extension::SPV_KHR_quad_control);
-    Reqs.addExtension(SPIRV::Extension::SPV_KHR_maximal_reconvergence);
+    addQuadControlRequirements(Reqs, ST, "OpGroupNonUniformQuadAllKHR");
     Reqs.addCapability(SPIRV::Capability::QuadControlKHR);
     break;
   case SPIRV::OpGroupNonUniformRotateKHR:
diff --git a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td 
b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
index 8792431da11510..8e65710703ee2f 100644
--- a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
+++ b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
@@ -411,6 +411,7 @@ defm SPV_KHR_untyped_pointers : ExtensionOperand<140, 
[EnvOpenCL]>;
 defm SPV_EXT_long_vector : ExtensionOperand<141, [EnvOpenCL, EnvVulkan]>;
 defm SPV_KHR_relaxed_extended_instruction : ExtensionOperand<142, [EnvVulkan, 
EnvOpenCL]>;
 defm SPV_KHR_quad_control : ExtensionOperand<143, [EnvVulkan]>;
+defm SPV_KHR_compute_shader_derivatives : ExtensionOperand<144, [EnvVulkan]>;
 
 
//===----------------------------------------------------------------------===//
 // Multiclass used to define Capabilities enum values and at the same time
@@ -567,7 +568,11 @@ defm VulkanMemoryModelKHR : CapabilityOperand<5345, 0, 0, 
[], []>;
 defm VulkanMemoryModelDeviceScopeKHR : CapabilityOperand<5346, 0, 0, [], []>;
 defm ImageFootprintNV : CapabilityOperand<5282, 0, 0, [], []>;
 defm FragmentBarycentricKHR : CapabilityOperand<5284, 0, 0, 
[SPV_KHR_fragment_shader_barycentric], [Shader]>;
-defm ComputeDerivativeGroupQuadsNV : CapabilityOperand<5288, 0, 0, [], []>;
+defm ComputeDerivativeGroupQuadsKHR
+    : CapabilityOperand<5288, 0, 0, [SPV_KHR_compute_shader_derivatives],
+                        [Shader]>;
+def ComputeDerivativeGroupQuadsNV
+    : Capability<"ComputeDerivativeGroupQuadsNV", 5288>;
 defm DemoteToHelperInvocation : CapabilityOperand<5379, 0x10600, 0, 
[SPV_EXT_demote_to_helper_invocation], []>;
 defm ComputeDerivativeGroupLinearNV : CapabilityOperand<5350, 0, 0, [], []>;
 defm FragmentDensityEXT : CapabilityOperand<5291, 0, 0, [], [Shader]>;
@@ -850,8 +855,12 @@ defm SignedZeroInfNanPreserve : ExecutionModeOperand<4461, 
[SignedZeroInfNanPres
 defm RoundingModeRTE : ExecutionModeOperand<4462, [RoundingModeRTE]>;
 defm RoundingModeRTZ : ExecutionModeOperand<4463, [RoundingModeRTZ]>;
 defm StencilRefReplacingEXT : ExecutionModeOperand<5027, [StencilExportEXT]>;
+defm QuadDerivativesKHR : ExecutionModeOperand<5088, [QuadControlKHR]>;
+defm RequireFullQuadsKHR : ExecutionModeOperand<5089, [QuadControlKHR]>;
 defm OutputLinesNV : ExecutionModeOperand<5269, [MeshShadingNV]>;
-defm DerivativeGroupQuadsNV : ExecutionModeOperand<5289, 
[ComputeDerivativeGroupQuadsNV]>;
+defm DerivativeGroupQuadsKHR
+    : ExecutionModeOperand<5289, [ComputeDerivativeGroupQuadsKHR]>;
+def DerivativeGroupQuadsNV : ExecutionMode<"DerivativeGroupQuadsNV", 5289>;
 defm DerivativeGroupLinearNV : ExecutionModeOperand<5290, 
[ComputeDerivativeGroupLinearNV]>;
 defm OutputTrianglesNV : ExecutionModeOperand<5298, [MeshShadingNV]>;
 defm RoundingModeRTPINTEL : ExecutionModeOperand<5620, [RoundToInfinityINTEL]>;
diff --git 
a/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_compute_shader_derivatives/derivative-group-quads.ll
 
b/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_compute_shader_derivatives/derivative-group-quads.ll
new file mode 100644
index 00000000000000..824c47924090a7
--- /dev/null
+++ 
b/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_compute_shader_derivatives/derivative-group-quads.ll
@@ -0,0 +1,30 @@
+; RUN: llc -O0 -verify-machineinstrs \
+; RUN:   -mtriple=spirv1.5-unknown-vulkan-compute \
+; RUN:   --spirv-ext=+SPV_KHR_compute_shader_derivatives \
+; RUN:   %s -o - | FileCheck %s
+; RUN: not llc -O0 -mtriple=spirv1.5-unknown-vulkan-compute \
+; RUN:   --spirv-ext=-SPV_KHR_compute_shader_derivatives \
+; RUN:   %s -o - 2>&1 | FileCheck %s --check-prefix=NO-EXT
+; RUN: %if spirv-tools %{ llc -O0 \
+; RUN:   -mtriple=spirv1.5-unknown-vulkan-compute \
+; RUN:   --spirv-ext=+SPV_KHR_compute_shader_derivatives \
+; RUN:   %s -o - -filetype=obj | spirv-val --target-env vulkan1.2 %}
+
+; NO-EXT: DerivativeGroupQuadsKHR requires the following SPIR-V extension: 
SPV_KHR_compute_shader_derivatives
+
+; CHECK-DAG: OpCapability Shader
+; CHECK-DAG: OpCapability ComputeDerivativeGroupQuadsKHR
+; CHECK: OpExtension "SPV_KHR_compute_shader_derivatives"
+; CHECK-NOT: OpExtension
+; CHECK: OpEntryPoint GLCompute %[[#MAIN:]] "main"
+; CHECK: OpExecutionMode %[[#MAIN]] DerivativeGroupQuadsKHR
+; CHECK: OpExecutionMode %[[#MAIN]] LocalSize 2 2 1
+
+define void @main() #0 {
+  ret void
+}
+
+attributes #0 = { "hlsl.numthreads"="2,2,1" "hlsl.shader"="compute" }
+
+!spirv.ExecutionMode = !{!0}
+!0 = !{ptr @main, i32 5289}
diff --git 
a/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_compute_shader_derivatives/quad-all.ll
 
b/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_compute_shader_derivatives/quad-all.ll
new file mode 100644
index 00000000000000..e62c3d2af07552
--- /dev/null
+++ 
b/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_compute_shader_derivatives/quad-all.ll
@@ -0,0 +1,44 @@
+; DEFINE: %{quad-exts} = +SPV_KHR_quad_control,+SPV_KHR_maximal_reconvergence
+; DEFINE: %{deriv-ext} = +SPV_KHR_compute_shader_derivatives
+
+; RUN: llc -O0 -verify-machineinstrs \
+; RUN:   -mtriple=spirv1.5-unknown-vulkan-compute \
+; RUN:   --spirv-ext=%{deriv-ext},%{quad-exts} \
+; RUN:   %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 \
+; RUN:   -mtriple=spirv1.5-unknown-vulkan-compute \
+; RUN:   --spirv-ext=%{deriv-ext},%{quad-exts} \
+; RUN:   %s -o - -filetype=obj | spirv-val --target-env vulkan1.2 %}
+
+; CHECK-DAG: OpCapability ComputeDerivativeGroupQuadsKHR
+; CHECK-DAG: OpCapability QuadControlKHR
+; CHECK-DAG: OpExtension "SPV_KHR_compute_shader_derivatives"
+; CHECK-DAG: OpExtension "SPV_KHR_quad_control"
+; CHECK-DAG: OpExtension "SPV_KHR_maximal_reconvergence"
+; CHECK: OpEntryPoint GLCompute %[[#MAIN:]] "main"
+; CHECK-DAG: OpExecutionMode %[[#MAIN]] DerivativeGroupQuadsKHR
+; CHECK-DAG: OpExecutionMode %[[#MAIN]] LocalSize 2 2 1
+; CHECK-DAG: %[[#BOOL:]] = OpTypeBool
+; CHECK-DAG: %[[#TRUE:]] = OpConstantTrue %[[#BOOL]]
+
+; CHECK: %[[#MAIN]] = OpFunction
+; CHECK: %[[#ALL:]] = OpGroupNonUniformQuadAllKHR %[[#BOOL]] %[[#TRUE]]
+; CHECK: %[[#VALUE:]] = OpSelect %{{[0-9]+}} %[[#ALL]]
+; CHECK: OpStore %{{[0-9]+}} %[[#VALUE]] Volatile
+define void @main() #0 {
+  %result = alloca i32
+  %tok = call token @llvm.experimental.convergence.entry()
+  %all = call i1 @llvm.spv.quad.all(i1 true) [ "convergencectrl"(token %tok) ]
+  %value = zext i1 %all to i32
+  store volatile i32 %value, ptr %result
+  ret void
+}
+
+declare i1 @llvm.spv.quad.all(i1) convergent
+
+attributes #0 = {
+  convergent "hlsl.numthreads"="2,2,1" "hlsl.shader"="compute"
+}
+
+!spirv.ExecutionMode = !{!0}
+!0 = !{ptr @main, i32 5289}
diff --git 
a/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_quad_control/quad-all-with-modes.ll
 
b/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_quad_control/quad-all-with-modes.ll
new file mode 100644
index 00000000000000..c12426daf3fe8b
--- /dev/null
+++ 
b/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_quad_control/quad-all-with-modes.ll
@@ -0,0 +1,37 @@
+; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv1.5-unknown-vulkan-pixel \
+; RUN:   --spirv-ext=+SPV_KHR_quad_control,+SPV_KHR_maximal_reconvergence \
+; RUN:   %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 \
+; RUN:   -mtriple=spirv1.5-unknown-vulkan-pixel \
+; RUN:   --spirv-ext=+SPV_KHR_quad_control,+SPV_KHR_maximal_reconvergence \
+; RUN:   %s -o - -filetype=obj | spirv-val %}
+
+; CHECK-DAG: OpCapability QuadControlKHR
+; CHECK-DAG: OpExtension "SPV_KHR_quad_control"
+; CHECK-DAG: OpExtension "SPV_KHR_maximal_reconvergence"
+; CHECK: OpEntryPoint Fragment %[[#MAIN:]] "main"
+; CHECK-DAG: OpExecutionMode %[[#MAIN]] QuadDerivativesKHR
+; CHECK-DAG: OpExecutionMode %[[#MAIN]] RequireFullQuadsKHR
+; CHECK-DAG: %[[#BOOL:]] = OpTypeBool
+; CHECK-DAG: %[[#TRUE:]] = OpConstantTrue %[[#BOOL]]
+
+; CHECK: %[[#MAIN]] = OpFunction
+; CHECK: %[[#ALL:]] = OpGroupNonUniformQuadAllKHR %[[#BOOL]] %[[#TRUE]]
+; CHECK: %[[#VALUE:]] = OpSelect %{{[0-9]+}} %[[#ALL]]
+; CHECK: OpStore %{{[0-9]+}} %[[#VALUE]] Volatile
+define void @main() #0 {
+  %result = alloca i32
+  %tok = call token @llvm.experimental.convergence.entry()
+  %all = call i1 @llvm.spv.quad.all(i1 true) [ "convergencectrl"(token %tok) ]
+  %value = zext i1 %all to i32
+  store volatile i32 %value, ptr %result
+  ret void
+}
+
+declare i1 @llvm.spv.quad.all(i1) convergent
+
+attributes #0 = { convergent "hlsl.shader"="pixel" }
+
+!spirv.ExecutionMode = !{!0, !1}
+!0 = !{ptr @main, i32 5088}
+!1 = !{ptr @main, i32 5089}
diff --git 
a/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_quad_control/quad-derivatives.ll 
b/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_quad_control/quad-derivatives.ll
new file mode 100644
index 00000000000000..1eeaeaadaeb486
--- /dev/null
+++ 
b/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_quad_control/quad-derivatives.ll
@@ -0,0 +1,35 @@
+; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv1.5-unknown-vulkan-pixel \
+; RUN:   --spirv-ext=+SPV_KHR_quad_control,+SPV_KHR_maximal_reconvergence \
+; RUN:   %s -o - | FileCheck %s
+; RUN: not llc -O0 -mtriple=spirv1.5-unknown-vulkan-pixel \
+; RUN:   --spirv-ext=-SPV_KHR_quad_control,+SPV_KHR_maximal_reconvergence \
+; RUN:   %s -o - 2>&1 | FileCheck %s --check-prefix=NO-EXT
+; RUN: not llc -O0 -mtriple=spirv1.5-unknown-vulkan-pixel \
+; RUN:   --spirv-ext=+SPV_KHR_quad_control,-SPV_KHR_maximal_reconvergence \
+; RUN:   %s -o - 2>&1 | FileCheck %s --check-prefix=NO-RECONVERGENCE
+; RUN: not llc -O0 -mtriple=spirv32v1.2-unknown-vulkan-pixel \
+; RUN:   --spirv-ext=+SPV_KHR_quad_control,+SPV_KHR_maximal_reconvergence \
+; RUN:   %s -o - 2>&1 | FileCheck %s --check-prefix=VERSION
+; RUN: %if spirv-tools %{ llc -O0 \
+; RUN:   -mtriple=spirv1.5-unknown-vulkan-pixel \
+; RUN:   --spirv-ext=+SPV_KHR_quad_control,+SPV_KHR_maximal_reconvergence \
+; RUN:   %s -o - -filetype=obj | spirv-val %}
+
+; NO-EXT: QuadDerivativesKHR requires the following SPIR-V extension: 
SPV_KHR_quad_control
+; NO-RECONVERGENCE: SPV_KHR_quad_control requires the following SPIR-V 
extension: SPV_KHR_maximal_reconvergence
+; VERSION: QuadDerivativesKHR requires SPIR-V 1.3
+
+; CHECK-DAG: OpCapability QuadControlKHR
+; CHECK-DAG: OpExtension "SPV_KHR_quad_control"
+; CHECK-DAG: OpExtension "SPV_KHR_maximal_reconvergence"
+; CHECK: OpEntryPoint Fragment %[[#MAIN:]] "main"
+; CHECK: OpExecutionMode %[[#MAIN]] QuadDerivativesKHR
+
+define void @main() #0 {
+  ret void
+}
+
+attributes #0 = { "hlsl.shader"="pixel" }
+
+!spirv.ExecutionMode = !{!0}
+!0 = !{ptr @main, i32 5088}
diff --git 
a/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_quad_control/require-full-quads.ll 
b/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_quad_control/require-full-quads.ll
new file mode 100644
index 00000000000000..b942c5d62015ed
--- /dev/null
+++ 
b/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_quad_control/require-full-quads.ll
@@ -0,0 +1,35 @@
+; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv1.5-unknown-vulkan-pixel \
+; RUN:   --spirv-ext=+SPV_KHR_quad_control,+SPV_KHR_maximal_reconvergence \
+; RUN:   %s -o - | FileCheck %s
+; RUN: not llc -O0 -mtriple=spirv1.5-unknown-vulkan-pixel \
+; RUN:   --spirv-ext=-SPV_KHR_quad_control,+SPV_KHR_maximal_reconvergence \
+; RUN:   %s -o - 2>&1 | FileCheck %s --check-prefix=NO-EXT
+; RUN: not llc -O0 -mtriple=spirv1.5-unknown-vulkan-pixel \
+; RUN:   --spirv-ext=+SPV_KHR_quad_control,-SPV_KHR_maximal_reconvergence \
+; RUN:   %s -o - 2>&1 | FileCheck %s --check-prefix=NO-RECONVERGENCE
+; RUN: not llc -O0 -mtriple=spirv32v1.2-unknown-vulkan-pixel \
+; RUN:   --spirv-ext=+SPV_KHR_quad_control,+SPV_KHR_maximal_reconvergence \
+; RUN:   %s -o - 2>&1 | FileCheck %s --check-prefix=VERSION
+; RUN: %if spirv-tools %{ llc -O0 \
+; RUN:   -mtriple=spirv1.5-unknown-vulkan-pixel \
+; RUN:   --spirv-ext=+SPV_KHR_quad_control,+SPV_KHR_maximal_reconvergence \
+; RUN:   %s -o - -filetype=obj | spirv-val %}
+
+; NO-EXT: RequireFullQuadsKHR requires the following SPIR-V extension: 
SPV_KHR_quad_control
+; NO-RECONVERGENCE: SPV_KHR_quad_control requires the following SPIR-V 
extension: SPV_KHR_maximal_reconvergence
+; VERSION: RequireFullQuadsKHR requires SPIR-V 1.3
+
+; CHECK-DAG: OpCapability QuadControlKHR
+; CHECK-DAG: OpExtension "SPV_KHR_quad_control"
+; CHECK-DAG: OpExtension "SPV_KHR_maximal_reconvergence"
+; CHECK: OpEntryPoint Fragment %[[#MAIN:]] "main"
+; CHECK: OpExecutionMode %[[#MAIN]] RequireFullQuadsKHR
+
+define void @main() #0 {
+  ret void
+}
+
+attributes #0 = { "hlsl.shader"="pixel" }
+
+!spirv.ExecutionMode = !{!0}
+!0 = !{ptr @main, i32 5089}
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/QuadAll.ll 
b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/QuadAll.ll
index 512f98e0940517..10e8faad8cb0f3 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/QuadAll.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/QuadAll.ll
@@ -14,13 +14,14 @@
 ; RUN:   --spirv-ext=+SPV_KHR_quad_control,+SPV_KHR_maximal_reconvergence \
 ; RUN:   %s -o - -filetype=obj | spirv-val %}
 
-; NO-EXT: OpGroupNonUniformQuadAllKHR instruction requires the following 
SPIR-V extension: SPV_KHR_quad_control
+; NO-EXT: OpGroupNonUniformQuadAllKHR requires the following SPIR-V extension: 
SPV_KHR_quad_control
 ; NO-RECONVERGENCE: SPV_KHR_quad_control requires the following SPIR-V 
extension: SPV_KHR_maximal_reconvergence
 ; VERSION: OpGroupNonUniformQuadAllKHR requires SPIR-V 1.3
 
 ; CHECK-DAG: OpCapability QuadControlKHR
 ; CHECK-DAG: OpExtension "SPV_KHR_quad_control"
 ; CHECK-DAG: OpExtension "SPV_KHR_maximal_reconvergence"
+; CHECK-NOT: OpExecutionMode
 ; CHECK-DAG: %[[#BOOL:]] = OpTypeBool
 
 ; CHECK-LABEL: Begin function quad_all

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to