1; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=SI -check-prefix=FUNC %s 2; RUN: llc -march=amdgcn -mcpu=tonga -mattr=-flat-for-global -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=VI -check-prefix=GFX89 -check-prefix=FUNC %s 3; RUN: llc -march=amdgcn -mcpu=gfx901 -mattr=-flat-for-global -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=GFX9 -check-prefix=GFX89 -check-prefix=FUNC %s 4; RUN: llc -march=r600 -mcpu=cypress < %s | FileCheck -check-prefix=EG -check-prefix=FUNC %s 5 6; FIXME: i16 promotion pass ruins the scalar cases when legal. 7; FIXME: r600 fails verifier 8 9; FUNC-LABEL: {{^}}sext_in_reg_i1_i32: 10; GCN: s_load_dword [[ARG:s[0-9]+]], 11; GCN: s_bfe_i32 [[SEXTRACT:s[0-9]+]], [[ARG]], 0x10000 12; GCN: v_mov_b32_e32 [[EXTRACT:v[0-9]+]], [[SEXTRACT]] 13; GCN: buffer_store_dword [[EXTRACT]], 14 15; EG: MEM_{{.*}} STORE_{{.*}} [[RES:T[0-9]+\.[XYZW]]], [[ADDR:T[0-9]+.[XYZW]]] 16; EG: LSHR * [[ADDR]] 17; EG: BFE_INT * [[RES]], {{.*}}, 0.0, 1 18define void @sext_in_reg_i1_i32(i32 addrspace(1)* %out, i32 %in) #0 { 19 %shl = shl i32 %in, 31 20 %sext = ashr i32 %shl, 31 21 store i32 %sext, i32 addrspace(1)* %out 22 ret void 23} 24 25; FUNC-LABEL: {{^}}sext_in_reg_i8_to_i32: 26; GCN: s_add_i32 [[VAL:s[0-9]+]], 27; GCN: s_sext_i32_i8 [[EXTRACT:s[0-9]+]], [[VAL]] 28; GCN: v_mov_b32_e32 [[VEXTRACT:v[0-9]+]], [[EXTRACT]] 29; GCN: buffer_store_dword [[VEXTRACT]], 30 31; EG: MEM_{{.*}} STORE_{{.*}} [[RES:T[0-9]+\.[XYZW]]], [[ADDR:T[0-9]+.[XYZW]]] 32; EG: ADD_INT 33; EG-NEXT: BFE_INT [[RES]], {{.*}}, 0.0, literal 34; EG-NEXT: LSHR * [[ADDR]] 35define void @sext_in_reg_i8_to_i32(i32 addrspace(1)* %out, i32 %a, i32 %b) #0 { 36 %c = add i32 %a, %b ; add to prevent folding into extload 37 %shl = shl i32 %c, 24 38 %ashr = ashr i32 %shl, 24 39 store i32 %ashr, i32 addrspace(1)* %out, align 4 40 ret void 41} 42 43; FUNC-LABEL: {{^}}sext_in_reg_i16_to_i32: 44; GCN: s_add_i32 [[VAL:s[0-9]+]], 45; GCN: s_sext_i32_i16 [[EXTRACT:s[0-9]+]], [[VAL]] 46; GCN: v_mov_b32_e32 [[VEXTRACT:v[0-9]+]], [[EXTRACT]] 47; GCN: buffer_store_dword [[VEXTRACT]], 48 49; EG: MEM_{{.*}} STORE_{{.*}} [[RES:T[0-9]+\.[XYZW]]], [[ADDR:T[0-9]+.[XYZW]]] 50; EG: ADD_INT 51; EG-NEXT: BFE_INT [[RES]], {{.*}}, 0.0, literal 52; EG-NEXT: LSHR * [[ADDR]] 53define void @sext_in_reg_i16_to_i32(i32 addrspace(1)* %out, i32 %a, i32 %b) #0 { 54 %c = add i32 %a, %b ; add to prevent folding into extload 55 %shl = shl i32 %c, 16 56 %ashr = ashr i32 %shl, 16 57 store i32 %ashr, i32 addrspace(1)* %out, align 4 58 ret void 59} 60 61; FUNC-LABEL: {{^}}sext_in_reg_i8_to_v1i32: 62; GCN: s_add_i32 [[VAL:s[0-9]+]], 63; GCN: s_sext_i32_i8 [[EXTRACT:s[0-9]+]], [[VAL]] 64; GCN: v_mov_b32_e32 [[VEXTRACT:v[0-9]+]], [[EXTRACT]] 65; GCN: buffer_store_dword [[VEXTRACT]], 66 67; EG: MEM_{{.*}} STORE_{{.*}} [[RES:T[0-9]+\.[XYZW]]], [[ADDR:T[0-9]+.[XYZW]]] 68; EG: ADD_INT 69; EG-NEXT: BFE_INT [[RES]], {{.*}}, 0.0, literal 70; EG-NEXT: LSHR * [[ADDR]] 71define void @sext_in_reg_i8_to_v1i32(<1 x i32> addrspace(1)* %out, <1 x i32> %a, <1 x i32> %b) #0 { 72 %c = add <1 x i32> %a, %b ; add to prevent folding into extload 73 %shl = shl <1 x i32> %c, <i32 24> 74 %ashr = ashr <1 x i32> %shl, <i32 24> 75 store <1 x i32> %ashr, <1 x i32> addrspace(1)* %out, align 4 76 ret void 77} 78 79; FUNC-LABEL: {{^}}sext_in_reg_i1_to_i64: 80; GCN: s_lshl_b64 [[VAL:s\[[0-9]+:[0-9]+\]]] 81; GCN-DAG: s_bfe_i64 s{{\[}}[[SLO:[0-9]+]]:[[SHI:[0-9]+]]{{\]}}, [[VAL]], 0x10000 82; GCN-DAG: v_mov_b32_e32 v[[VLO:[0-9]+]], s[[SLO]] 83; GCN-DAG: v_mov_b32_e32 v[[VHI:[0-9]+]], s[[SHI]] 84; GCN: buffer_store_dwordx2 v{{\[}}[[VLO]]:[[VHI]]{{\]}} 85define void @sext_in_reg_i1_to_i64(i64 addrspace(1)* %out, i64 %a, i64 %b) #0 { 86 %c = shl i64 %a, %b 87 %shl = shl i64 %c, 63 88 %ashr = ashr i64 %shl, 63 89 store i64 %ashr, i64 addrspace(1)* %out, align 8 90 ret void 91} 92 93; FUNC-LABEL: {{^}}sext_in_reg_i8_to_i64: 94; GCN: s_lshl_b64 [[VAL:s\[[0-9]+:[0-9]+\]]] 95; GCN-DAG: s_bfe_i64 s{{\[}}[[SLO:[0-9]+]]:[[SHI:[0-9]+]]{{\]}}, [[VAL]], 0x80000 96; GCN-DAG: v_mov_b32_e32 v[[VLO:[0-9]+]], s[[SLO]] 97; GCN-DAG: v_mov_b32_e32 v[[VHI:[0-9]+]], s[[SHI]] 98; GCN: buffer_store_dwordx2 v{{\[}}[[VLO]]:[[VHI]]{{\]}} 99define void @sext_in_reg_i8_to_i64(i64 addrspace(1)* %out, i64 %a, i64 %b) #0 { 100 %c = shl i64 %a, %b 101 %shl = shl i64 %c, 56 102 %ashr = ashr i64 %shl, 56 103 store i64 %ashr, i64 addrspace(1)* %out, align 8 104 ret void 105} 106 107; FUNC-LABEL: {{^}}sext_in_reg_i16_to_i64: 108; GCN: s_lshl_b64 [[VAL:s\[[0-9]+:[0-9]+\]]] 109; GCN-DAG: s_bfe_i64 s{{\[}}[[SLO:[0-9]+]]:[[SHI:[0-9]+]]{{\]}}, [[VAL]], 0x100000 110; GCN-DAG: v_mov_b32_e32 v[[VLO:[0-9]+]], s[[SLO]] 111; GCN-DAG: v_mov_b32_e32 v[[VHI:[0-9]+]], s[[SHI]] 112; GCN: buffer_store_dwordx2 v{{\[}}[[VLO]]:[[VHI]]{{\]}} 113 114define void @sext_in_reg_i16_to_i64(i64 addrspace(1)* %out, i64 %a, i64 %b) #0 { 115 %c = shl i64 %a, %b 116 %shl = shl i64 %c, 48 117 %ashr = ashr i64 %shl, 48 118 store i64 %ashr, i64 addrspace(1)* %out, align 8 119 ret void 120} 121 122; FUNC-LABEL: {{^}}sext_in_reg_i32_to_i64: 123; GCN: s_lshl_b64 [[VAL:s\[[0-9]+:[0-9]+\]]] 124; GCN-DAG: s_bfe_i64 s{{\[}}[[SLO:[0-9]+]]:[[SHI:[0-9]+]]{{\]}}, [[VAL]], 0x200000 125; GCN-DAG: v_mov_b32_e32 v[[VLO:[0-9]+]], s[[SLO]] 126; GCN-DAG: v_mov_b32_e32 v[[VHI:[0-9]+]], s[[SHI]] 127; GCN: buffer_store_dwordx2 v{{\[}}[[VLO]]:[[VHI]]{{\]}} 128define void @sext_in_reg_i32_to_i64(i64 addrspace(1)* %out, i64 %a, i64 %b) #0 { 129 %c = shl i64 %a, %b 130 %shl = shl i64 %c, 32 131 %ashr = ashr i64 %shl, 32 132 store i64 %ashr, i64 addrspace(1)* %out, align 8 133 ret void 134} 135 136; This is broken on Evergreen for some reason related to the <1 x i64> kernel arguments. 137; XFUNC-LABEL: {{^}}sext_in_reg_i8_to_v1i64: 138; XGCN: s_bfe_i32 [[EXTRACT:s[0-9]+]], {{s[0-9]+}}, 524288 139; XGCN: s_ashr_i32 {{v[0-9]+}}, [[EXTRACT]], 31 140; XGCN: buffer_store_dword 141; XEG: BFE_INT 142; XEG: ASHR 143; define void @sext_in_reg_i8_to_v1i64(<1 x i64> addrspace(1)* %out, <1 x i64> %a, <1 x i64> %b) #0 { 144; %c = add <1 x i64> %a, %b 145; %shl = shl <1 x i64> %c, <i64 56> 146; %ashr = ashr <1 x i64> %shl, <i64 56> 147; store <1 x i64> %ashr, <1 x i64> addrspace(1)* %out, align 8 148; ret void 149; } 150 151; FUNC-LABEL: {{^}}v_sext_in_reg_i1_to_i64: 152; SI: buffer_load_dwordx2 153; SI: v_lshl_b64 v{{\[}}[[VAL_LO:[0-9]+]]:[[VAL_HI:[0-9]+]]{{\]}} 154 155; GFX89: flat_load_dwordx2 156; GFX89: v_lshlrev_b64 v{{\[}}[[VAL_LO:[0-9]+]]:[[VAL_HI:[0-9]+]]{{\]}} 157 158; GCN: v_bfe_i32 v[[LO:[0-9]+]], v[[VAL_LO]], 0, 1 159; GCN: v_ashrrev_i32_e32 v[[HI:[0-9]+]], 31, v[[LO]] 160 161; SI: buffer_store_dwordx2 v{{\[}}[[LO]]:[[HI]]{{\]}} 162; GFX89: flat_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, v{{\[}}[[LO]]:[[HI]]{{\]}} 163define void @v_sext_in_reg_i1_to_i64(i64 addrspace(1)* %out, i64 addrspace(1)* %aptr, i64 addrspace(1)* %bptr) #0 { 164 %tid = call i32 @llvm.r600.read.tidig.x() 165 %a.gep = getelementptr i64, i64 addrspace(1)* %aptr, i32 %tid 166 %b.gep = getelementptr i64, i64 addrspace(1)* %aptr, i32 %tid 167 %out.gep = getelementptr i64, i64 addrspace(1)* %out, i32 %tid 168 %a = load i64, i64 addrspace(1)* %a.gep, align 8 169 %b = load i64, i64 addrspace(1)* %b.gep, align 8 170 171 %c = shl i64 %a, %b 172 %shl = shl i64 %c, 63 173 %ashr = ashr i64 %shl, 63 174 store i64 %ashr, i64 addrspace(1)* %out.gep, align 8 175 ret void 176} 177 178; FUNC-LABEL: {{^}}v_sext_in_reg_i8_to_i64: 179; SI: buffer_load_dwordx2 180; SI: v_lshl_b64 v{{\[}}[[VAL_LO:[0-9]+]]:[[VAL_HI:[0-9]+]]{{\]}} 181 182; GFX89: flat_load_dwordx2 183; GFX89: v_lshlrev_b64 v{{\[}}[[VAL_LO:[0-9]+]]:[[VAL_HI:[0-9]+]]{{\]}} 184 185; GCN: v_bfe_i32 v[[LO:[0-9]+]], v[[VAL_LO]], 0, 8 186; GCN: v_ashrrev_i32_e32 v[[HI:[0-9]+]], 31, v[[LO]] 187 188; SI: buffer_store_dwordx2 v{{\[}}[[LO]]:[[HI]]{{\]}} 189; GFX89: flat_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, v{{\[}}[[LO]]:[[HI]]{{\]}} 190define void @v_sext_in_reg_i8_to_i64(i64 addrspace(1)* %out, i64 addrspace(1)* %aptr, i64 addrspace(1)* %bptr) #0 { 191 %tid = call i32 @llvm.r600.read.tidig.x() 192 %a.gep = getelementptr i64, i64 addrspace(1)* %aptr, i32 %tid 193 %b.gep = getelementptr i64, i64 addrspace(1)* %aptr, i32 %tid 194 %out.gep = getelementptr i64, i64 addrspace(1)* %out, i32 %tid 195 %a = load i64, i64 addrspace(1)* %a.gep, align 8 196 %b = load i64, i64 addrspace(1)* %b.gep, align 8 197 198 %c = shl i64 %a, %b 199 %shl = shl i64 %c, 56 200 %ashr = ashr i64 %shl, 56 201 store i64 %ashr, i64 addrspace(1)* %out.gep, align 8 202 ret void 203} 204 205; FUNC-LABEL: {{^}}v_sext_in_reg_i16_to_i64: 206; SI: buffer_load_dwordx2 207; SI: v_lshl_b64 v{{\[}}[[VAL_LO:[0-9]+]]:[[VAL_HI:[0-9]+]]{{\]}} 208 209; GFX89: flat_load_dwordx2 210; GFX89: v_lshlrev_b64 v{{\[}}[[VAL_LO:[0-9]+]]:[[VAL_HI:[0-9]+]]{{\]}} 211 212; GCN: v_bfe_i32 v[[LO:[0-9]+]], v[[VAL_LO]], 0, 16 213; GCN: v_ashrrev_i32_e32 v[[HI:[0-9]+]], 31, v[[LO]] 214 215; SI: buffer_store_dwordx2 v{{\[}}[[LO]]:[[HI]]{{\]}} 216; GFX89: flat_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, v{{\[}}[[LO]]:[[HI]]{{\]}} 217define void @v_sext_in_reg_i16_to_i64(i64 addrspace(1)* %out, i64 addrspace(1)* %aptr, i64 addrspace(1)* %bptr) #0 { 218 %tid = call i32 @llvm.r600.read.tidig.x() 219 %a.gep = getelementptr i64, i64 addrspace(1)* %aptr, i32 %tid 220 %b.gep = getelementptr i64, i64 addrspace(1)* %aptr, i32 %tid 221 %out.gep = getelementptr i64, i64 addrspace(1)* %out, i32 %tid 222 %a = load i64, i64 addrspace(1)* %a.gep, align 8 223 %b = load i64, i64 addrspace(1)* %b.gep, align 8 224 225 %c = shl i64 %a, %b 226 %shl = shl i64 %c, 48 227 %ashr = ashr i64 %shl, 48 228 store i64 %ashr, i64 addrspace(1)* %out.gep, align 8 229 ret void 230} 231 232; FUNC-LABEL: {{^}}v_sext_in_reg_i32_to_i64: 233; SI: buffer_load_dwordx2 234; SI: v_lshl_b64 v{{\[}}[[LO:[0-9]+]]:[[HI:[0-9]+]]{{\]}}, 235 236; GFX89: flat_load_dwordx2 237; GFX89: v_lshlrev_b64 v{{\[}}[[LO:[0-9]+]]:[[HI:[0-9]+]]{{\]}}, 238 239; GCN: v_ashrrev_i32_e32 v[[SHR:[0-9]+]], 31, v[[LO]] 240; GFX89: flat_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, v{{\[}}[[LO]]:[[SHR]]{{\]}} 241define void @v_sext_in_reg_i32_to_i64(i64 addrspace(1)* %out, i64 addrspace(1)* %aptr, i64 addrspace(1)* %bptr) #0 { 242 %tid = call i32 @llvm.r600.read.tidig.x() 243 %a.gep = getelementptr i64, i64 addrspace(1)* %aptr, i32 %tid 244 %b.gep = getelementptr i64, i64 addrspace(1)* %aptr, i32 %tid 245 %out.gep = getelementptr i64, i64 addrspace(1)* %out, i32 %tid 246 %a = load i64, i64 addrspace(1)* %a.gep, align 8 247 %b = load i64, i64 addrspace(1)* %b.gep, align 8 248 249 %c = shl i64 %a, %b 250 %shl = shl i64 %c, 32 251 %ashr = ashr i64 %shl, 32 252 store i64 %ashr, i64 addrspace(1)* %out.gep, align 8 253 ret void 254} 255 256; FUNC-LABEL: {{^}}sext_in_reg_i1_in_i32_other_amount: 257; GCN-NOT: s_lshl 258; GCN-NOT: s_ashr 259; GCN: s_bfe_i32 {{s[0-9]+}}, {{s[0-9]+}}, 0x190001 260 261; EG: MEM_{{.*}} STORE_{{.*}} [[RES:T[0-9]+\.[XYZW]]], [[ADDR:T[0-9]+.[XYZW]]] 262; EG-NOT: BFE 263; EG: ADD_INT 264; EG: LSHL 265; EG: ASHR [[RES]] 266; EG: LSHR {{\*?}} [[ADDR]] 267define void @sext_in_reg_i1_in_i32_other_amount(i32 addrspace(1)* %out, i32 %a, i32 %b) #0 { 268 %c = add i32 %a, %b 269 %x = shl i32 %c, 6 270 %y = ashr i32 %x, 7 271 store i32 %y, i32 addrspace(1)* %out 272 ret void 273} 274 275; FUNC-LABEL: {{^}}sext_in_reg_v2i1_in_v2i32_other_amount: 276; GCN-NOT: s_lshl 277; GCN-NOT: s_ashr 278; GCN-DAG: s_bfe_i32 {{s[0-9]+}}, {{s[0-9]+}}, 0x190001 279; GCN-DAG: s_bfe_i32 {{s[0-9]+}}, {{s[0-9]+}}, 0x190001 280; GCN: s_endpgm 281 282; EG: MEM_{{.*}} STORE_{{.*}} [[RES:T[0-9]+]]{{\.[XYZW][XYZW]}}, [[ADDR:T[0-9]+.[XYZW]]] 283; EG-NOT: BFE 284; EG: ADD_INT 285; EG: LSHL 286; EG: ASHR [[RES]] 287; EG: LSHL 288; EG: ASHR [[RES]] 289; EG: LSHR {{\*?}} [[ADDR]] 290define void @sext_in_reg_v2i1_in_v2i32_other_amount(<2 x i32> addrspace(1)* %out, <2 x i32> %a, <2 x i32> %b) #0 { 291 %c = add <2 x i32> %a, %b 292 %x = shl <2 x i32> %c, <i32 6, i32 6> 293 %y = ashr <2 x i32> %x, <i32 7, i32 7> 294 store <2 x i32> %y, <2 x i32> addrspace(1)* %out 295 ret void 296} 297 298 299; FUNC-LABEL: {{^}}sext_in_reg_v2i1_to_v2i32: 300; GCN: s_bfe_i32 {{s[0-9]+}}, {{s[0-9]+}}, 0x10000 301; GCN: s_bfe_i32 {{s[0-9]+}}, {{s[0-9]+}}, 0x10000 302; GCN: buffer_store_dwordx2 303 304; EG: MEM_{{.*}} STORE_{{.*}} [[RES:T[0-9]+]]{{\.[XYZW][XYZW]}}, [[ADDR:T[0-9]+.[XYZW]]] 305; EG: BFE_INT [[RES]] 306; EG: BFE_INT [[RES]] 307; EG: LSHR {{\*?}} [[ADDR]] 308define void @sext_in_reg_v2i1_to_v2i32(<2 x i32> addrspace(1)* %out, <2 x i32> %a, <2 x i32> %b) #0 { 309 %c = add <2 x i32> %a, %b ; add to prevent folding into extload 310 %shl = shl <2 x i32> %c, <i32 31, i32 31> 311 %ashr = ashr <2 x i32> %shl, <i32 31, i32 31> 312 store <2 x i32> %ashr, <2 x i32> addrspace(1)* %out, align 8 313 ret void 314} 315 316; FUNC-LABEL: {{^}}sext_in_reg_v4i1_to_v4i32: 317; GCN: s_bfe_i32 {{s[0-9]+}}, {{s[0-9]+}}, 0x10000 318; GCN: s_bfe_i32 {{s[0-9]+}}, {{s[0-9]+}}, 0x10000 319; GCN: s_bfe_i32 {{s[0-9]+}}, {{s[0-9]+}}, 0x10000 320; GCN: s_bfe_i32 {{s[0-9]+}}, {{s[0-9]+}}, 0x10000 321; GCN: buffer_store_dwordx4 322 323; EG: MEM_{{.*}} STORE_{{.*}} [[RES:T[0-9]+]]{{\.[XYZW][XYZW][XYZW][XYZW]}}, [[ADDR:T[0-9]+.[XYZW]]] 324; EG: BFE_INT [[RES]] 325; EG: BFE_INT [[RES]] 326; EG: BFE_INT [[RES]] 327; EG: BFE_INT [[RES]] 328; EG: LSHR {{\*?}} [[ADDR]] 329define void @sext_in_reg_v4i1_to_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> %a, <4 x i32> %b) #0 { 330 %c = add <4 x i32> %a, %b ; add to prevent folding into extload 331 %shl = shl <4 x i32> %c, <i32 31, i32 31, i32 31, i32 31> 332 %ashr = ashr <4 x i32> %shl, <i32 31, i32 31, i32 31, i32 31> 333 store <4 x i32> %ashr, <4 x i32> addrspace(1)* %out, align 8 334 ret void 335} 336 337; FUNC-LABEL: {{^}}sext_in_reg_v2i8_to_v2i32: 338; GCN: s_sext_i32_i8 {{s[0-9]+}}, {{s[0-9]+}} 339; GCN: s_sext_i32_i8 {{s[0-9]+}}, {{s[0-9]+}} 340; GCN: buffer_store_dwordx2 341 342; EG: MEM_{{.*}} STORE_{{.*}} [[RES:T[0-9]+]]{{\.[XYZW][XYZW]}}, [[ADDR:T[0-9]+.[XYZW]]] 343; EG: BFE_INT [[RES]] 344; EG: BFE_INT [[RES]] 345; EG: LSHR {{\*?}} [[ADDR]] 346define void @sext_in_reg_v2i8_to_v2i32(<2 x i32> addrspace(1)* %out, <2 x i32> %a, <2 x i32> %b) #0 { 347 %c = add <2 x i32> %a, %b ; add to prevent folding into extload 348 %shl = shl <2 x i32> %c, <i32 24, i32 24> 349 %ashr = ashr <2 x i32> %shl, <i32 24, i32 24> 350 store <2 x i32> %ashr, <2 x i32> addrspace(1)* %out, align 8 351 ret void 352} 353 354; FUNC-LABEL: {{^}}sext_in_reg_v4i8_to_v4i32: 355; GCN: s_sext_i32_i8 {{s[0-9]+}}, {{s[0-9]+}} 356; GCN: s_sext_i32_i8 {{s[0-9]+}}, {{s[0-9]+}} 357; GCN: s_sext_i32_i8 {{s[0-9]+}}, {{s[0-9]+}} 358; GCN: s_sext_i32_i8 {{s[0-9]+}}, {{s[0-9]+}} 359; GCN: buffer_store_dwordx4 360 361; EG: MEM_{{.*}} STORE_{{.*}} [[RES:T[0-9]+]]{{\.[XYZW][XYZW][XYZW][XYZW]}}, [[ADDR:T[0-9]+.[XYZW]]] 362; EG: BFE_INT [[RES]] 363; EG: BFE_INT [[RES]] 364; EG: BFE_INT [[RES]] 365; EG: BFE_INT [[RES]] 366; EG: LSHR {{\*?}} [[ADDR]] 367define void @sext_in_reg_v4i8_to_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> %a, <4 x i32> %b) #0 { 368 %c = add <4 x i32> %a, %b ; add to prevent folding into extload 369 %shl = shl <4 x i32> %c, <i32 24, i32 24, i32 24, i32 24> 370 %ashr = ashr <4 x i32> %shl, <i32 24, i32 24, i32 24, i32 24> 371 store <4 x i32> %ashr, <4 x i32> addrspace(1)* %out, align 8 372 ret void 373} 374 375; FUNC-LABEL: {{^}}sext_in_reg_v2i16_to_v2i32: 376; GCN: s_sext_i32_i16 {{s[0-9]+}}, {{s[0-9]+}} 377; GCN: s_sext_i32_i16 {{s[0-9]+}}, {{s[0-9]+}} 378; GCN: buffer_store_dwordx2 379 380; EG: MEM_{{.*}} STORE_{{.*}} [[RES:T[0-9]+]]{{\.[XYZW][XYZW]}}, [[ADDR:T[0-9]+.[XYZW]]] 381; EG: BFE_INT [[RES]] 382; EG: BFE_INT [[RES]] 383; EG: LSHR {{\*?}} [[ADDR]] 384define void @sext_in_reg_v2i16_to_v2i32(<2 x i32> addrspace(1)* %out, <2 x i32> %a, <2 x i32> %b) #0 { 385 %c = add <2 x i32> %a, %b ; add to prevent folding into extload 386 %shl = shl <2 x i32> %c, <i32 16, i32 16> 387 %ashr = ashr <2 x i32> %shl, <i32 16, i32 16> 388 store <2 x i32> %ashr, <2 x i32> addrspace(1)* %out, align 8 389 ret void 390} 391 392; FUNC-LABEL: {{^}}testcase: 393define void @testcase(i8 addrspace(1)* %out, i8 %a) #0 { 394 %and_a_1 = and i8 %a, 1 395 %cmp_eq = icmp eq i8 %and_a_1, 0 396 %cmp_slt = icmp slt i8 %a, 0 397 %sel0 = select i1 %cmp_slt, i8 0, i8 %a 398 %sel1 = select i1 %cmp_eq, i8 0, i8 %a 399 %xor = xor i8 %sel0, %sel1 400 store i8 %xor, i8 addrspace(1)* %out 401 ret void 402} 403 404; FUNC-LABEL: {{^}}testcase_3: 405define void @testcase_3(i8 addrspace(1)* %out, i8 %a) #0 { 406 %and_a_1 = and i8 %a, 1 407 %cmp_eq = icmp eq i8 %and_a_1, 0 408 %cmp_slt = icmp slt i8 %a, 0 409 %sel0 = select i1 %cmp_slt, i8 0, i8 %a 410 %sel1 = select i1 %cmp_eq, i8 0, i8 %a 411 %xor = xor i8 %sel0, %sel1 412 store i8 %xor, i8 addrspace(1)* %out 413 ret void 414} 415 416; FUNC-LABEL: {{^}}vgpr_sext_in_reg_v4i8_to_v4i32: 417; GCN: v_bfe_i32 [[EXTRACT:v[0-9]+]], {{v[0-9]+}}, 0, 8 418; GCN: v_bfe_i32 [[EXTRACT:v[0-9]+]], {{v[0-9]+}}, 0, 8 419; GCN: v_bfe_i32 [[EXTRACT:v[0-9]+]], {{v[0-9]+}}, 0, 8 420; GCN: v_bfe_i32 [[EXTRACT:v[0-9]+]], {{v[0-9]+}}, 0, 8 421define void @vgpr_sext_in_reg_v4i8_to_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> addrspace(1)* %a, <4 x i32> addrspace(1)* %b) #0 { 422 %loada = load <4 x i32>, <4 x i32> addrspace(1)* %a, align 16 423 %loadb = load <4 x i32>, <4 x i32> addrspace(1)* %b, align 16 424 %c = add <4 x i32> %loada, %loadb ; add to prevent folding into extload 425 %shl = shl <4 x i32> %c, <i32 24, i32 24, i32 24, i32 24> 426 %ashr = ashr <4 x i32> %shl, <i32 24, i32 24, i32 24, i32 24> 427 store <4 x i32> %ashr, <4 x i32> addrspace(1)* %out, align 8 428 ret void 429} 430 431; FUNC-LABEL: {{^}}vgpr_sext_in_reg_v4i16_to_v4i32: 432; GCN: v_bfe_i32 [[EXTRACT:v[0-9]+]], {{v[0-9]+}}, 0, 16 433; GCN: v_bfe_i32 [[EXTRACT:v[0-9]+]], {{v[0-9]+}}, 0, 16 434define void @vgpr_sext_in_reg_v4i16_to_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> addrspace(1)* %a, <4 x i32> addrspace(1)* %b) #0 { 435 %loada = load <4 x i32>, <4 x i32> addrspace(1)* %a, align 16 436 %loadb = load <4 x i32>, <4 x i32> addrspace(1)* %b, align 16 437 %c = add <4 x i32> %loada, %loadb ; add to prevent folding into extload 438 %shl = shl <4 x i32> %c, <i32 16, i32 16, i32 16, i32 16> 439 %ashr = ashr <4 x i32> %shl, <i32 16, i32 16, i32 16, i32 16> 440 store <4 x i32> %ashr, <4 x i32> addrspace(1)* %out, align 8 441 ret void 442} 443 444; FUNC-LABEL: {{^}}sext_in_reg_to_illegal_type: 445; GCN: buffer_load_sbyte 446; GCN: v_max_i32 447; GCN-NOT: bfe 448; GCN: buffer_store_short 449define void @sext_in_reg_to_illegal_type(i16 addrspace(1)* nocapture %out, i8 addrspace(1)* nocapture %src) #0 { 450 %tmp5 = load i8, i8 addrspace(1)* %src, align 1 451 %tmp2 = sext i8 %tmp5 to i32 452 %tmp2.5 = icmp sgt i32 %tmp2, 0 453 %tmp3 = select i1 %tmp2.5, i32 %tmp2, i32 0 454 %tmp4 = trunc i32 %tmp3 to i8 455 %tmp6 = sext i8 %tmp4 to i16 456 store i16 %tmp6, i16 addrspace(1)* %out, align 2 457 ret void 458} 459 460declare i32 @llvm.AMDGPU.bfe.i32(i32, i32, i32) nounwind readnone 461 462; FUNC-LABEL: {{^}}bfe_0_width: 463; GCN-NOT: {{[^@]}}bfe 464; GCN: s_endpgm 465define void @bfe_0_width(i32 addrspace(1)* %out, i32 addrspace(1)* %ptr) #0 { 466 %load = load i32, i32 addrspace(1)* %ptr, align 4 467 %bfe = call i32 @llvm.AMDGPU.bfe.i32(i32 %load, i32 8, i32 0) nounwind readnone 468 store i32 %bfe, i32 addrspace(1)* %out, align 4 469 ret void 470} 471 472; FUNC-LABEL: {{^}}bfe_8_bfe_8: 473; GCN: v_bfe_i32 474; GCN-NOT: {{[^@]}}bfe 475; GCN: s_endpgm 476define void @bfe_8_bfe_8(i32 addrspace(1)* %out, i32 addrspace(1)* %ptr) #0 { 477 %load = load i32, i32 addrspace(1)* %ptr, align 4 478 %bfe0 = call i32 @llvm.AMDGPU.bfe.i32(i32 %load, i32 0, i32 8) nounwind readnone 479 %bfe1 = call i32 @llvm.AMDGPU.bfe.i32(i32 %bfe0, i32 0, i32 8) nounwind readnone 480 store i32 %bfe1, i32 addrspace(1)* %out, align 4 481 ret void 482} 483 484; FUNC-LABEL: {{^}}bfe_8_bfe_16: 485; GCN: v_bfe_i32 v{{[0-9]+}}, v{{[0-9]+}}, 0, 8 486; GCN: s_endpgm 487define void @bfe_8_bfe_16(i32 addrspace(1)* %out, i32 addrspace(1)* %ptr) #0 { 488 %load = load i32, i32 addrspace(1)* %ptr, align 4 489 %bfe0 = call i32 @llvm.AMDGPU.bfe.i32(i32 %load, i32 0, i32 8) nounwind readnone 490 %bfe1 = call i32 @llvm.AMDGPU.bfe.i32(i32 %bfe0, i32 0, i32 16) nounwind readnone 491 store i32 %bfe1, i32 addrspace(1)* %out, align 4 492 ret void 493} 494 495; This really should be folded into 1 496; FUNC-LABEL: {{^}}bfe_16_bfe_8: 497; GCN: v_bfe_i32 v{{[0-9]+}}, v{{[0-9]+}}, 0, 8 498; GCN-NOT: {{[^@]}}bfe 499; GCN: s_endpgm 500define void @bfe_16_bfe_8(i32 addrspace(1)* %out, i32 addrspace(1)* %ptr) #0 { 501 %load = load i32, i32 addrspace(1)* %ptr, align 4 502 %bfe0 = call i32 @llvm.AMDGPU.bfe.i32(i32 %load, i32 0, i32 16) nounwind readnone 503 %bfe1 = call i32 @llvm.AMDGPU.bfe.i32(i32 %bfe0, i32 0, i32 8) nounwind readnone 504 store i32 %bfe1, i32 addrspace(1)* %out, align 4 505 ret void 506} 507 508; Make sure there isn't a redundant BFE 509; FUNC-LABEL: {{^}}sext_in_reg_i8_to_i32_bfe: 510; GCN: s_sext_i32_i8 s{{[0-9]+}}, s{{[0-9]+}} 511; GCN-NOT: {{[^@]}}bfe 512; GCN: s_endpgm 513define void @sext_in_reg_i8_to_i32_bfe(i32 addrspace(1)* %out, i32 %a, i32 %b) #0 { 514 %c = add i32 %a, %b ; add to prevent folding into extload 515 %bfe = call i32 @llvm.AMDGPU.bfe.i32(i32 %c, i32 0, i32 8) nounwind readnone 516 %shl = shl i32 %bfe, 24 517 %ashr = ashr i32 %shl, 24 518 store i32 %ashr, i32 addrspace(1)* %out, align 4 519 ret void 520} 521 522; FUNC-LABEL: {{^}}sext_in_reg_i8_to_i32_bfe_wrong: 523define void @sext_in_reg_i8_to_i32_bfe_wrong(i32 addrspace(1)* %out, i32 %a, i32 %b) #0 { 524 %c = add i32 %a, %b ; add to prevent folding into extload 525 %bfe = call i32 @llvm.AMDGPU.bfe.i32(i32 %c, i32 8, i32 0) nounwind readnone 526 %shl = shl i32 %bfe, 24 527 %ashr = ashr i32 %shl, 24 528 store i32 %ashr, i32 addrspace(1)* %out, align 4 529 ret void 530} 531 532; FUNC-LABEL: {{^}}sextload_i8_to_i32_bfe: 533; GCN: buffer_load_sbyte 534; GCN-NOT: {{[^@]}}bfe 535; GCN: s_endpgm 536define void @sextload_i8_to_i32_bfe(i32 addrspace(1)* %out, i8 addrspace(1)* %ptr) #0 { 537 %load = load i8, i8 addrspace(1)* %ptr, align 1 538 %sext = sext i8 %load to i32 539 %bfe = call i32 @llvm.AMDGPU.bfe.i32(i32 %sext, i32 0, i32 8) nounwind readnone 540 %shl = shl i32 %bfe, 24 541 %ashr = ashr i32 %shl, 24 542 store i32 %ashr, i32 addrspace(1)* %out, align 4 543 ret void 544} 545 546; GCN: .text 547; FUNC-LABEL: {{^}}sextload_i8_to_i32_bfe_0:{{.*$}} 548; GCN-NOT: {{[^@]}}bfe 549; GCN: s_endpgm 550define void @sextload_i8_to_i32_bfe_0(i32 addrspace(1)* %out, i8 addrspace(1)* %ptr) #0 { 551 %load = load i8, i8 addrspace(1)* %ptr, align 1 552 %sext = sext i8 %load to i32 553 %bfe = call i32 @llvm.AMDGPU.bfe.i32(i32 %sext, i32 8, i32 0) nounwind readnone 554 %shl = shl i32 %bfe, 24 555 %ashr = ashr i32 %shl, 24 556 store i32 %ashr, i32 addrspace(1)* %out, align 4 557 ret void 558} 559 560; FUNC-LABEL: {{^}}sext_in_reg_i1_bfe_offset_0: 561; GCN-NOT: shr 562; GCN-NOT: shl 563; GCN: v_bfe_i32 v{{[0-9]+}}, v{{[0-9]+}}, 0, 1 564; GCN: s_endpgm 565define void @sext_in_reg_i1_bfe_offset_0(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 { 566 %x = load i32, i32 addrspace(1)* %in, align 4 567 %shl = shl i32 %x, 31 568 %shr = ashr i32 %shl, 31 569 %bfe = call i32 @llvm.AMDGPU.bfe.i32(i32 %shr, i32 0, i32 1) 570 store i32 %bfe, i32 addrspace(1)* %out, align 4 571 ret void 572} 573 574; FUNC-LABEL: {{^}}sext_in_reg_i1_bfe_offset_1: 575; GCN: buffer_load_dword 576; GCN-NOT: shl 577; GCN-NOT: shr 578; GCN: v_bfe_i32 v{{[0-9]+}}, v{{[0-9]+}}, 1, 1 579; GCN: s_endpgm 580define void @sext_in_reg_i1_bfe_offset_1(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 { 581 %x = load i32, i32 addrspace(1)* %in, align 4 582 %shl = shl i32 %x, 30 583 %shr = ashr i32 %shl, 30 584 %bfe = call i32 @llvm.AMDGPU.bfe.i32(i32 %shr, i32 1, i32 1) 585 store i32 %bfe, i32 addrspace(1)* %out, align 4 586 ret void 587} 588 589; FUNC-LABEL: {{^}}sext_in_reg_i2_bfe_offset_1: 590; GCN: buffer_load_dword 591; GCN-NOT: v_lshl 592; GCN-NOT: v_ashr 593; GCN: v_bfe_i32 v{{[0-9]+}}, v{{[0-9]+}}, 0, 2 594; GCN: v_bfe_i32 v{{[0-9]+}}, v{{[0-9]+}}, 1, 2 595; GCN: s_endpgm 596define void @sext_in_reg_i2_bfe_offset_1(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 { 597 %x = load i32, i32 addrspace(1)* %in, align 4 598 %shl = shl i32 %x, 30 599 %shr = ashr i32 %shl, 30 600 %bfe = call i32 @llvm.AMDGPU.bfe.i32(i32 %shr, i32 1, i32 2) 601 store i32 %bfe, i32 addrspace(1)* %out, align 4 602 ret void 603} 604 605; Make sure we propagate the VALUness to users of a moved scalar BFE. 606 607; FUNC-LABEL: {{^}}v_sext_in_reg_i1_to_i64_move_use: 608; SI: buffer_load_dwordx2 609; SI: v_lshl_b64 v{{\[}}[[VAL_LO:[0-9]+]]:[[VAL_HI:[0-9]+]]{{\]}} 610 611; GFX89: flat_load_dwordx2 612; GFX89: v_lshlrev_b64 v{{\[}}[[VAL_LO:[0-9]+]]:[[VAL_HI:[0-9]+]]{{\]}} 613 614; GCN-DAG: v_bfe_i32 v[[LO:[0-9]+]], v[[VAL_LO]], 0, 1 615; GCN-DAG: v_ashrrev_i32_e32 v[[HI:[0-9]+]], 31, v[[LO]] 616; GCN-DAG: v_and_b32_e32 v[[RESULT_LO:[0-9]+]], s{{[0-9]+}}, v[[LO]] 617; GCN-DAG: v_and_b32_e32 v[[RESULT_HI:[0-9]+]], s{{[0-9]+}}, v[[HI]] 618; SI: buffer_store_dwordx2 v{{\[}}[[RESULT_LO]]:[[RESULT_HI]]{{\]}} 619; GFX89: flat_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, v{{\[}}[[RESULT_LO]]:[[RESULT_HI]]{{\]}} 620define void @v_sext_in_reg_i1_to_i64_move_use(i64 addrspace(1)* %out, i64 addrspace(1)* %aptr, i64 addrspace(1)* %bptr, i64 %s.val) #0 { 621 %tid = call i32 @llvm.r600.read.tidig.x() 622 %a.gep = getelementptr i64, i64 addrspace(1)* %aptr, i32 %tid 623 %b.gep = getelementptr i64, i64 addrspace(1)* %aptr, i32 %tid 624 %out.gep = getelementptr i64, i64 addrspace(1)* %out, i32 %tid 625 %a = load i64, i64 addrspace(1)* %a.gep, align 8 626 %b = load i64, i64 addrspace(1)* %b.gep, align 8 627 628 %c = shl i64 %a, %b 629 %shl = shl i64 %c, 63 630 %ashr = ashr i64 %shl, 63 631 632 %and = and i64 %ashr, %s.val 633 store i64 %and, i64 addrspace(1)* %out.gep, align 8 634 ret void 635} 636 637; FUNC-LABEL: {{^}}v_sext_in_reg_i32_to_i64_move_use: 638; SI: buffer_load_dwordx2 639; SI: v_lshl_b64 v{{\[}}[[LO:[0-9]+]]:[[HI:[0-9]+]]{{\]}}, 640 641; GFX89: flat_load_dwordx2 642; GFX89: v_lshlrev_b64 v{{\[}}[[LO:[0-9]+]]:[[HI:[0-9]+]]{{\]}}, 643 644; GCN-DAG: v_ashrrev_i32_e32 v[[SHR:[0-9]+]], 31, v[[LO]] 645; GCN-DAG: v_and_b32_e32 v[[RESULT_LO:[0-9]+]], s{{[0-9]+}}, v[[LO]] 646; GCN-DAG: v_and_b32_e32 v[[RESULT_HI:[0-9]+]], s{{[0-9]+}}, v[[SHR]] 647 648; SI: buffer_store_dwordx2 v{{\[}}[[RESULT_LO]]:[[RESULT_HI]]{{\]}} 649; GFX89: flat_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, v{{\[}}[[RESULT_LO]]:[[RESULT_HI]]{{\]}} 650define void @v_sext_in_reg_i32_to_i64_move_use(i64 addrspace(1)* %out, i64 addrspace(1)* %aptr, i64 addrspace(1)* %bptr, i64 %s.val) #0 { 651 %tid = call i32 @llvm.r600.read.tidig.x() 652 %a.gep = getelementptr i64, i64 addrspace(1)* %aptr, i32 %tid 653 %b.gep = getelementptr i64, i64 addrspace(1)* %aptr, i32 %tid 654 %out.gep = getelementptr i64, i64 addrspace(1)* %out, i32 %tid 655 %a = load i64, i64 addrspace(1)* %a.gep, align 8 656 %b = load i64, i64 addrspace(1)* %b.gep, align 8 657 658 %c = shl i64 %a, %b 659 %shl = shl i64 %c, 32 660 %ashr = ashr i64 %shl, 32 661 %and = and i64 %ashr, %s.val 662 store i64 %and, i64 addrspace(1)* %out.gep, align 8 663 ret void 664} 665 666; FUNC-LABEL: {{^}}s_sext_in_reg_i1_i16: 667; GCN: s_load_dword [[VAL:s[0-9]+]] 668 669; SI: s_bfe_i32 [[BFE:s[0-9]+]], [[VAL]], 0x10000 670; SI: v_mov_b32_e32 [[VBFE:v[0-9]+]], [[BFE]] 671; SI: buffer_store_short [[VBFE]] 672 673; GFX89: s_lshl_b32 s{{[0-9]+}}, s{{[0-9]+}}, 15 674; GFX89: s_sext_i32_i16 s{{[0-9]+}}, s{{[0-9]+}} 675; GFX89: s_lshr_b32 s{{[0-9]+}}, s{{[0-9]+}}, 15 676define void @s_sext_in_reg_i1_i16(i16 addrspace(1)* %out, i32 addrspace(2)* %ptr) #0 { 677 %ld = load i32, i32 addrspace(2)* %ptr 678 %in = trunc i32 %ld to i16 679 %shl = shl i16 %in, 15 680 %sext = ashr i16 %shl, 15 681 store i16 %sext, i16 addrspace(1)* %out 682 ret void 683} 684 685; FUNC-LABEL: {{^}}s_sext_in_reg_i2_i16: 686; GCN: s_load_dword [[VAL:s[0-9]+]] 687 688; SI: s_bfe_i32 [[BFE:s[0-9]+]], [[VAL]], 0x20000 689; SI: v_mov_b32_e32 [[VBFE:v[0-9]+]], [[BFE]] 690; SI: buffer_store_short [[VBFE]] 691 692; GFX89: s_lshl_b32 s{{[0-9]+}}, s{{[0-9]+}}, 14 693; GFX89: s_sext_i32_i16 s{{[0-9]+}}, s{{[0-9]+}} 694; GFX89: s_lshr_b32 s{{[0-9]+}}, s{{[0-9]+}}, 14 695define void @s_sext_in_reg_i2_i16(i16 addrspace(1)* %out, i32 addrspace(2)* %ptr) #0 { 696 %ld = load i32, i32 addrspace(2)* %ptr 697 %in = trunc i32 %ld to i16 698 %shl = shl i16 %in, 14 699 %sext = ashr i16 %shl, 14 700 store i16 %sext, i16 addrspace(1)* %out 701 ret void 702} 703 704; FUNC-LABEL: {{^}}v_sext_in_reg_i1_i16: 705; GCN: {{buffer|flat}}_load_ushort [[VAL:v[0-9]+]] 706; GCN: v_bfe_i32 [[BFE:v[0-9]+]], [[VAL]], 0, 1{{$}} 707 708; GCN: ds_write_b16 v{{[0-9]+}}, [[BFE]] 709define void @v_sext_in_reg_i1_i16(i16 addrspace(3)* %out, i16 addrspace(1)* %ptr) #0 { 710 %tid = call i32 @llvm.r600.read.tidig.x() 711 %gep = getelementptr i16, i16 addrspace(1)* %ptr, i32 %tid 712 %out.gep = getelementptr i16, i16 addrspace(3)* %out, i32 %tid 713 714 %in = load i16, i16 addrspace(1)* %gep 715 %shl = shl i16 %in, 15 716 %sext = ashr i16 %shl, 15 717 store i16 %sext, i16 addrspace(3)* %out.gep 718 ret void 719} 720 721; FUNC-LABEL: {{^}}v_sext_in_reg_i1_i16_nonload: 722; GCN: {{buffer|flat}}_load_ushort [[VAL0:v[0-9]+]] 723; GCN: {{buffer|flat}}_load_ushort [[VAL1:v[0-9]+]] 724 725; SI: v_lshlrev_b32_e32 [[REG:v[0-9]+]], [[VAL1]], [[VAL0]] 726; GFX89: v_lshlrev_b16_e32 [[REG:v[0-9]+]], [[VAL1]], [[VAL0]] 727 728; GCN: v_bfe_i32 [[BFE:v[0-9]+]], [[REG]], 0, 1{{$}} 729; GCN: ds_write_b16 v{{[0-9]+}}, [[BFE]] 730define void @v_sext_in_reg_i1_i16_nonload(i16 addrspace(3)* %out, i16 addrspace(1)* %aptr, i16 addrspace(1)* %bptr, i16 %s.val) nounwind { 731 %tid = call i32 @llvm.r600.read.tidig.x() 732 %a.gep = getelementptr i16, i16 addrspace(1)* %aptr, i32 %tid 733 %b.gep = getelementptr i16, i16 addrspace(1)* %bptr, i32 %tid 734 %out.gep = getelementptr i16, i16 addrspace(3)* %out, i32 %tid 735 %a = load volatile i16, i16 addrspace(1)* %a.gep, align 2 736 %b = load volatile i16, i16 addrspace(1)* %b.gep, align 2 737 738 %c = shl i16 %a, %b 739 %shl = shl i16 %c, 15 740 %ashr = ashr i16 %shl, 15 741 742 store i16 %ashr, i16 addrspace(3)* %out.gep, align 2 743 ret void 744} 745 746; FUNC-LABEL: {{^}}s_sext_in_reg_i2_i16_arg: 747; GCN: s_load_dword [[VAL:s[0-9]+]] 748 749; SI: s_bfe_i32 [[BFE:s[0-9]+]], [[VAL]], 0x20000 750; SI: v_mov_b32_e32 [[VBFE:v[0-9]+]], [[BFE]] 751; SI: buffer_store_short [[VBFE]] 752 753; GFX89: s_lshl_b32 s{{[0-9]+}}, s{{[0-9]+}}, 14{{$}} 754; GFX89: s_sext_i32_i16 s{{[0-9]+}}, s{{[0-9]+}} 755; GFX89: s_lshr_b32 s{{[0-9]+}}, s{{[0-9]+}}, 14{{$}} 756define void @s_sext_in_reg_i2_i16_arg(i16 addrspace(1)* %out, i16 %in) #0 { 757 %shl = shl i16 %in, 14 758 %sext = ashr i16 %shl, 14 759 store i16 %sext, i16 addrspace(1)* %out 760 ret void 761} 762 763; FUNC-LABEL: {{^}}s_sext_in_reg_i8_i16_arg: 764; GCN: s_load_dword [[VAL:s[0-9]+]] 765 766; SI: s_sext_i32_i8 [[SSEXT:s[0-9]+]], [[VAL]] 767; SI: v_mov_b32_e32 [[VSEXT:v[0-9]+]], [[SSEXT]] 768; SI: buffer_store_short [[VBFE]] 769 770; GFX89: s_lshl_b32 s{{[0-9]+}}, s{{[0-9]+}}, 8{{$}} 771; GFX89: s_sext_i32_i16 s{{[0-9]+}}, s{{[0-9]+}} 772; GFX89: s_lshr_b32 s{{[0-9]+}}, s{{[0-9]+}}, 8{{$}} 773define void @s_sext_in_reg_i8_i16_arg(i16 addrspace(1)* %out, i16 %in) #0 { 774 %shl = shl i16 %in, 8 775 %sext = ashr i16 %shl, 8 776 store i16 %sext, i16 addrspace(1)* %out 777 ret void 778} 779 780; FUNC-LABEL: {{^}}s_sext_in_reg_i15_i16_arg: 781; GCN: s_load_dword [[VAL:s[0-9]+]] 782 783; SI: s_bfe_i32 [[BFE:s[0-9]+]], [[VAL]], 0xf0000 784; SI: v_mov_b32_e32 [[VBFE:v[0-9]+]], [[BFE]] 785; SI: buffer_store_short [[VBFE]] 786 787; GFX89: s_lshl_b32 s{{[0-9]+}}, s{{[0-9]+}}, 1{{$}} 788; GFX89: s_sext_i32_i16 s{{[0-9]+}}, s{{[0-9]+}} 789; GFX89: s_lshr_b32 s{{[0-9]+}}, s{{[0-9]+}}, 1{{$}} 790define void @s_sext_in_reg_i15_i16_arg(i16 addrspace(1)* %out, i16 %in) #0 { 791 %shl = shl i16 %in, 1 792 %sext = ashr i16 %shl, 1 793 store i16 %sext, i16 addrspace(1)* %out 794 ret void 795} 796 797; FUNC-LABEL: {{^}}sext_in_reg_v2i1_to_v2i16: 798; GFX9: v_pk_add_u16 [[ADD:v[0-9]+]] 799; GFX9: v_pk_lshlrev_b16 [[SHL:v[0-9]+]], 15, [[ADD]] 800; GFX9: v_pk_ashrrev_i16 [[SRA:v[0-9]+]], 15, [[SHL]] 801define void @sext_in_reg_v2i1_to_v2i16(<2 x i16> addrspace(1)* %out, <2 x i16> %a, <2 x i16> %b) #0 { 802 %c = add <2 x i16> %a, %b ; add to prevent folding into extload 803 %shl = shl <2 x i16> %c, <i16 15, i16 15> 804 %ashr = ashr <2 x i16> %shl, <i16 15, i16 15> 805 store <2 x i16> %ashr, <2 x i16> addrspace(1)* %out 806 ret void 807} 808 809; FUNC-LABEL: {{^}}sext_in_reg_v3i1_to_v3i16: 810; GFX9: v_pk_add_u16 811; GFX9: v_pk_add_u16 812; GFX9: v_pk_lshlrev_b16 v{{[0-9]+}}, 15, v{{[0-9]+}} 813; GFX9: v_pk_lshlrev_b16 v{{[0-9]+}}, 15, v{{[0-9]+}} 814; GFX9: v_pk_ashrrev_i16 v{{[0-9]+}}, 15, v{{[0-9]+}} 815; GFX9: v_pk_ashrrev_i16 v{{[0-9]+}}, 15, v{{[0-9]+}} 816define void @sext_in_reg_v3i1_to_v3i16(<3 x i16> addrspace(1)* %out, <3 x i16> %a, <3 x i16> %b) #0 { 817 %c = add <3 x i16> %a, %b ; add to prevent folding into extload 818 %shl = shl <3 x i16> %c, <i16 15, i16 15, i16 15> 819 %ashr = ashr <3 x i16> %shl, <i16 15, i16 15, i16 15> 820 store <3 x i16> %ashr, <3 x i16> addrspace(1)* %out 821 ret void 822} 823 824; FUNC-LABEL: {{^}}sext_in_reg_v2i2_to_v2i16: 825; GFX9: v_pk_add_u16 [[ADD:v[0-9]+]] 826; GFX9: v_pk_lshlrev_b16 [[SHL:v[0-9]+]], 14, [[ADD]] 827; GFX9: v_pk_ashrrev_i16 [[SRA:v[0-9]+]], 14, [[SHL]] 828define void @sext_in_reg_v2i2_to_v2i16(<2 x i16> addrspace(1)* %out, <2 x i16> %a, <2 x i16> %b) #0 { 829 %c = add <2 x i16> %a, %b ; add to prevent folding into extload 830 %shl = shl <2 x i16> %c, <i16 14, i16 14> 831 %ashr = ashr <2 x i16> %shl, <i16 14, i16 14> 832 store <2 x i16> %ashr, <2 x i16> addrspace(1)* %out 833 ret void 834} 835 836; FUNC-LABEL: {{^}}sext_in_reg_v2i8_to_v2i16: 837; GFX9: v_pk_add_u16 [[ADD:v[0-9]+]] 838; GFX9: v_pk_lshlrev_b16 [[SHL:v[0-9]+]], 8, [[ADD]] 839; GFX9: v_pk_ashrrev_i16 [[SRA:v[0-9]+]], 8, [[SHL]] 840define void @sext_in_reg_v2i8_to_v2i16(<2 x i16> addrspace(1)* %out, <2 x i16> %a, <2 x i16> %b) #0 { 841 %c = add <2 x i16> %a, %b ; add to prevent folding into extload 842 %shl = shl <2 x i16> %c, <i16 8, i16 8> 843 %ashr = ashr <2 x i16> %shl, <i16 8, i16 8> 844 store <2 x i16> %ashr, <2 x i16> addrspace(1)* %out 845 ret void 846} 847 848; FUNC-LABEL: {{^}}sext_in_reg_v3i8_to_v3i16: 849; GFX9: v_pk_add_u16 850; GFX9: v_pk_add_u16 851; GFX9: v_pk_lshlrev_b16 v{{[0-9]+}}, 8, v{{[0-9]+}} 852; GFX9: v_pk_lshlrev_b16 v{{[0-9]+}}, 8, v{{[0-9]+}} 853; GFX9: v_pk_ashrrev_i16 v{{[0-9]+}}, 8, v{{[0-9]+}} 854; GFX9: v_pk_ashrrev_i16 v{{[0-9]+}}, 8, v{{[0-9]+}} 855define void @sext_in_reg_v3i8_to_v3i16(<3 x i16> addrspace(1)* %out, <3 x i16> %a, <3 x i16> %b) #0 { 856 %c = add <3 x i16> %a, %b ; add to prevent folding into extload 857 %shl = shl <3 x i16> %c, <i16 8, i16 8, i16 8> 858 %ashr = ashr <3 x i16> %shl, <i16 8, i16 8, i16 8> 859 store <3 x i16> %ashr, <3 x i16> addrspace(1)* %out 860 ret void 861} 862 863declare i32 @llvm.r600.read.tidig.x() #1 864 865attributes #0 = { nounwind } 866attributes #1 = { nounwind readnone } 867