clspv icon indicating copy to clipboard operation
clspv copied to clipboard

dead code in SPIRVProducer: no such thing as bool vector?

Open dneto0 opened this issue 8 years ago • 2 comments

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.

dneto0 avatar Aug 28 '17 16:08 dneto0

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 .

sheredom avatar Aug 28 '17 16:08 sheredom

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.

dneto0 avatar Aug 28 '17 23:08 dneto0

sext with i1 has a special handle case: https://github.com/google/clspv/blob/c9d2022bdc215352f1818b90f71abf607c84b4a4/lib/SPIRVProducerPass.cpp#L4648

rjodinchr avatar Mar 09 '24 10:03 rjodinchr