1; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=SI -check-prefix=SICIVI %s 2; RUN: llc -march=amdgcn -mcpu=tonga -mattr=-flat-for-global -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=VI -check-prefix=SICIVI %s 3; RUN: llc -march=amdgcn -mcpu=gfx901 -mattr=-flat-for-global -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=GFX9 %s 4 5; GCN-LABEL: {{^}}extract_vector_elt_v2i16: 6; GCN: s_load_dword [[VEC:s[0-9]+]] 7; GCN: s_lshr_b32 [[ELT1:s[0-9]+]], [[VEC]], 16 8; GCN-DAG: v_mov_b32_e32 [[VELT0:v[0-9]+]], [[VEC]] 9; GCN-DAG: v_mov_b32_e32 [[VELT1:v[0-9]+]], [[ELT1]] 10; GCN-DAG: buffer_store_short [[VELT0]] 11; GCN-DAG: buffer_store_short [[VELT1]] 12define void @extract_vector_elt_v2i16(i16 addrspace(1)* %out, <2 x i16> addrspace(2)* %vec.ptr) #0 { 13 %vec = load <2 x i16>, <2 x i16> addrspace(2)* %vec.ptr 14 %p0 = extractelement <2 x i16> %vec, i32 0 15 %p1 = extractelement <2 x i16> %vec, i32 1 16 %out1 = getelementptr i16, i16 addrspace(1)* %out, i32 10 17 store i16 %p1, i16 addrspace(1)* %out, align 2 18 store i16 %p0, i16 addrspace(1)* %out1, align 2 19 ret void 20} 21 22; GCN-LABEL: {{^}}extract_vector_elt_v2i16_dynamic_sgpr: 23; GCN: s_load_dword [[IDX:s[0-9]+]] 24; GCN: s_load_dword [[VEC:s[0-9]+]] 25; GCN: s_lshl_b32 [[IDX_SCALED:s[0-9]+]], [[IDX]], 16 26; GCN: s_lshr_b32 [[ELT1:s[0-9]+]], [[VEC]], [[IDX_SCALED]] 27; GCN: v_mov_b32_e32 [[VELT1:v[0-9]+]], [[ELT1]] 28; GCN: buffer_store_short [[VELT1]] 29; GCN: ScratchSize: 0 30define void @extract_vector_elt_v2i16_dynamic_sgpr(i16 addrspace(1)* %out, <2 x i16> addrspace(2)* %vec.ptr, i32 %idx) #0 { 31 %vec = load <2 x i16>, <2 x i16> addrspace(2)* %vec.ptr 32 %elt = extractelement <2 x i16> %vec, i32 %idx 33 store i16 %elt, i16 addrspace(1)* %out, align 2 34 ret void 35} 36 37; GCN-LABEL: {{^}}extract_vector_elt_v2i16_dynamic_vgpr: 38; GCN-DAG: s_load_dword [[VEC:s[0-9]+]] 39; GCN-DAG: {{flat|buffer}}_load_dword [[IDX:v[0-9]+]] 40; GCN: v_lshlrev_b32_e32 [[IDX_SCALED:v[0-9]+]], 16, [[IDX]] 41 42; SI: v_lshr_b32_e32 [[ELT:v[0-9]+]], [[VEC]], [[IDX_SCALED]] 43; VI: v_lshrrev_b32_e64 [[ELT:v[0-9]+]], [[IDX_SCALED]], [[VEC]] 44 45; SI: buffer_store_short [[ELT]] 46; VI: flat_store_short v{{\[[0-9]+:[0-9]+\]}}, [[ELT]] 47; GCN: ScratchSize: 0{{$}} 48define void @extract_vector_elt_v2i16_dynamic_vgpr(i16 addrspace(1)* %out, <2 x i16> addrspace(2)* %vec.ptr, i32 addrspace(1)* %idx.ptr) #0 { 49 %tid = call i32 @llvm.amdgcn.workitem.id.x() 50 %tid.ext = sext i32 %tid to i64 51 %gep = getelementptr inbounds i32, i32 addrspace(1)* %idx.ptr, i64 %tid.ext 52 %out.gep = getelementptr inbounds i16, i16 addrspace(1)* %out, i64 %tid.ext 53 %idx = load volatile i32, i32 addrspace(1)* %gep 54 %vec = load <2 x i16>, <2 x i16> addrspace(2)* %vec.ptr 55 %elt = extractelement <2 x i16> %vec, i32 %idx 56 store i16 %elt, i16 addrspace(1)* %out.gep, align 2 57 ret void 58} 59 60; GCN-LABEL: {{^}}extract_vector_elt_v3i16: 61; GCN: buffer_load_ushort 62; GCN: buffer_store_short 63; GCN: buffer_store_short 64define void @extract_vector_elt_v3i16(i16 addrspace(1)* %out, <3 x i16> %foo) #0 { 65 %p0 = extractelement <3 x i16> %foo, i32 0 66 %p1 = extractelement <3 x i16> %foo, i32 2 67 %out1 = getelementptr i16, i16 addrspace(1)* %out, i32 1 68 store i16 %p1, i16 addrspace(1)* %out, align 2 69 store i16 %p0, i16 addrspace(1)* %out1, align 2 70 ret void 71} 72 73; GCN-LABEL: {{^}}extract_vector_elt_v4i16: 74; SICIVI: buffer_load_ushort 75; SICIVI: buffer_load_ushort 76; SICIVI: buffer_store_short 77; SICIVI: buffer_store_short 78 79; GFX9-DAG: s_load_dword [[LOAD0:s[0-9]+]], s[0:1], 0x2c 80; GFX9-DAG: s_load_dword [[LOAD1:s[0-9]+]], s[0:1], 0x30 81; GFX9-DAG: v_mov_b32_e32 [[VLOAD0:v[0-9]+]], [[LOAD0]] 82; GFX9-DAG: buffer_store_short [[VLOAD0]], off 83; GFX9-DAG: v_mov_b32_e32 [[VLOAD1:v[0-9]+]], [[LOAD1]] 84; GFX9-DAG: buffer_store_short [[VLOAD1]], off 85define void @extract_vector_elt_v4i16(i16 addrspace(1)* %out, <4 x i16> %foo) #0 { 86 %p0 = extractelement <4 x i16> %foo, i32 0 87 %p1 = extractelement <4 x i16> %foo, i32 2 88 %out1 = getelementptr i16, i16 addrspace(1)* %out, i32 10 89 store volatile i16 %p1, i16 addrspace(1)* %out, align 2 90 store volatile i16 %p0, i16 addrspace(1)* %out1, align 2 91 ret void 92} 93 94; GCN-LABEL: {{^}}dynamic_extract_vector_elt_v3i16: 95; GCN: buffer_load_ushort 96; GCN: buffer_load_ushort 97; GCN: buffer_load_ushort 98 99; SICIVI: buffer_store_short 100; SICIVI: buffer_store_short 101; SICIVI: buffer_store_short 102 103; GFX9: buffer_store_dword 104; GFX9: buffer_store_dword 105 106; GCN: buffer_load_ushort 107; GCN: buffer_store_short 108define void @dynamic_extract_vector_elt_v3i16(i16 addrspace(1)* %out, <3 x i16> %foo, i32 %idx) #0 { 109 %p0 = extractelement <3 x i16> %foo, i32 %idx 110 %out1 = getelementptr i16, i16 addrspace(1)* %out, i32 1 111 store i16 %p0, i16 addrspace(1)* %out 112 ret void 113} 114 115; GCN-LABEL: {{^}}dynamic_extract_vector_elt_v4i16: 116; SICIVI: buffer_load_ushort 117; SICIVI: buffer_load_ushort 118; SICIVI: buffer_load_ushort 119; SICIVI: buffer_load_ushort 120 121; SICIVI: buffer_store_short 122; SICIVI: buffer_store_short 123; SICIVI: buffer_store_short 124; SICIVI: buffer_store_short 125 126; SICIVI: buffer_load_ushort 127; SICIVI: buffer_store_short 128 129; GFX9: s_load_dword 130; GFX9: buffer_store_dword 131; GFX9: buffer_store_dword 132; GFX9: buffer_load_ushort 133; GFX9: buffer_store_short 134define void @dynamic_extract_vector_elt_v4i16(i16 addrspace(1)* %out, <4 x i16> %foo, i32 %idx) #0 { 135 %p0 = extractelement <4 x i16> %foo, i32 %idx 136 %out1 = getelementptr i16, i16 addrspace(1)* %out, i32 1 137 store i16 %p0, i16 addrspace(1)* %out 138 ret void 139} 140 141declare i32 @llvm.amdgcn.workitem.id.x() #1 142 143attributes #0 = { nounwind } 144attributes #1 = { nounwind readnone } 145