[Mlir-commits] [mlir] e339ed1 - [mlir][SPIR-V] Add OpExpectKHR op (#195842)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Tue May 5 10:10:26 PDT 2026


Author: Arseniy Obolenskiy
Date: 2026-05-05T19:10:21+02:00
New Revision: e339ed1806ec817abf7933618c8b9f5dfdaf40f8

URL: https://github.com/llvm/llvm-project/commit/e339ed1806ec817abf7933618c8b9f5dfdaf40f8
DIFF: https://github.com/llvm/llvm-project/commit/e339ed1806ec817abf7933618c8b9f5dfdaf40f8.diff

LOG: [mlir][SPIR-V] Add OpExpectKHR op (#195842)

Complete SPV_KHR_expect_assume extension support

Added: 
    mlir/test/Target/SPIRV/expect-assume-ops.mlir

Modified: 
    mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td
    mlir/include/mlir/Dialect/SPIRV/IR/SPIRVMiscOps.td
    mlir/test/Dialect/SPIRV/IR/misc-ops.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td
index f870e6d920c8c..b33a84d093fb9 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td
@@ -4682,6 +4682,7 @@ def SPIRV_OC_OpSetMeshOutputsEXT              : I32EnumAttrCase<"OpSetMeshOutput
 def SPIRV_OC_OpSubgroupBlockReadINTEL         : I32EnumAttrCase<"OpSubgroupBlockReadINTEL", 5575>;
 def SPIRV_OC_OpSubgroupBlockWriteINTEL        : I32EnumAttrCase<"OpSubgroupBlockWriteINTEL", 5576>;
 def SPIRV_OC_OpAssumeTrueKHR                  : I32EnumAttrCase<"OpAssumeTrueKHR", 5630>;
+def SPIRV_OC_OpExpectKHR                      : I32EnumAttrCase<"OpExpectKHR", 5631>;
 def SPIRV_OC_OpAtomicFAddEXT                  : I32EnumAttrCase<"OpAtomicFAddEXT", 6035>;
 def SPIRV_OC_OpConvertFToBF16INTEL            : I32EnumAttrCase<"OpConvertFToBF16INTEL", 6116>;
 def SPIRV_OC_OpConvertBF16ToFINTEL            : I32EnumAttrCase<"OpConvertBF16ToFINTEL", 6117>;
@@ -4806,7 +4807,7 @@ def SPIRV_OpcodeAttr :
       SPIRV_OC_OpSpecConstantCompositeReplicateEXT,
       SPIRV_OC_OpEmitMeshTasksEXT, SPIRV_OC_OpSetMeshOutputsEXT,
       SPIRV_OC_OpSubgroupBlockReadINTEL, SPIRV_OC_OpSubgroupBlockWriteINTEL,
-      SPIRV_OC_OpAssumeTrueKHR, SPIRV_OC_OpAtomicFAddEXT,
+      SPIRV_OC_OpAssumeTrueKHR, SPIRV_OC_OpExpectKHR, SPIRV_OC_OpAtomicFAddEXT,
       SPIRV_OC_OpConvertFToBF16INTEL, SPIRV_OC_OpConvertBF16ToFINTEL,
       SPIRV_OC_OpControlBarrierArriveINTEL, SPIRV_OC_OpControlBarrierWaitINTEL,
       SPIRV_OC_OpGroupIMulKHR, SPIRV_OC_OpGroupFMulKHR,

diff  --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVMiscOps.td b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVMiscOps.td
index d828e118757e2..786dc23c2bdfe 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVMiscOps.td
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVMiscOps.td
@@ -26,10 +26,6 @@ def SPIRV_KHRAssumeTrueOp : SPIRV_KhrVendorOp<"AssumeTrue", []> {
 
     <!-- End of AutoGen section -->
 
-    ```
-    assumetruekhr-op ::= `spirv.KHR.AssumeTrue` ssa-use
-    ```
-
     #### Example:
 
     ```mlir
@@ -56,6 +52,49 @@ def SPIRV_KHRAssumeTrueOp : SPIRV_KhrVendorOp<"AssumeTrue", []> {
 
 // -----
 
+def SPIRV_KHRExpectOp : SPIRV_KhrVendorOp<"Expect",
+    [Pure, AllTypesMatch<["value", "expectedValue", "result"]>]> {
+  let summary = "Provides a hint to the optimizer that the value is likely "
+                "to equal the expected value.";
+
+  let description = [{
+    Result Type must be a scalar or vector of integer type or Boolean type.
+
+    Value and Expected Value must be of Result Type. Result is the same as
+    Value.
+
+    <!-- End of AutoGen section -->
+
+    #### Example:
+
+    ```mlir
+    %2 = spirv.KHR.Expect %0, %1 : i32
+    %5 = spirv.KHR.Expect %3, %4 : vector<4xi1>
+    ```
+  }];
+
+  let availability = [
+    MinVersion<SPIRV_V_1_0>,
+    MaxVersion<SPIRV_V_1_6>,
+    Extension<[SPV_KHR_expect_assume]>,
+    Capability<[SPIRV_C_ExpectAssumeKHR]>
+  ];
+
+  let arguments = (ins
+    SPIRV_ScalarOrVectorOf<AnyTypeOf<[SPIRV_Integer, SPIRV_Bool]>>:$value,
+    SPIRV_ScalarOrVectorOf<AnyTypeOf<[SPIRV_Integer, SPIRV_Bool]>>:$expectedValue
+  );
+
+  let results = (outs
+    SPIRV_ScalarOrVectorOf<AnyTypeOf<[SPIRV_Integer, SPIRV_Bool]>>:$result
+  );
+
+  let hasVerifier = 0;
+  let assemblyFormat = "operands attr-dict `:` type($result)";
+}
+
+// -----
+
 def SPIRV_UndefOp : SPIRV_Op<"Undef", [Pure]> {
   let summary = "Make an intermediate object whose value is undefined.";
 

diff  --git a/mlir/test/Dialect/SPIRV/IR/misc-ops.mlir b/mlir/test/Dialect/SPIRV/IR/misc-ops.mlir
index 182b661035a61..cfd19a683bebf 100644
--- a/mlir/test/Dialect/SPIRV/IR/misc-ops.mlir
+++ b/mlir/test/Dialect/SPIRV/IR/misc-ops.mlir
@@ -44,3 +44,55 @@ func.func @assume_true(%arg : f32) -> () {
   spirv.KHR.AssumeTrue %arg
   spirv.Return
 }
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.KHR.Expect
+//===----------------------------------------------------------------------===//
+
+func.func @expect_scalar_int(%val : i32, %expected : i32) -> i32 {
+  // CHECK: %{{.*}} = spirv.KHR.Expect %{{.*}}, %{{.*}} : i32
+  %0 = spirv.KHR.Expect %val, %expected : i32
+  spirv.ReturnValue %0 : i32
+}
+
+// -----
+
+func.func @expect_scalar_bool(%val : i1, %expected : i1) -> i1 {
+  // CHECK: %{{.*}} = spirv.KHR.Expect %{{.*}}, %{{.*}} : i1
+  %0 = spirv.KHR.Expect %val, %expected : i1
+  spirv.ReturnValue %0 : i1
+}
+
+// -----
+
+func.func @expect_vector_int(%val : vector<4xi32>, %expected : vector<4xi32>) -> vector<4xi32> {
+  // CHECK: %{{.*}} = spirv.KHR.Expect %{{.*}}, %{{.*}} : vector<4xi32>
+  %0 = spirv.KHR.Expect %val, %expected : vector<4xi32>
+  spirv.ReturnValue %0 : vector<4xi32>
+}
+
+// -----
+
+func.func @expect_vector_bool(%val : vector<4xi1>, %expected : vector<4xi1>) -> vector<4xi1> {
+  // CHECK: %{{.*}} = spirv.KHR.Expect %{{.*}}, %{{.*}} : vector<4xi1>
+  %0 = spirv.KHR.Expect %val, %expected : vector<4xi1>
+  spirv.ReturnValue %0 : vector<4xi1>
+}
+
+// -----
+
+func.func @expect_type_mismatch(%val : i32, %expected : i64) -> i32 {
+  // expected-error @+1 {{op failed to verify that all of {value, expectedValue, result} have same type}}
+  %0 = "spirv.KHR.Expect"(%val, %expected) : (i32, i64) -> i32
+  spirv.ReturnValue %0 : i32
+}
+
+// -----
+
+func.func @expect_float_invalid(%val : f32, %expected : f32) -> f32 {
+  // expected-error @+1 {{op operand #0 must be}}
+  %0 = "spirv.KHR.Expect"(%val, %expected) : (f32, f32) -> f32
+  spirv.ReturnValue %0 : f32
+}

diff  --git a/mlir/test/Target/SPIRV/expect-assume-ops.mlir b/mlir/test/Target/SPIRV/expect-assume-ops.mlir
new file mode 100644
index 0000000000000..e742835462227
--- /dev/null
+++ b/mlir/test/Target/SPIRV/expect-assume-ops.mlir
@@ -0,0 +1,45 @@
+// RUN: mlir-translate --no-implicit-module --test-spirv-roundtrip %s | FileCheck %s
+
+// RUN: %if spirv-tools %{ rm -rf %t %}
+// RUN: %if spirv-tools %{ mkdir %t %}
+// RUN: %if spirv-tools %{ mlir-translate --no-implicit-module --serialize-spirv --split-input-file --spirv-save-validation-files-with-prefix=%t/module %s %}
+// RUN: %if spirv-tools %{ spirv-val %t %}
+
+spirv.module Logical GLSL450 requires
+  #spirv.vce<v1.0, [Shader, Linkage, ExpectAssumeKHR], [SPV_KHR_expect_assume]> {
+
+  // CHECK-LABEL: @assume_true
+  spirv.func @assume_true(%arg : i1) "None" {
+    // CHECK: spirv.KHR.AssumeTrue %{{.*}}
+    spirv.KHR.AssumeTrue %arg
+    spirv.Return
+  }
+
+  // CHECK-LABEL: @expect_scalar_int
+  spirv.func @expect_scalar_int(%val : i32, %expected : i32) -> i32 "None" {
+    // CHECK: {{%.+}} = spirv.KHR.Expect %{{.*}}, %{{.*}} : i32
+    %0 = spirv.KHR.Expect %val, %expected : i32
+    spirv.ReturnValue %0 : i32
+  }
+
+  // CHECK-LABEL: @expect_scalar_bool
+  spirv.func @expect_scalar_bool(%val : i1, %expected : i1) -> i1 "None" {
+    // CHECK: {{%.+}} = spirv.KHR.Expect %{{.*}}, %{{.*}} : i1
+    %0 = spirv.KHR.Expect %val, %expected : i1
+    spirv.ReturnValue %0 : i1
+  }
+
+  // CHECK-LABEL: @expect_vector_int
+  spirv.func @expect_vector_int(%val : vector<4xi32>, %expected : vector<4xi32>) -> vector<4xi32> "None" {
+    // CHECK: {{%.+}} = spirv.KHR.Expect %{{.*}}, %{{.*}} : vector<4xi32>
+    %0 = spirv.KHR.Expect %val, %expected : vector<4xi32>
+    spirv.ReturnValue %0 : vector<4xi32>
+  }
+
+  // CHECK-LABEL: @expect_vector_bool
+  spirv.func @expect_vector_bool(%val : vector<4xi1>, %expected : vector<4xi1>) -> vector<4xi1> "None" {
+    // CHECK: {{%.+}} = spirv.KHR.Expect %{{.*}}, %{{.*}} : vector<4xi1>
+    %0 = spirv.KHR.Expect %val, %expected : vector<4xi1>
+    spirv.ReturnValue %0 : vector<4xi1>
+  }
+}


        


More information about the Mlir-commits mailing list