-
Notifications
You must be signed in to change notification settings - Fork 261
Closed
Description
This seems to go presuambly due to opaque pointers and indicies not being fixed up. The initializer in global uchar2* p_var = &a_var[1]; gets translated to @p_var = addrspace(1) global ptr addrspace(1) getelementptr (i8, ptr addrspace(1) @a_var, i64 2), align 8. It uses an index of 2 because when assuming it all to be a raw char array is correct. However in the SPIR-V we end up with this:
%a_var = OpVariable %_ptr_CrossWorkgroup__arr_v2uchar_ulong_2 CrossWorkgroup %14
%17 = OpSpecConstantOp %_ptr_CrossWorkgroup_uchar PtrAccessChain %a_var %ulong_2
%p_var = OpVariable %_ptr_CrossWorkgroup__ptr_CrossWorkgroup_uchar CrossWorkgroup %17
which would rather be something like global uchar* p_var = &(&a_var)[2]; maybe? It's a bit weird, becuase of the ouse of PtrAccessChain here. %a_var is an two element long array of a 2 component uchar vector, and this PtrAccessChain selects the third element here...
OpenCL C
uchar2 from_buf(uchar2 a) { return a; }
uchar2 to_buf(uchar2 a) { return a; }
#define INIT_VAR(a) ((uchar2)(a))
uchar2 var = INIT_VAR(0);
global uchar2 g_var = INIT_VAR(1);
uchar2 a_var[2] = { INIT_VAR(1), INIT_VAR(1) };
volatile global uchar2* p_var = &a_var[1];
kernel void writer( global uchar2* src, uint idx ) {
var = from_buf(src[0]);
g_var = from_buf(src[1]);
a_var[0] = from_buf(src[2]);
a_var[1] = from_buf(src[3]);
p_var = a_var + idx;
}
kernel void reader( global uchar2* dest, uchar2 ptr_write_val ) {
*p_var = from_buf(ptr_write_val);
dest[0] = to_buf(var);
dest[1] = to_buf(g_var);
dest[2] = to_buf(a_var[0]);
dest[3] = to_buf(a_var[1]);
}LLVM
source_filename = "input.cl"
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
target triple = "spirv64-unknown-unknown"
@var = addrspace(1) global <2 x i8> zeroinitializer, align 2
@g_var = addrspace(1) global <2 x i8> <i8 1, i8 1>, align 2
@a_var = addrspace(1) global [2 x <2 x i8>] [<2 x i8> <i8 1, i8 1>, <2 x i8> <i8 1, i8 1>], align 2
@p_var = addrspace(1) global ptr addrspace(1) getelementptr (i8, ptr addrspace(1) @a_var, i64 2), align 8
; Function Attrs: convergent noinline norecurse nounwind optnone
define spir_func <2 x i8> @from_buf(<2 x i8> noundef %a) #0 {
entry:
%a.addr = alloca <2 x i8>, align 2
store <2 x i8> %a, ptr %a.addr, align 2
%0 = load <2 x i8>, ptr %a.addr, align 2
ret <2 x i8> %0
}
; Function Attrs: convergent noinline norecurse nounwind optnone
define spir_func <2 x i8> @to_buf(<2 x i8> noundef %a) #0 {
entry:
%a.addr = alloca <2 x i8>, align 2
store <2 x i8> %a, ptr %a.addr, align 2
%0 = load <2 x i8>, ptr %a.addr, align 2
ret <2 x i8> %0
}
; Function Attrs: convergent noinline norecurse nounwind optnone
define spir_kernel void @writer(ptr addrspace(1) noundef align 2 %src, i32 noundef %idx) #1 !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:
%src.addr = alloca ptr addrspace(1), align 8
%idx.addr = alloca i32, align 4
store ptr addrspace(1) %src, ptr %src.addr, align 8
store i32 %idx, ptr %idx.addr, align 4
%0 = load ptr addrspace(1), ptr %src.addr, align 8
%arrayidx = getelementptr inbounds <2 x i8>, ptr addrspace(1) %0, i64 0
%1 = load <2 x i8>, ptr addrspace(1) %arrayidx, align 2
%call = call spir_func <2 x i8> @from_buf(<2 x i8> noundef %1) #2
store <2 x i8> %call, ptr addrspace(1) @var, align 2
%2 = load ptr addrspace(1), ptr %src.addr, align 8
%arrayidx1 = getelementptr inbounds <2 x i8>, ptr addrspace(1) %2, i64 1
%3 = load <2 x i8>, ptr addrspace(1) %arrayidx1, align 2
%call2 = call spir_func <2 x i8> @from_buf(<2 x i8> noundef %3) #2
store <2 x i8> %call2, ptr addrspace(1) @g_var, align 2
%4 = load ptr addrspace(1), ptr %src.addr, align 8
%arrayidx3 = getelementptr inbounds <2 x i8>, ptr addrspace(1) %4, i64 2
%5 = load <2 x i8>, ptr addrspace(1) %arrayidx3, align 2
%call4 = call spir_func <2 x i8> @from_buf(<2 x i8> noundef %5) #2
store <2 x i8> %call4, ptr addrspace(1) @a_var, align 2
%6 = load ptr addrspace(1), ptr %src.addr, align 8
%arrayidx5 = getelementptr inbounds <2 x i8>, ptr addrspace(1) %6, i64 3
%7 = load <2 x i8>, ptr addrspace(1) %arrayidx5, align 2
%call6 = call spir_func <2 x i8> @from_buf(<2 x i8> noundef %7) #2
store <2 x i8> %call6, ptr addrspace(1) getelementptr inbounds ([2 x <2 x i8>], ptr addrspace(1) @a_var, i64 0, i64 1), align 2
%8 = load i32, ptr %idx.addr, align 4
%idx.ext = zext i32 %8 to i64
%add.ptr = getelementptr inbounds <2 x i8>, ptr addrspace(1) @a_var, i64 %idx.ext
store ptr addrspace(1) %add.ptr, ptr addrspace(1) @p_var, align 8
ret void
}
; Function Attrs: convergent noinline norecurse nounwind optnone
define spir_kernel void @reader(ptr addrspace(1) noundef align 2 %dest, <2 x i8> noundef %ptr_write_val) #1 !kernel_arg_addr_space !3 !kernel_arg_access_qual !4 !kernel_arg_type !8 !kernel_arg_base_type !9 !kernel_arg_type_qual !7 {
entry:
%dest.addr = alloca ptr addrspace(1), align 8
%ptr_write_val.addr = alloca <2 x i8>, align 2
store ptr addrspace(1) %dest, ptr %dest.addr, align 8
store <2 x i8> %ptr_write_val, ptr %ptr_write_val.addr, align 2
%0 = load <2 x i8>, ptr %ptr_write_val.addr, align 2
%call = call spir_func <2 x i8> @from_buf(<2 x i8> noundef %0) #2
%1 = load ptr addrspace(1), ptr addrspace(1) @p_var, align 8
store volatile <2 x i8> %call, ptr addrspace(1) %1, align 2
%2 = load <2 x i8>, ptr addrspace(1) @var, align 2
%call1 = call spir_func <2 x i8> @to_buf(<2 x i8> noundef %2) #2
%3 = load ptr addrspace(1), ptr %dest.addr, align 8
%arrayidx = getelementptr inbounds <2 x i8>, ptr addrspace(1) %3, i64 0
store <2 x i8> %call1, ptr addrspace(1) %arrayidx, align 2
%4 = load <2 x i8>, ptr addrspace(1) @g_var, align 2
%call2 = call spir_func <2 x i8> @to_buf(<2 x i8> noundef %4) #2
%5 = load ptr addrspace(1), ptr %dest.addr, align 8
%arrayidx3 = getelementptr inbounds <2 x i8>, ptr addrspace(1) %5, i64 1
store <2 x i8> %call2, ptr addrspace(1) %arrayidx3, align 2
%6 = load <2 x i8>, ptr addrspace(1) @a_var, align 2
%call4 = call spir_func <2 x i8> @to_buf(<2 x i8> noundef %6) #2
%7 = load ptr addrspace(1), ptr %dest.addr, align 8
%arrayidx5 = getelementptr inbounds <2 x i8>, ptr addrspace(1) %7, i64 2
store <2 x i8> %call4, ptr addrspace(1) %arrayidx5, align 2
%8 = load <2 x i8>, ptr addrspace(1) getelementptr inbounds ([2 x <2 x i8>], ptr addrspace(1) @a_var, i64 0, i64 1), align 2
%call6 = call spir_func <2 x i8> @to_buf(<2 x i8> noundef %8) #2
%9 = load ptr addrspace(1), ptr %dest.addr, align 8
%arrayidx7 = getelementptr inbounds <2 x i8>, ptr addrspace(1) %9, i64 3
store <2 x i8> %call6, ptr addrspace(1) %arrayidx7, align 2
ret void
}
attributes #0 = { convergent noinline norecurse nounwind optnone "no-builtin-memset" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
attributes #1 = { convergent noinline norecurse nounwind optnone "no-builtin-memset" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "uniform-work-group-size"="false" }
attributes #2 = { convergent nounwind "no-builtin-memset" }
!llvm.module.flags = !{!0}
!opencl.ocl.version = !{!1}
!llvm.ident = !{!2}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 3, i32 0}
!2 = !{!"clang version 19.0.0git (https://github.com/llvm/llvm-project.git 610b9e23c5a3040aacc6fe85de8694f80bf5bdf5)"}
!3 = !{i32 1, i32 0}
!4 = !{!"none", !"none"}
!5 = !{!"uchar2*", !"uint"}
!6 = !{!"uchar __attribute__((ext_vector_type(2)))*", !"uint"}
!7 = !{!"", !""}
!8 = !{!"uchar2*", !"uchar2"}
!9 = !{!"uchar __attribute__((ext_vector_type(2)))*", !"uchar __attribute__((ext_vector_type(2)))"}SPIR-V
; SPIR-V
; Version: 1.4
; Generator: Khronos LLVM/SPIR-V Translator; 14
; Bound: 113
; Schema: 0
OpCapability Addresses
OpCapability Linkage
OpCapability Kernel
OpCapability Int64
OpCapability Int8
%1 = OpExtInstImport "OpenCL.std"
OpMemoryModel Physical64 OpenCL
OpEntryPoint Kernel %99 "writer" %var %g_var %a_var %p_var
OpEntryPoint Kernel %104 "reader" %var %g_var %a_var %p_var
%109 = OpString "kernel_arg_type.writer.uchar2*,uint,"
%110 = OpString "kernel_arg_type_qual.writer.,,"
%111 = OpString "kernel_arg_type.reader.uchar2*,uchar2,"
%112 = OpString "kernel_arg_type_qual.reader.,,"
OpSource OpenCL_C 300000
OpName %var "var"
OpName %g_var "g_var"
OpName %a_var "a_var"
OpName %p_var "p_var"
OpName %from_buf "from_buf"
OpName %a "a"
OpName %entry "entry"
OpName %a_addr "a.addr"
OpName %to_buf "to_buf"
OpName %a_0 "a"
OpName %entry_0 "entry"
OpName %a_addr_0 "a.addr"
OpName %writer "writer"
OpName %src "src"
OpName %idx "idx"
OpName %entry_1 "entry"
OpName %src_addr "src.addr"
OpName %idx_addr "idx.addr"
OpName %arrayidx "arrayidx"
OpName %call "call"
OpName %arrayidx1 "arrayidx1"
OpName %call2 "call2"
OpName %arrayidx3 "arrayidx3"
OpName %call4 "call4"
OpName %arrayidx5 "arrayidx5"
OpName %call6 "call6"
OpName %idx_ext "idx.ext"
OpName %add_ptr "add.ptr"
OpName %reader "reader"
OpName %dest "dest"
OpName %ptr_write_val "ptr_write_val"
OpName %entry_2 "entry"
OpName %dest_addr "dest.addr"
OpName %ptr_write_val_addr "ptr_write_val.addr"
OpName %call_0 "call"
OpName %call1 "call1"
OpName %arrayidx_0 "arrayidx"
OpName %call2_0 "call2"
OpName %arrayidx3_0 "arrayidx3"
OpName %call4_0 "call4"
OpName %arrayidx5_0 "arrayidx5"
OpName %call6_0 "call6"
OpName %arrayidx7 "arrayidx7"
OpName %src_0 "src"
OpName %idx_0 "idx"
OpName %dest_0 "dest"
OpName %ptr_write_val_0 "ptr_write_val"
OpDecorate %var LinkageAttributes "var" Export
OpDecorate %var Alignment 2
OpDecorate %g_var LinkageAttributes "g_var" Export
OpDecorate %g_var Alignment 2
OpDecorate %a_var LinkageAttributes "a_var" Export
OpDecorate %a_var Alignment 2
OpDecorate %p_var LinkageAttributes "p_var" Export
OpDecorate %p_var Alignment 8
OpDecorate %from_buf LinkageAttributes "from_buf" Export
OpDecorate %a_addr Alignment 2
OpDecorate %to_buf LinkageAttributes "to_buf" Export
OpDecorate %a_addr_0 Alignment 2
OpDecorate %writer LinkageAttributes "writer" Export
OpDecorate %src Alignment 2
OpDecorate %src_addr Alignment 8
OpDecorate %idx_addr Alignment 4
OpDecorate %reader LinkageAttributes "reader" Export
OpDecorate %dest Alignment 2
OpDecorate %dest_addr Alignment 8
OpDecorate %ptr_write_val_addr Alignment 2
OpDecorate %src_0 Alignment 2
OpDecorate %dest_0 Alignment 2
%uchar = OpTypeInt 8 0
%ulong = OpTypeInt 64 0
%uint = OpTypeInt 32 0
%uchar_1 = OpConstant %uchar 1
%ulong_2 = OpConstant %ulong 2
%ulong_0 = OpConstant %ulong 0
%ulong_1 = OpConstant %ulong 1
%ulong_3 = OpConstant %ulong 3
%v2uchar = OpTypeVector %uchar 2
%_ptr_CrossWorkgroup_v2uchar = OpTypePointer CrossWorkgroup %v2uchar
%_arr_v2uchar_ulong_2 = OpTypeArray %v2uchar %ulong_2
%_ptr_CrossWorkgroup__arr_v2uchar_ulong_2 = OpTypePointer CrossWorkgroup %_arr_v2uchar_ulong_2
%_ptr_CrossWorkgroup_uchar = OpTypePointer CrossWorkgroup %uchar
%_ptr_CrossWorkgroup__ptr_CrossWorkgroup_uchar = OpTypePointer CrossWorkgroup %_ptr_CrossWorkgroup_uchar
%20 = OpTypeFunction %v2uchar %v2uchar
%_ptr_Function_v2uchar = OpTypePointer Function %v2uchar
%void = OpTypeVoid
%34 = OpTypeFunction %void %_ptr_CrossWorkgroup_v2uchar %uint
%_ptr_Function__ptr_CrossWorkgroup_v2uchar = OpTypePointer Function %_ptr_CrossWorkgroup_v2uchar
%_ptr_Function_uint = OpTypePointer Function %uint
%_ptr_CrossWorkgroup__ptr_CrossWorkgroup_v2uchar = OpTypePointer CrossWorkgroup %_ptr_CrossWorkgroup_v2uchar
%70 = OpTypeFunction %void %_ptr_CrossWorkgroup_v2uchar %v2uchar
%5 = OpConstantNull %v2uchar
%var = OpVariable %_ptr_CrossWorkgroup_v2uchar CrossWorkgroup %5
%8 = OpConstantComposite %v2uchar %uchar_1 %uchar_1
%g_var = OpVariable %_ptr_CrossWorkgroup_v2uchar CrossWorkgroup %8
%14 = OpConstantComposite %_arr_v2uchar_ulong_2 %8 %8
%a_var = OpVariable %_ptr_CrossWorkgroup__arr_v2uchar_ulong_2 CrossWorkgroup %14
%17 = OpSpecConstantOp %_ptr_CrossWorkgroup_uchar PtrAccessChain %a_var %ulong_2
%p_var = OpVariable %_ptr_CrossWorkgroup__ptr_CrossWorkgroup_uchar CrossWorkgroup %17
%from_buf = OpFunction %v2uchar DontInline %20
%a = OpFunctionParameter %v2uchar
%entry = OpLabel
%a_addr = OpVariable %_ptr_Function_v2uchar Function
OpStore %a_addr %a Aligned 2
%26 = OpLoad %v2uchar %a_addr Aligned 2
OpReturnValue %26
OpFunctionEnd
%to_buf = OpFunction %v2uchar DontInline %20
%a_0 = OpFunctionParameter %v2uchar
%entry_0 = OpLabel
%a_addr_0 = OpVariable %_ptr_Function_v2uchar Function
OpStore %a_addr_0 %a_0 Aligned 2
%31 = OpLoad %v2uchar %a_addr_0 Aligned 2
OpReturnValue %31
OpFunctionEnd
%writer = OpFunction %void DontInline %34
%src = OpFunctionParameter %_ptr_CrossWorkgroup_v2uchar
%idx = OpFunctionParameter %uint
%entry_1 = OpLabel
%src_addr = OpVariable %_ptr_Function__ptr_CrossWorkgroup_v2uchar Function
%idx_addr = OpVariable %_ptr_Function_uint Function
OpStore %src_addr %src Aligned 8
OpStore %idx_addr %idx Aligned 4
%43 = OpLoad %_ptr_CrossWorkgroup_v2uchar %src_addr Aligned 8
%arrayidx = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_v2uchar %43 %ulong_0
%46 = OpLoad %v2uchar %arrayidx Aligned 2
%call = OpFunctionCall %v2uchar %from_buf %46
OpStore %var %call Aligned 2
%48 = OpLoad %_ptr_CrossWorkgroup_v2uchar %src_addr Aligned 8
%arrayidx1 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_v2uchar %48 %ulong_1
%51 = OpLoad %v2uchar %arrayidx1 Aligned 2
%call2 = OpFunctionCall %v2uchar %from_buf %51
OpStore %g_var %call2 Aligned 2
%53 = OpLoad %_ptr_CrossWorkgroup_v2uchar %src_addr Aligned 8
%arrayidx3 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_v2uchar %53 %ulong_2
%55 = OpLoad %v2uchar %arrayidx3 Aligned 2
%call4 = OpFunctionCall %v2uchar %from_buf %55
%57 = OpBitcast %_ptr_CrossWorkgroup_v2uchar %a_var
OpStore %57 %call4 Aligned 2
%58 = OpLoad %_ptr_CrossWorkgroup_v2uchar %src_addr Aligned 8
%arrayidx5 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_v2uchar %58 %ulong_3
%61 = OpLoad %v2uchar %arrayidx5 Aligned 2
%call6 = OpFunctionCall %v2uchar %from_buf %61
%63 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_v2uchar %a_var %ulong_0 %ulong_1
OpStore %63 %call6 Aligned 2
%64 = OpLoad %uint %idx_addr Aligned 4
%idx_ext = OpUConvert %ulong %64
%66 = OpBitcast %_ptr_CrossWorkgroup_v2uchar %a_var
%add_ptr = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_v2uchar %66 %idx_ext
%69 = OpBitcast %_ptr_CrossWorkgroup__ptr_CrossWorkgroup_v2uchar %p_var
OpStore %69 %add_ptr Aligned 8
OpReturn
OpFunctionEnd
%reader = OpFunction %void DontInline %70
%dest = OpFunctionParameter %_ptr_CrossWorkgroup_v2uchar
%ptr_write_val = OpFunctionParameter %v2uchar
%entry_2 = OpLabel
%dest_addr = OpVariable %_ptr_Function__ptr_CrossWorkgroup_v2uchar Function
%ptr_write_val_addr = OpVariable %_ptr_Function_v2uchar Function
OpStore %dest_addr %dest Aligned 8
OpStore %ptr_write_val_addr %ptr_write_val Aligned 2
%77 = OpLoad %v2uchar %ptr_write_val_addr Aligned 2
%call_0 = OpFunctionCall %v2uchar %from_buf %77
%79 = OpLoad %_ptr_CrossWorkgroup_uchar %p_var Aligned 8
%80 = OpBitcast %_ptr_CrossWorkgroup_v2uchar %79
OpStore %80 %call_0 Volatile|Aligned 2
%81 = OpLoad %v2uchar %var Aligned 2
%call1 = OpFunctionCall %v2uchar %to_buf %81
%83 = OpLoad %_ptr_CrossWorkgroup_v2uchar %dest_addr Aligned 8
%arrayidx_0 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_v2uchar %83 %ulong_0
OpStore %arrayidx_0 %call1 Aligned 2
%85 = OpLoad %v2uchar %g_var Aligned 2
%call2_0 = OpFunctionCall %v2uchar %to_buf %85
%87 = OpLoad %_ptr_CrossWorkgroup_v2uchar %dest_addr Aligned 8
%arrayidx3_0 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_v2uchar %87 %ulong_1
OpStore %arrayidx3_0 %call2_0 Aligned 2
%89 = OpBitcast %_ptr_CrossWorkgroup_v2uchar %a_var
%90 = OpLoad %v2uchar %89 Aligned 2
%call4_0 = OpFunctionCall %v2uchar %to_buf %90
%92 = OpLoad %_ptr_CrossWorkgroup_v2uchar %dest_addr Aligned 8
%arrayidx5_0 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_v2uchar %92 %ulong_2
OpStore %arrayidx5_0 %call4_0 Aligned 2
%94 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_v2uchar %a_var %ulong_0 %ulong_1
%95 = OpLoad %v2uchar %94 Aligned 2
%call6_0 = OpFunctionCall %v2uchar %to_buf %95
%97 = OpLoad %_ptr_CrossWorkgroup_v2uchar %dest_addr Aligned 8
%arrayidx7 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_v2uchar %97 %ulong_3
OpStore %arrayidx7 %call6_0 Aligned 2
OpReturn
OpFunctionEnd
%99 = OpFunction %void DontInline %34
%src_0 = OpFunctionParameter %_ptr_CrossWorkgroup_v2uchar
%idx_0 = OpFunctionParameter %uint
%102 = OpLabel
%103 = OpFunctionCall %void %writer %src_0 %idx_0
OpReturn
OpFunctionEnd
%104 = OpFunction %void DontInline %70
%dest_0 = OpFunctionParameter %_ptr_CrossWorkgroup_v2uchar
%ptr_write_val_0 = OpFunctionParameter %v2uchar
%107 = OpLabel
%108 = OpFunctionCall %void %reader %dest_0 %ptr_write_val_0
OpReturn
OpFunctionEnd
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels