1; RUN: llc -amdgpu-scalarize-global-loads=false -march=amdgcn -mtriple=amdgcn-- -mcpu=verde -verify-machineinstrs < %s | FileCheck -allow-deprecated-dag-overlap -check-prefix=GCN -check-prefix=SI -check-prefix=FUNC %s 2; RUN: llc -amdgpu-scalarize-global-loads=false -march=amdgcn -mtriple=amdgcn-- -mcpu=tonga -mattr=-flat-for-global -verify-machineinstrs < %s | FileCheck -allow-deprecated-dag-overlap -check-prefix=GCN -check-prefix=VI -check-prefix=FUNC %s 3; RUN: llc -amdgpu-scalarize-global-loads=false -march=r600 -mtriple=r600-- -mcpu=redwood -verify-machineinstrs < %s | FileCheck -allow-deprecated-dag-overlap -check-prefix=EG -check-prefix=FUNC %s 4 5declare i32 @llvm.amdgcn.workitem.id.x() #0 6 7; FUNC-LABEL: {{^}}ashr_v2i32: 8; SI: v_ashr_i32_e32 v{{[0-9]+, v[0-9]+, v[0-9]+}} 9; SI: v_ashr_i32_e32 v{{[0-9]+, v[0-9]+, v[0-9]+}} 10 11; VI: v_ashrrev_i32_e32 v{{[0-9]+, v[0-9]+, v[0-9]+}} 12; VI: v_ashrrev_i32_e32 v{{[0-9]+, v[0-9]+, v[0-9]+}} 13 14; EG: ASHR {{\*? *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} 15; EG: ASHR {{\*? *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} 16define amdgpu_kernel void @ashr_v2i32(<2 x i32> addrspace(1)* %out, <2 x i32> addrspace(1)* %in) { 17 %b_ptr = getelementptr <2 x i32>, <2 x i32> addrspace(1)* %in, i32 1 18 %a = load <2 x i32>, <2 x i32> addrspace(1)* %in 19 %b = load <2 x i32>, <2 x i32> addrspace(1)* %b_ptr 20 %result = ashr <2 x i32> %a, %b 21 store <2 x i32> %result, <2 x i32> addrspace(1)* %out 22 ret void 23} 24 25; FUNC-LABEL: {{^}}ashr_v4i32: 26; SI: v_ashr_i32_e32 v{{[0-9]+, v[0-9]+, v[0-9]+}} 27; SI: v_ashr_i32_e32 v{{[0-9]+, v[0-9]+, v[0-9]+}} 28; SI: v_ashr_i32_e32 v{{[0-9]+, v[0-9]+, v[0-9]+}} 29; SI: v_ashr_i32_e32 v{{[0-9]+, v[0-9]+, v[0-9]+}} 30 31; VI: v_ashrrev_i32_e32 v{{[0-9]+, v[0-9]+, v[0-9]+}} 32; VI: v_ashrrev_i32_e32 v{{[0-9]+, v[0-9]+, v[0-9]+}} 33; VI: v_ashrrev_i32_e32 v{{[0-9]+, v[0-9]+, v[0-9]+}} 34; VI: v_ashrrev_i32_e32 v{{[0-9]+, v[0-9]+, v[0-9]+}} 35 36; EG: ASHR {{\*? *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} 37; EG: ASHR {{\*? *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} 38; EG: ASHR {{\*? *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} 39; EG: ASHR {{\*? *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} 40define amdgpu_kernel void @ashr_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> addrspace(1)* %in) { 41 %b_ptr = getelementptr <4 x i32>, <4 x i32> addrspace(1)* %in, i32 1 42 %a = load <4 x i32>, <4 x i32> addrspace(1)* %in 43 %b = load <4 x i32>, <4 x i32> addrspace(1)* %b_ptr 44 %result = ashr <4 x i32> %a, %b 45 store <4 x i32> %result, <4 x i32> addrspace(1)* %out 46 ret void 47} 48 49; FUNC-LABEL: {{^}}ashr_v2i16: 50; FIXME: The ashr operation is uniform, but because its operands come from a 51; global load we end up with the vector instructions rather than scalar. 52; VI: v_ashrrev_i32_sdwa v{{[0-9]+}}, sext(v{{[0-9]+}}), sext(v{{[0-9]+}}) dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:WORD_0 53; VI: v_ashrrev_i32_sdwa v{{[0-9]+}}, sext(v{{[0-9]+}}), sext(v{{[0-9]+}}) dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:WORD_1 54define amdgpu_kernel void @ashr_v2i16(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(1)* %in) { 55 %b_ptr = getelementptr <2 x i16>, <2 x i16> addrspace(1)* %in, i16 1 56 %a = load <2 x i16>, <2 x i16> addrspace(1)* %in 57 %b = load <2 x i16>, <2 x i16> addrspace(1)* %b_ptr 58 %result = ashr <2 x i16> %a, %b 59 store <2 x i16> %result, <2 x i16> addrspace(1)* %out 60 ret void 61} 62 63; FUNC-LABEL: {{^}}ashr_v4i16: 64; FIXME: The ashr operation is uniform, but because its operands come from a 65; global load we end up with the vector instructions rather than scalar. 66; VI: v_ashrrev_i32_sdwa v{{[0-9]+}}, sext(v{{[0-9]+}}), sext(v{{[0-9]+}}) dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:WORD_0 67; VI: v_ashrrev_i32_sdwa v{{[0-9]+}}, sext(v{{[0-9]+}}), sext(v{{[0-9]+}}) dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:WORD_1 68; VI: v_ashrrev_i32_sdwa v{{[0-9]+}}, sext(v{{[0-9]+}}), sext(v{{[0-9]+}}) dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:WORD_0 69; VI: v_ashrrev_i32_sdwa v{{[0-9]+}}, sext(v{{[0-9]+}}), sext(v{{[0-9]+}}) dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:WORD_1 70define amdgpu_kernel void @ashr_v4i16(<4 x i16> addrspace(1)* %out, <4 x i16> addrspace(1)* %in) { 71 %b_ptr = getelementptr <4 x i16>, <4 x i16> addrspace(1)* %in, i16 1 72 %a = load <4 x i16>, <4 x i16> addrspace(1)* %in 73 %b = load <4 x i16>, <4 x i16> addrspace(1)* %b_ptr 74 %result = ashr <4 x i16> %a, %b 75 store <4 x i16> %result, <4 x i16> addrspace(1)* %out 76 ret void 77} 78 79; FUNC-LABEL: {{^}}s_ashr_i64: 80; GCN: s_ashr_i64 s[{{[0-9]}}:{{[0-9]}}], s[{{[0-9]}}:{{[0-9]}}], 8 81 82; EG: ASHR 83define amdgpu_kernel void @s_ashr_i64(i64 addrspace(1)* %out, i32 %in) { 84entry: 85 %in.ext = sext i32 %in to i64 86 %ashr = ashr i64 %in.ext, 8 87 store i64 %ashr, i64 addrspace(1)* %out 88 ret void 89} 90 91; FUNC-LABEL: {{^}}ashr_i64_2: 92; SI: v_ashr_i64 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], v[0-9]+}} 93 94; VI: v_ashrrev_i64 {{v\[[0-9]+:[0-9]+\], v[0-9]+, v\[[0-9]+:[0-9]+\]}} 95 96; EG: SUB_INT {{\*? *}}[[COMPSH:T[0-9]+\.[XYZW]]], {{literal.[xy]}}, [[SHIFT:T[0-9]+\.[XYZW]]] 97; EG: LSHL {{\* *}}[[TEMP:T[0-9]+\.[XYZW]]], [[OPHI:T[0-9]+\.[XYZW]]], {{[[COMPSH]]|PV.[XYZW]}} 98; EG-DAG: ADD_INT {{\*? *}}[[BIGSH:T[0-9]+\.[XYZW]]], [[SHIFT]], literal 99; EG-DAG: LSHL {{\*? *}}[[OVERF:T[0-9]+\.[XYZW]]], {{[[TEMP]]|PV.[XYZW]}}, 1 100; EG-DAG: LSHR {{\*? *}}[[LOSMTMP:T[0-9]+\.[XYZW]]], [[OPLO:T[0-9]+\.[XYZW]]], [[SHIFT]] 101; EG-DAG: OR_INT {{\*? *}}[[LOSM:T[0-9]+\.[XYZW]]], {{[[LOSMTMP]]|PV.[XYZW]|PS}}, {{[[OVERF]]|PV.[XYZW]}} 102; EG-DAG: ASHR {{\*? *}}[[HISM:T[0-9]+\.[XYZW]]], [[OPHI]], {{PS|PV.[XYZW]|[[SHIFT]]}} 103; EG-DAG: ASHR {{\*? *}}[[LOBIG:T[0-9]+\.[XYZW]]], [[OPHI]], literal 104; EG-DAG: ASHR {{\*? *}}[[HIBIG:T[0-9]+\.[XYZW]]], [[OPHI]], literal 105; EG-DAG: SETGT_UINT {{\*? *}}[[RESC:T[0-9]+\.[XYZW]]], [[SHIFT]], literal 106; EG-DAG: CNDE_INT {{\*? *}}[[RESLO:T[0-9]+\.[XYZW]]], {{T[0-9]+\.[XYZW]}} 107; EG-DAG: CNDE_INT {{\*? *}}[[RESHI:T[0-9]+\.[XYZW]]], {{T[0-9]+\.[XYZW]}} 108define amdgpu_kernel void @ashr_i64_2(i64 addrspace(1)* %out, i64 addrspace(1)* %in) { 109entry: 110 %b_ptr = getelementptr i64, i64 addrspace(1)* %in, i64 1 111 %a = load i64, i64 addrspace(1)* %in 112 %b = load i64, i64 addrspace(1)* %b_ptr 113 %result = ashr i64 %a, %b 114 store i64 %result, i64 addrspace(1)* %out 115 ret void 116} 117 118; FUNC-LABEL: {{^}}ashr_v2i64: 119; SI: v_ashr_i64 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], v[0-9]+}} 120; VI: v_ashrrev_i64 {{v\[[0-9]+:[0-9]+\], v[0-9]+, v\[[0-9]+:[0-9]+\]}} 121 122; EG-DAG: SUB_INT {{\*? *}}[[COMPSHA:T[0-9]+\.[XYZW]]], {{literal.[xy]}}, [[SHA:T[0-9]+\.[XYZW]]] 123; EG-DAG: SUB_INT {{\*? *}}[[COMPSHB:T[0-9]+\.[XYZW]]], {{literal.[xy]}}, [[SHB:T[0-9]+\.[XYZW]]] 124; EG-DAG: LSHL {{\*? *}}[[COMPSHA]] 125; EG-DAG: LSHL {{\*? *}}[[COMPSHB]] 126; EG-DAG: LSHL {{.*}}, 1 127; EG-DAG: LSHL {{.*}}, 1 128; EG-DAG: ASHR {{.*}}, [[SHA]] 129; EG-DAG: ASHR {{.*}}, [[SHB]] 130; EG-DAG: LSHR {{.*}}, [[SHA]] 131; EG-DAG: LSHR {{.*}}, [[SHB]] 132; EG-DAG: OR_INT 133; EG-DAG: OR_INT 134; EG-DAG: ADD_INT {{\*? *}}[[BIGSHA:T[0-9]+\.[XYZW]]]{{.*}}, literal 135; EG-DAG: ADD_INT {{\*? *}}[[BIGSHB:T[0-9]+\.[XYZW]]]{{.*}}, literal 136; EG-DAG: ASHR 137; EG-DAG: ASHR 138; EG-DAG: ASHR {{.*}}, literal 139; EG-DAG: ASHR {{.*}}, literal 140; EG-DAG: SETGT_UINT {{\*? *T[0-9]\.[XYZW]}}, [[SHA]], literal 141; EG-DAG: SETGT_UINT {{\*? *T[0-9]\.[XYZW]}}, [[SHB]], literal 142; EG-DAG: CNDE_INT 143; EG-DAG: CNDE_INT 144; EG-DAG: CNDE_INT 145; EG-DAG: CNDE_INT 146define amdgpu_kernel void @ashr_v2i64(<2 x i64> addrspace(1)* %out, <2 x i64> addrspace(1)* %in) { 147 %b_ptr = getelementptr <2 x i64>, <2 x i64> addrspace(1)* %in, i64 1 148 %a = load <2 x i64>, <2 x i64> addrspace(1)* %in 149 %b = load <2 x i64>, <2 x i64> addrspace(1)* %b_ptr 150 %result = ashr <2 x i64> %a, %b 151 store <2 x i64> %result, <2 x i64> addrspace(1)* %out 152 ret void 153} 154 155; FIXME: Broken on r600 156; XFUNC-LABEL: {{^}}s_ashr_v2i64: 157; XGCN: s_ashr_i64 {{s\[[0-9]+:[0-9]+\], s\[[0-9]+:[0-9]+\], s[0-9]+}} 158; XGCN: s_ashr_i64 {{s\[[0-9]+:[0-9]+\], s\[[0-9]+:[0-9]+\], s[0-9]+}} 159; define amdgpu_kernel void @s_ashr_v2i64(<2 x i64> addrspace(1)* %out, <2 x i64> addrspace(1)* %in, <2 x i64> %a, <2 x i64> %b) { 160; %result = ashr <2 x i64> %a, %b 161; store <2 x i64> %result, <2 x i64> addrspace(1)* %out 162; ret void 163; } 164 165; FUNC-LABEL: {{^}}ashr_v4i64: 166; SI: v_ashr_i64 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], v[0-9]+}} 167; SI: v_ashr_i64 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], v[0-9]+}} 168; SI: v_ashr_i64 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], v[0-9]+}} 169; SI: v_ashr_i64 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], v[0-9]+}} 170 171; VI: v_ashrrev_i64 {{v\[[0-9]+:[0-9]+\], v[0-9]+, v\[[0-9]+:[0-9]+\]}} 172; VI: v_ashrrev_i64 {{v\[[0-9]+:[0-9]+\], v[0-9]+, v\[[0-9]+:[0-9]+\]}} 173; VI: v_ashrrev_i64 {{v\[[0-9]+:[0-9]+\], v[0-9]+, v\[[0-9]+:[0-9]+\]}} 174; VI: v_ashrrev_i64 {{v\[[0-9]+:[0-9]+\], v[0-9]+, v\[[0-9]+:[0-9]+\]}} 175 176; EG-DAG: SUB_INT {{\*? *}}[[COMPSHA:T[0-9]+\.[XYZW]]], {{literal.[xy]}}, [[SHA:T[0-9]+\.[XYZW]]] 177; EG-DAG: SUB_INT {{\*? *}}[[COMPSHB:T[0-9]+\.[XYZW]]], {{literal.[xy]}}, [[SHB:T[0-9]+\.[XYZW]]] 178; EG-DAG: SUB_INT {{\*? *}}[[COMPSHC:T[0-9]+\.[XYZW]]], {{literal.[xy]}}, [[SHC:T[0-9]+\.[XYZW]]] 179; EG-DAG: SUB_INT {{\*? *}}[[COMPSHD:T[0-9]+\.[XYZW]]], {{literal.[xy]}}, [[SHD:T[0-9]+\.[XYZW]]] 180; EG-DAG: LSHL {{\*? *}}[[COMPSHA]] 181; EG-DAG: LSHL {{\*? *}}[[COMPSHB]] 182; EG-DAG: LSHL {{\*? *}}[[COMPSHC]] 183; EG-DAG: LSHL {{\*? *}}[[COMPSHD]] 184; EG-DAG: LSHL {{.*}}, 1 185; EG-DAG: LSHL {{.*}}, 1 186; EG-DAG: LSHL {{.*}}, 1 187; EG-DAG: LSHL {{.*}}, 1 188; EG-DAG: ASHR {{.*}}, [[SHA]] 189; EG-DAG: ASHR {{.*}}, [[SHB]] 190; EG-DAG: ASHR {{.*}}, [[SHC]] 191; EG-DAG: ASHR {{.*}}, [[SHD]] 192; EG-DAG: LSHR {{.*}}, [[SHA]] 193; EG-DAG: LSHR {{.*}}, [[SHB]] 194; EG-DAG: LSHR {{.*}}, [[SHA]] 195; EG-DAG: LSHR {{.*}}, [[SHB]] 196; EG-DAG: OR_INT 197; EG-DAG: OR_INT 198; EG-DAG: OR_INT 199; EG-DAG: OR_INT 200; EG-DAG: ADD_INT {{\*? *}}[[BIGSHA:T[0-9]+\.[XYZW]]]{{.*}}, literal 201; EG-DAG: ADD_INT {{\*? *}}[[BIGSHB:T[0-9]+\.[XYZW]]]{{.*}}, literal 202; EG-DAG: ADD_INT {{\*? *}}[[BIGSHC:T[0-9]+\.[XYZW]]]{{.*}}, literal 203; EG-DAG: ADD_INT {{\*? *}}[[BIGSHD:T[0-9]+\.[XYZW]]]{{.*}}, literal 204; EG-DAG: ASHR 205; EG-DAG: ASHR 206; EG-DAG: ASHR 207; EG-DAG: ASHR 208; EG-DAG: ASHR {{.*}}, literal 209; EG-DAG: ASHR {{.*}}, literal 210; EG-DAG: ASHR {{.*}}, literal 211; EG-DAG: ASHR {{.*}}, literal 212; EG-DAG: SETGT_UINT {{\*? *T[0-9]\.[XYZW]}}, [[SHA]], literal 213; EG-DAG: SETGT_UINT {{\*? *T[0-9]\.[XYZW]}}, [[SHB]], literal 214; EG-DAG: SETGT_UINT {{\*? *T[0-9]\.[XYZW]}}, [[SHC]], literal 215; EG-DAG: SETGT_UINT {{\*? *T[0-9]\.[XYZW]}}, [[SHD]], literal 216; EG-DAG: CNDE_INT 217; EG-DAG: CNDE_INT 218; EG-DAG: CNDE_INT 219; EG-DAG: CNDE_INT 220; EG-DAG: CNDE_INT 221; EG-DAG: CNDE_INT 222; EG-DAG: CNDE_INT 223; EG-DAG: CNDE_INT 224define amdgpu_kernel void @ashr_v4i64(<4 x i64> addrspace(1)* %out, <4 x i64> addrspace(1)* %in) { 225 %b_ptr = getelementptr <4 x i64>, <4 x i64> addrspace(1)* %in, i64 1 226 %a = load <4 x i64>, <4 x i64> addrspace(1)* %in 227 %b = load <4 x i64>, <4 x i64> addrspace(1)* %b_ptr 228 %result = ashr <4 x i64> %a, %b 229 store <4 x i64> %result, <4 x i64> addrspace(1)* %out 230 ret void 231} 232 233; GCN-LABEL: {{^}}s_ashr_32_i64: 234; GCN: s_load_dword s[[HI:[0-9]+]], {{s\[[0-9]+:[0-9]+\]}}, {{0x14|0x50}} 235; GCN: s_ashr_i32 s[[SHIFT:[0-9]+]], s[[HI]], 31 236; GCN: s_add_u32 s{{[0-9]+}}, s[[HI]], s{{[0-9]+}} 237; GCN: s_addc_u32 s{{[0-9]+}}, s[[SHIFT]], s{{[0-9]+}} 238define amdgpu_kernel void @s_ashr_32_i64(i64 addrspace(1)* %out, [8 x i32], i64 %a, [8 x i32], i64 %b) { 239 %result = ashr i64 %a, 32 240 %add = add i64 %result, %b 241 store i64 %add, i64 addrspace(1)* %out 242 ret void 243} 244 245; GCN-LABEL: {{^}}v_ashr_32_i64: 246; SI: buffer_load_dword v[[HI:[0-9]+]], {{v\[[0-9]+:[0-9]+\]}}, {{s\[[0-9]+:[0-9]+\]}}, 0 addr64 offset:4 247; VI: flat_load_dword v[[HI:[0-9]+]] 248; GCN: v_ashrrev_i32_e32 v[[SHIFT:[0-9]+]], 31, v[[HI]] 249; GCN: {{buffer|flat}}_store_dwordx2 {{.*}}v{{\[}}[[HI]]:[[SHIFT]]{{\]}} 250define amdgpu_kernel void @v_ashr_32_i64(i64 addrspace(1)* %out, i64 addrspace(1)* %in) { 251 %tid = call i32 @llvm.amdgcn.workitem.id.x() #0 252 %gep.in = getelementptr i64, i64 addrspace(1)* %in, i32 %tid 253 %gep.out = getelementptr i64, i64 addrspace(1)* %out, i32 %tid 254 %a = load i64, i64 addrspace(1)* %gep.in 255 %result = ashr i64 %a, 32 256 store i64 %result, i64 addrspace(1)* %gep.out 257 ret void 258} 259 260; GCN-LABEL: {{^}}s_ashr_63_i64: 261; GCN: s_load_dword s[[HI:[0-9]+]], {{s\[[0-9]+:[0-9]+\]}}, {{0x14|0x50}} 262; GCN: s_ashr_i32 s[[SHIFT:[0-9]+]], s[[HI]], 31 263; GCN: s_add_u32 {{s[0-9]+}}, s[[SHIFT]], {{s[0-9]+}} 264; GCN: s_addc_u32 {{s[0-9]+}}, s[[SHIFT]], {{s[0-9]+}} 265define amdgpu_kernel void @s_ashr_63_i64(i64 addrspace(1)* %out, [8 x i32], i64 %a, [8 x i32], i64 %b) { 266 %result = ashr i64 %a, 63 267 %add = add i64 %result, %b 268 store i64 %add, i64 addrspace(1)* %out 269 ret void 270} 271 272; GCN-LABEL: {{^}}v_ashr_63_i64: 273; SI: buffer_load_dword v[[HI:[0-9]+]], {{v\[[0-9]+:[0-9]+\]}}, {{s\[[0-9]+:[0-9]+\]}}, 0 addr64 offset:4 274; VI: flat_load_dword v[[HI:[0-9]+]] 275; GCN: v_ashrrev_i32_e32 v[[SHIFT:[0-9]+]], 31, v[[HI]] 276; GCN: v_mov_b32_e32 v[[COPY:[0-9]+]], v[[SHIFT]] 277; GCN: {{buffer|flat}}_store_dwordx2 {{.*}}v{{\[}}[[SHIFT]]:[[COPY]]{{\]}} 278define amdgpu_kernel void @v_ashr_63_i64(i64 addrspace(1)* %out, i64 addrspace(1)* %in) { 279 %tid = call i32 @llvm.amdgcn.workitem.id.x() #0 280 %gep.in = getelementptr i64, i64 addrspace(1)* %in, i32 %tid 281 %gep.out = getelementptr i64, i64 addrspace(1)* %out, i32 %tid 282 %a = load i64, i64 addrspace(1)* %gep.in 283 %result = ashr i64 %a, 63 284 store i64 %result, i64 addrspace(1)* %gep.out 285 ret void 286} 287 288attributes #0 = { nounwind readnone } 289