dead code in SPIRVProducer: no such thing as bool vector?
OpenCL C doesn't have vector-of-bool. But the SPIR-V code generation for cast operations tries to handle that case. In that case it would generate invalid code because the constants it selects from are scalars. The check for vector-of-bool looks like a read herring: I suspect it never fires.
Does Vector of bool maybe get generated as the result of a CMP inst on a vector?
On 28 Aug 2017 17:36, "David Neto" [email protected] wrote:
OpenCL C doesn't have vector-of-bool. But the SPIR-V code generation for cast operations tries to handle that case. In that case it would generate invalid code because the constants it selects from are scalars. The check for vector-of-bool looks like a read herring: I suspect it never fires.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/google/clspv/issues/47, or mute the thread https://github.com/notifications/unsubscribe-auth/AAlTY4FSAnYpdJmYNWtxC-TEu86AYCeiks5scux0gaJpZM4PEwoC .
Does Vector of bool maybe get generated as the result of a CMP inst on a vector?
Indeed it does! Good catch.kernel
void foo(global int4 *A) {
*A = A[0] == A[1];
}
Produces this LLVM:
define spir_kernel void @foo(<4 x i32> addrspace(1)* nocapture %A) local_unnamed_addr #0 !kernel_arg_addr_space !3 !kernel_arg_access_qual !4 !kernel_arg_type !5 !kernel_arg_base_type !6 !kernel_arg_type_qual !7 {
entry:
%0 = load <4 x i32>, <4 x i32> addrspace(1)* %A, align 16
%arrayidx1 = getelementptr inbounds <4 x i32>, <4 x i32> addrspace(1)* %A, i32 1
%1 = load <4 x i32>, <4 x i32> addrspace(1)* %arrayidx1, align 16
%cmp = icmp eq <4 x i32> %0, %1
%sext = sext <4 x i1> %cmp to <4 x i32>
store <4 x i32> %sext, <4 x i32> addrspace(1)* %A, align 16
ret void
}
That sext is the case trying to be handled.
The compiler looks like it's generating the right code:
%void = OpTypeVoid
%8 = OpTypeFunction %void
%bool = OpTypeBool
%v4bool = OpTypeVector %bool 4
%v3uint = OpTypeVector %uint 3
%_ptr_Private_v3uint = OpTypePointer Private %v3uint
%13 = OpConstantNull %v4uint
%uint_4294967295 = OpConstant %uint 4294967295
%15 = OpConstantComposite %v4uint %uint_4294967295 %uint_4294967295 %uint_4294967295 %uint_4294967295
%uint_0 = OpConstant %uint 0
%uint_1 = OpConstant %uint 1
%18 = OpSpecConstant %uint 1
%19 = OpSpecConstant %uint 1
%20 = OpSpecConstant %uint 1
%gl_WorkGroupSize = OpSpecConstantComposite %v3uint %18 %19 %20
%22 = OpVariable %_ptr_Private_v3uint Private %gl_WorkGroupSize
%23 = OpVariable %_ptr_StorageBuffer__struct_5 StorageBuffer
%24 = OpFunction %void None %8
%25 = OpLabel
%26 = OpAccessChain %_ptr_StorageBuffer_v4uint %23 %uint_0 %uint_0
%27 = OpLoad %v4uint %26
%28 = OpAccessChain %_ptr_StorageBuffer_v4uint %23 %uint_0 %uint_1
%29 = OpLoad %v4uint %28
%30 = OpIEqual %v4bool %27 %29
%31 = OpSelect %v4uint %30 %15 %13
OpStore %26 %31
OpReturn
So now I'm confused. How did we get those vector types when the true and false operands to the select look like they are generated in scalars in the casting code. ?! Must look further.
sext with i1 has a special handle case: https://github.com/google/clspv/blob/c9d2022bdc215352f1818b90f71abf607c84b4a4/lib/SPIRVProducerPass.cpp#L4648