[SPIR-V] Convert integer vector to bool vector for OpAny/OpAll (#191804)

OpenCL any()/all() builtins receive integer vectors, but OpAny/OpAll
require boolean vector inputs per the SPIR-V spec

related to https://github.com/llvm/llvm-project/issues/190736
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
index b228799..f91387a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
@@ -1327,12 +1327,35 @@
   std::tie(CompareRegister, RelationType) =
       buildBoolRegister(MIRBuilder, Call->ReturnType, GR);
 
+  // OpAny/OpAll require a boolean vector input, but OpenCL any()/all()
+  // builtins receive integer vectors. Convert via OpINotEqual against zero.
+  SmallVector<Register> Arguments(Call->Arguments.begin(),
+                                  Call->Arguments.end());
+  if ((Opcode == SPIRV::OpAny || Opcode == SPIRV::OpAll) &&
+      !GR->isScalarOrVectorOfType(Arguments[0], SPIRV::OpTypeBool)) {
+    SPIRVTypeInst ArgType = GR->getSPIRVTypeForVReg(Arguments[0]);
+    unsigned NumElts = ArgType->getOperand(2).getImm();
+    SPIRVTypeInst BoolVecTy = GR->getOrCreateSPIRVVectorType(
+        GR->getOrCreateSPIRVBoolType(MIRBuilder, /*EmitIR=*/true), NumElts,
+        MIRBuilder, /*EmitIR=*/true);
+    Register ZeroReg =
+        GR->getOrCreateConsIntVector(uint64_t(0), MIRBuilder, ArgType,
+                                     /*EmitIR=*/true);
+    Register BoolVecReg = createVirtualRegister(BoolVecTy, GR, MIRBuilder);
+    MIRBuilder.buildInstr(SPIRV::OpINotEqual)
+        .addDef(BoolVecReg)
+        .addUse(GR->getSPIRVTypeID(BoolVecTy))
+        .addUse(Arguments[0])
+        .addUse(ZeroReg);
+    Arguments[0] = BoolVecReg;
+  }
+
   // Build relational instruction.
   auto MIB = MIRBuilder.buildInstr(Opcode)
                  .addDef(CompareRegister)
                  .addUse(GR->getSPIRVTypeID(RelationType));
 
-  for (auto Argument : Call->Arguments)
+  for (auto Argument : Arguments)
     MIB.addUse(Argument);
 
   // Build select instruction.
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/OpAllAny.ll b/llvm/test/CodeGen/SPIRV/transcoding/OpAllAny.ll
index 52c893c..dd43749 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/OpAllAny.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/OpAllAny.ll
@@ -1,16 +1,26 @@
 ; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
 
 ;; This test checks SYCL relational builtin any and all with vector input types.
 
-; CHECK-SPIRV: %[[#BoolTypeID:]] = OpTypeBool
+; CHECK-SPIRV-DAG: %[[#BoolTypeID:]] = OpTypeBool
+; CHECK-SPIRV-DAG: %[[#BoolVecTypeID:]] = OpTypeVector %[[#BoolTypeID]] 2
 
+; CHECK-SPIRV: %[[#]] = OpINotEqual %[[#BoolVecTypeID]]
 ; CHECK-SPIRV: OpAny %[[#BoolTypeID]]
+; CHECK-SPIRV: %[[#]] = OpINotEqual %[[#BoolVecTypeID]]
 ; CHECK-SPIRV: OpAny %[[#BoolTypeID]]
+; CHECK-SPIRV: %[[#]] = OpINotEqual %[[#BoolVecTypeID]]
 ; CHECK-SPIRV: OpAny %[[#BoolTypeID]]
+; CHECK-SPIRV: %[[#]] = OpINotEqual %[[#BoolVecTypeID]]
 ; CHECK-SPIRV: OpAny %[[#BoolTypeID]]
+; CHECK-SPIRV: %[[#]] = OpINotEqual %[[#BoolVecTypeID]]
 ; CHECK-SPIRV: OpAll %[[#BoolTypeID]]
+; CHECK-SPIRV: %[[#]] = OpINotEqual %[[#BoolVecTypeID]]
 ; CHECK-SPIRV: OpAll %[[#BoolTypeID]]
+; CHECK-SPIRV: %[[#]] = OpINotEqual %[[#BoolVecTypeID]]
 ; CHECK-SPIRV: OpAll %[[#BoolTypeID]]
+; CHECK-SPIRV: %[[#]] = OpINotEqual %[[#BoolVecTypeID]]
 ; CHECK-SPIRV: OpAll %[[#BoolTypeID]]
 
 define dso_local spir_func void @test_vector(ptr addrspace(4) nocapture writeonly %out, <2 x i8> %c, <2 x i16> %s, <2 x i32> %i, <2 x i64> %l) local_unnamed_addr {