1; RUN: llc -march=amdgcn -mcpu=SI -verify-machineinstrs < %s | FileCheck -check-prefix=SI -check-prefix=GCN -check-prefix=SI-NOHSA -check-prefix=GCN-NOHSA -check-prefix=FUNC %s 2; RUN: llc -march=amdgcn -mcpu=tonga -verify-machineinstrs < %s | FileCheck -check-prefix=VI -check-prefix=VI-NOHSA -check-prefix=GCN -check-prefix=GCN-NOHSA -check-prefix=FUNC %s 3; RUN: llc -march=r600 -mcpu=redwood < %s | FileCheck -check-prefix=EG -check-prefix=FUNC %s 4 5 6; FUNC-LABEL: {{^}}local_size_x: 7; EG: MEM_RAT_CACHELESS STORE_RAW [[VAL:T[0-9]+\.X]] 8; EG: MOV * [[VAL]], KC0[1].Z 9 10; SI-NOHSA: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x6 11; VI-NOHSA: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x18 12; CI-HSA: s_load_dword [[XY:s[0-9]+]], s[4:5], 0x1 13; VI-HSA: s_load_dword [[XY:s[0-9]+]], s[4:5], 0x4 14 15; GCN: v_mov_b32_e32 [[VVAL:v[0-9]+]], [[VAL]] 16; GCN: buffer_store_dword [[VVAL]] 17define void @local_size_x(i32 addrspace(1)* %out) { 18entry: 19 %0 = call i32 @llvm.r600.read.local.size.x() #0 20 store i32 %0, i32 addrspace(1)* %out 21 ret void 22} 23 24; FUNC-LABEL: {{^}}local_size_y: 25; EG: MEM_RAT_CACHELESS STORE_RAW [[VAL:T[0-9]+\.X]] 26; EG: MOV * [[VAL]], KC0[1].W 27 28; SI-NOHSA: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x7 29; VI-NOHSA: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x1c 30; GCN: v_mov_b32_e32 [[VVAL:v[0-9]+]], [[VAL]] 31; GCN: buffer_store_dword [[VVAL]] 32define void @local_size_y(i32 addrspace(1)* %out) { 33entry: 34 %0 = call i32 @llvm.r600.read.local.size.y() #0 35 store i32 %0, i32 addrspace(1)* %out 36 ret void 37} 38 39; FUNC-LABEL: {{^}}local_size_z: 40; EG: MEM_RAT_CACHELESS STORE_RAW [[VAL:T[0-9]+\.X]] 41; EG: MOV * [[VAL]], KC0[2].X 42 43; SI-NOHSA: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x8 44; VI-NOHSA: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x20 45; GCN: v_mov_b32_e32 [[VVAL:v[0-9]+]], [[VAL]] 46; GCN: buffer_store_dword [[VVAL]] 47define void @local_size_z(i32 addrspace(1)* %out) { 48entry: 49 %0 = call i32 @llvm.r600.read.local.size.z() #0 50 store i32 %0, i32 addrspace(1)* %out 51 ret void 52} 53 54; FUNC-LABEL: {{^}}local_size_xy: 55; SI-NOHSA-DAG: s_load_dword [[X:s[0-9]+]], s[0:1], 0x6 56; SI-NOHSA-DAG: s_load_dword [[Y:s[0-9]+]], s[0:1], 0x7 57; VI-NOHSA-DAG: s_load_dword [[X:s[0-9]+]], s[0:1], 0x18 58; VI-NOHSA-DAG: s_load_dword [[Y:s[0-9]+]], s[0:1], 0x1c 59; GCN-DAG: v_mov_b32_e32 [[VY:v[0-9]+]], [[Y]] 60; GCN: v_mul_u32_u24_e32 [[VAL:v[0-9]+]], [[X]], [[VY]] 61; GCN: buffer_store_dword [[VAL]] 62define void @local_size_xy(i32 addrspace(1)* %out) { 63entry: 64 %x = call i32 @llvm.r600.read.local.size.x() #0 65 %y = call i32 @llvm.r600.read.local.size.y() #0 66 %val = mul i32 %x, %y 67 store i32 %val, i32 addrspace(1)* %out 68 ret void 69} 70 71; FUNC-LABEL: {{^}}local_size_xz: 72 73; SI-NOHSA-DAG: s_load_dword [[X:s[0-9]+]], s[0:1], 0x6 74; SI-NOHSA-DAG: s_load_dword [[Z:s[0-9]+]], s[0:1], 0x8 75; VI-NOHSA-DAG: s_load_dword [[X:s[0-9]+]], s[0:1], 0x18 76; VI-NOHSA-DAG: s_load_dword [[Z:s[0-9]+]], s[0:1], 0x20 77; HSA-DAG: s_and_b32 [[X:s[0-9]+]], [[XY]], 0xffff 78; GCN-DAG: v_mov_b32_e32 [[VZ:v[0-9]+]], [[Z]] 79; GCN: v_mul_u32_u24_e32 [[VAL:v[0-9]+]], [[X]], [[VZ]] 80; GCN: buffer_store_dword [[VAL]] 81define void @local_size_xz(i32 addrspace(1)* %out) { 82entry: 83 %x = call i32 @llvm.r600.read.local.size.x() #0 84 %z = call i32 @llvm.r600.read.local.size.z() #0 85 %val = mul i32 %x, %z 86 store i32 %val, i32 addrspace(1)* %out 87 ret void 88} 89 90; FUNC-LABEL: {{^}}local_size_yz: 91; HSA: enable_sgpr_private_segment_buffer = 1 92; HSA: enable_sgpr_dispatch_ptr = 1 93 94; SI-NOHSA-DAG: s_load_dword [[Y:s[0-9]+]], s[0:1], 0x7 95; SI-NOHSA-DAG: s_load_dword [[Z:s[0-9]+]], s[0:1], 0x8 96; VI-NOHSA-DAG: s_load_dword [[Y:s[0-9]+]], s[0:1], 0x1c 97; VI-NOHSA-DAG: s_load_dword [[Z:s[0-9]+]], s[0:1], 0x20 98; GCN-DAG: v_mov_b32_e32 [[VZ:v[0-9]+]], [[Z]] 99; GCN: v_mul_u32_u24_e32 [[VAL:v[0-9]+]], [[Y]], [[VZ]] 100; GCN: buffer_store_dword [[VAL]] 101define void @local_size_yz(i32 addrspace(1)* %out) { 102entry: 103 %y = call i32 @llvm.r600.read.local.size.y() #0 104 %z = call i32 @llvm.r600.read.local.size.z() #0 105 %val = mul i32 %y, %z 106 store i32 %val, i32 addrspace(1)* %out 107 ret void 108} 109 110; FUNC-LABEL: {{^}}local_size_xyz: 111; HSA: enable_sgpr_private_segment_buffer = 1 112; HSA: enable_sgpr_dispatch_ptr = 1 113 114; SI-NOHSA-DAG: s_load_dword [[X:s[0-9]+]], s[0:1], 0x6 115; SI-NOHSA-DAG: s_load_dword [[Y:s[0-9]+]], s[0:1], 0x7 116; SI-NOHSA-DAG: s_load_dword [[Z:s[0-9]+]], s[0:1], 0x8 117; VI-NOHSA-DAG: s_load_dword [[X:s[0-9]+]], s[0:1], 0x18 118; VI-NOHSA-DAG: s_load_dword [[Y:s[0-9]+]], s[0:1], 0x1c 119; VI-NOHSA-DAG: s_load_dword [[Z:s[0-9]+]], s[0:1], 0x20 120; GCN-DAG: v_mov_b32_e32 [[VY:v[0-9]+]], [[Y]] 121; GCN-DAG: v_mov_b32_e32 [[VZ:v[0-9]+]], [[Z]] 122; GCN: v_mad_u32_u24 [[VAL:v[0-9]+]], [[X]], [[VY]], [[VZ]] 123; GCN: buffer_store_dword [[VAL]] 124define void @local_size_xyz(i32 addrspace(1)* %out) { 125entry: 126 %x = call i32 @llvm.r600.read.local.size.x() #0 127 %y = call i32 @llvm.r600.read.local.size.y() #0 128 %z = call i32 @llvm.r600.read.local.size.z() #0 129 %xy = mul i32 %x, %y 130 %xyz = add i32 %xy, %z 131 store i32 %xyz, i32 addrspace(1)* %out 132 ret void 133} 134 135; FUNC-LABEL: {{^}}local_size_x_known_bits: 136; SI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x6 137; VI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x18 138; GCN-NOT: 0xffff 139; GCN: v_mov_b32_e32 [[VVAL:v[0-9]+]], [[VAL]] 140; GCN-NEXT: buffer_store_dword [[VVAL]] 141define void @local_size_x_known_bits(i32 addrspace(1)* %out) { 142entry: 143 %size = call i32 @llvm.r600.read.local.size.x() #0 144 %shl = shl i32 %size, 16 145 %shr = lshr i32 %shl, 16 146 store i32 %shr, i32 addrspace(1)* %out 147 ret void 148} 149 150; FUNC-LABEL: {{^}}local_size_y_known_bits: 151; SI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x7 152; VI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x1c 153; GCN-NOT: 0xffff 154; GCN: v_mov_b32_e32 [[VVAL:v[0-9]+]], [[VAL]] 155; GCN-NEXT: buffer_store_dword [[VVAL]] 156define void @local_size_y_known_bits(i32 addrspace(1)* %out) { 157entry: 158 %size = call i32 @llvm.r600.read.local.size.y() #0 159 %shl = shl i32 %size, 16 160 %shr = lshr i32 %shl, 16 161 store i32 %shr, i32 addrspace(1)* %out 162 ret void 163} 164 165; FUNC-LABEL: {{^}}local_size_z_known_bits: 166; SI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x8 167; VI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x20 168; GCN-NOT: 0xffff 169; GCN: v_mov_b32_e32 [[VVAL:v[0-9]+]], [[VAL]] 170; GCN-NEXT: buffer_store_dword [[VVAL]] 171define void @local_size_z_known_bits(i32 addrspace(1)* %out) { 172entry: 173 %size = call i32 @llvm.r600.read.local.size.z() #0 174 %shl = shl i32 %size, 16 175 %shr = lshr i32 %shl, 16 176 store i32 %shr, i32 addrspace(1)* %out 177 ret void 178} 179 180declare i32 @llvm.r600.read.local.size.x() #0 181declare i32 @llvm.r600.read.local.size.y() #0 182declare i32 @llvm.r600.read.local.size.z() #0 183 184attributes #0 = { nounwind readnone } 185