1; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV 2; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %} 3 4; TODO(#60133): Requires updates following opaque pointer migration. 5; XFAIL: * 6 7;; Check 'LLVM ==> SPIR-V' conversion of extractvalue/insertvalue. 8 9%struct.arr = type { [7 x float] } 10%struct.st = type { %struct.inner } 11%struct.inner = type { float } 12 13; CHECK-SPIRV: %[[#float_ty:]] = OpTypeFloat 32 14; CHECK-SPIRV: %[[#int_ty:]] = OpTypeInt 32 15; CHECK-SPIRV: %[[#arr_size:]] = OpConstant %[[#int_ty]] 7 16; CHECK-SPIRV: %[[#array_ty:]] = OpTypeArray %[[#float_ty]] %[[#arr_size]] 17; CHECK-SPIRV: %[[#struct_ty:]] = OpTypeStruct %[[#array_ty]] 18; CHECK-SPIRV: %[[#struct_ptr_ty:]] = OpTypePointer CrossWorkgroup %[[#struct_ty]] 19; CHECK-SPIRV: %[[#array_ptr_ty:]] = OpTypePointer CrossWorkgroup %[[#array_ty]] 20; CHECK-SPIRV: %[[#struct1_in_ty:]] = OpTypeStruct %[[#float_ty]] 21; CHECK-SPIRV: %[[#struct1_ty:]] = OpTypeStruct %[[#struct1_in_ty]] 22; CHECK-SPIRV: %[[#struct1_ptr_ty:]] = OpTypePointer CrossWorkgroup %[[#struct1_ty]] 23; CHECK-SPIRV: %[[#struct1_in_ptr_ty:]] = OpTypePointer CrossWorkgroup %[[#struct1_in_ty]] 24; CHECK-SPIRV-NOT: OpConstant %{{.*}} 2 25; CHECK-SPIRV-NOT: OpConstant %{{.*}} 4 26; CHECK-SPIRV-NOT: OpConstant %{{.*}} 5 27 28; CHECK-SPIRV-LABEL: OpFunction 29; CHECK-SPIRV-NEXT: %[[#object:]] = OpFunctionParameter %[[#struct_ptr_ty]] 30; CHECK-SPIRV: %[[#store_ptr:]] = OpInBoundsPtrAccessChain %[[#array_ptr_ty]] %[[#object]] %[[#]] %[[#]] 31; CHECK-SPIRV: %[[#extracted_array:]] = OpLoad %[[#array_ty]] %[[#store_ptr]] Aligned 4 32; CHECK-SPIRV: %[[#elem_4:]] = OpCompositeExtract %[[#float_ty]] %[[#extracted_array]] 4 33; CHECK-SPIRV: %[[#elem_2:]] = OpCompositeExtract %[[#float_ty]] %[[#extracted_array]] 2 34; CHECK-SPIRV: %[[#add:]] = OpFAdd %[[#float_ty]] %[[#elem_4]] %[[#elem_2]] 35; CHECK-SPIRV: %[[#inserted_array:]] = OpCompositeInsert %[[#array_ty]] %[[#add]] %[[#extracted_array]] 5 36; CHECK-SPIRV: OpStore %[[#store_ptr]] %[[#inserted_array]] 37; CHECK-SPIRV-LABEL: OpFunctionEnd 38 39define spir_func void @array_test(%struct.arr addrspace(1)* %object) { 40entry: 41 %0 = getelementptr inbounds %struct.arr, %struct.arr addrspace(1)* %object, i32 0, i32 0 42 %1 = load [7 x float], [7 x float] addrspace(1)* %0, align 4 43 %2 = extractvalue [7 x float] %1, 4 44 %3 = extractvalue [7 x float] %1, 2 45 %4 = fadd float %2, %3 46 %5 = insertvalue [7 x float] %1, float %4, 5 47 store [7 x float] %5, [7 x float] addrspace(1)* %0 48 ret void 49} 50 51; CHECK-SPIRV-LABEL: OpFunction 52; CHECK-SPIRV-NEXT: %[[#object:]] = OpFunctionParameter %[[#struct1_ptr_ty]] 53; CHECK-SPIRV: %[[#store1_ptr:]] = OpInBoundsPtrAccessChain %[[#struct1_in_ptr_ty]] %[[#object]] %[[#]] %[[#]] 54; CHECK-SPIRV: %[[#extracted_struct:]] = OpLoad %[[#struct1_in_ty]] %[[#store1_ptr]] Aligned 4 55; CHECK-SPIRV: %[[#elem:]] = OpCompositeExtract %[[#float_ty]] %[[#extracted_struct]] 0 56; CHECK-SPIRV: %[[#add:]] = OpFAdd %[[#float_ty]] %[[#elem]] %[[#]] 57; CHECK-SPIRV: %[[#inserted_struct:]] = OpCompositeInsert %[[#struct1_in_ty]] %[[#add]] %[[#extracted_struct]] 0 58; CHECK-SPIRV: OpStore %[[#store1_ptr]] %[[#inserted_struct]] 59; CHECK-SPIRV-LABEL: OpFunctionEnd 60 61define spir_func void @struct_test(%struct.st addrspace(1)* %object) { 62entry: 63 %0 = getelementptr inbounds %struct.st, %struct.st addrspace(1)* %object, i32 0, i32 0 64 %1 = load %struct.inner, %struct.inner addrspace(1)* %0, align 4 65 %2 = extractvalue %struct.inner %1, 0 66 %3 = fadd float %2, 1.000000e+00 67 %4 = insertvalue %struct.inner %1, float %3, 0 68 store %struct.inner %4, %struct.inner addrspace(1)* %0 69 ret void 70} 71