[llvm] [SPIR-V] Fix invalid OpIMul emitted for i1 multiplication (PR #207388)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 3 05:58:05 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-spir-v

Author: Arseniy Obolenskiy (aobolensk)

<details>
<summary>Changes</summary>

OpIMul requires integer scalar/vector operands

OpTypeBool is not considered an integer type and causes spirv-val failure

---
Full diff: https://github.com/llvm/llvm-project/pull/207388.diff


2 Files Affected:

- (modified) llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp (+7) 
- (modified) llvm/test/CodeGen/SPIRV/instructions/scalar-integer-arithmetic.ll (+14) 


``````````diff
diff --git a/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp b/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp
index eb16c9a314a23..ef85c62547d81 100644
--- a/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp
@@ -512,6 +512,13 @@ void SPIRVTargetLowering::finalizeLowering(MachineFunction &MF) const {
                                       SPIRV::OpTypeBool))
           MI.setDesc(STI.getInstrInfo()->get(SPIRV::OpLogicalNotEqual));
         break;
+      // multiplication of bool operands is equivalent to a logical AND
+      case SPIRV::OpIMulS:
+      case SPIRV::OpIMulV:
+        if (GR.isScalarOrVectorOfType(MI.getOperand(1).getReg(),
+                                      SPIRV::OpTypeBool))
+          MI.setDesc(STI.getInstrInfo()->get(SPIRV::OpLogicalAnd));
+        break;
 
       // ensure that LLVM IR bitwise instructions result in logical SPIR-V
       // instructions when applied to bool type
diff --git a/llvm/test/CodeGen/SPIRV/instructions/scalar-integer-arithmetic.ll b/llvm/test/CodeGen/SPIRV/instructions/scalar-integer-arithmetic.ll
index 649c146f68993..e62ba39132db4 100644
--- a/llvm/test/CodeGen/SPIRV/instructions/scalar-integer-arithmetic.ll
+++ b/llvm/test/CodeGen/SPIRV/instructions/scalar-integer-arithmetic.ll
@@ -8,6 +8,7 @@
 ; CHECK-DAG: OpName [[BOOL_SUB:%.+]] "bool_sub"
 ; CHECK-DAG: OpName [[SCALAR_ADD:%.+]] "scalar_add"
 ; CHECK-DAG: OpName [[SCALAR_SUB:%.+]] "scalar_sub"
+; CHECK-DAG: OpName [[BOOL_MUL:%.+]] "bool_mul"
 ; CHECK-DAG: OpName [[SCALAR_MUL:%.+]] "scalar_mul"
 ; CHECK-DAG: OpName [[SCALAR_UDIV:%.+]] "scalar_udiv"
 ; CHECK-DAG: OpName [[SCALAR_SDIV:%.+]] "scalar_sdiv"
@@ -84,6 +85,19 @@ define i32 @scalar_sub(i32 %a, i32 %b) {
 
 
 ;; Test mul on scalar:
+define i1 @bool_mul(i1 %a, i1 %b) {
+    %c = mul i1 %a, %b
+    ret i1 %c
+}
+
+; CHECK:      [[BOOL_MUL]] = OpFunction [[BOOL]] None [[BOOL_FN]]
+; CHECK-NEXT: [[A:%.+]] = OpFunctionParameter [[BOOL]]
+; CHECK-NEXT: [[B:%.+]] = OpFunctionParameter [[BOOL]]
+; CHECK:      OpLabel
+; CHECK:      [[C:%.+]] = OpLogicalAnd [[BOOL]] [[A]] [[B]]
+; CHECK:      OpReturnValue [[C]]
+; CHECK-NEXT: OpFunctionEnd
+
 define i32 @scalar_mul(i32 %a, i32 %b) {
     %c = mul i32 %a, %b
     ret i32 %c

``````````

</details>


https://github.com/llvm/llvm-project/pull/207388


More information about the llvm-commits mailing list