1; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=GCN-NOHSA -check-prefix=FUNC %s 2; RUN: llc -mtriple=amdgcn--amdhsa -mcpu=kaveri -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=GCN-HSA -check-prefix=FUNC %s 3; RUN: llc -march=amdgcn -mcpu=tonga -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=GCN-NOHSA -check-prefix=FUNC %s 4; RUN: llc -march=r600 -mcpu=redwood < %s | FileCheck -check-prefix=EG -check-prefix=FUNC %s 5 6; FUNC-LABEL: {{^}}local_unaligned_load_store_i16: 7; GCN: ds_read_u8 8; GCN: ds_read_u8 9; GCN: ds_write_b8 10; GCN: ds_write_b8 11; GCN: s_endpgm 12define void @local_unaligned_load_store_i16(i16 addrspace(3)* %p, i16 addrspace(3)* %r) #0 { 13 %v = load i16, i16 addrspace(3)* %p, align 1 14 store i16 %v, i16 addrspace(3)* %r, align 1 15 ret void 16} 17 18; FUNC-LABEL: {{^}}unaligned_load_store_i16_global: 19; GCN-NOHSA: buffer_load_ubyte 20; GCN-NOHSA: buffer_load_ubyte 21; GCN-NOHSA: buffer_store_byte 22; GCN-NOHSA: buffer_store_byte 23 24; GCN-HSA: flat_load_ubyte 25; GCN-HSA: flat_load_ubyte 26; GCN-HSA: flat_store_byte 27; GCN-HSA: flat_store_byte 28define void @unaligned_load_store_i16_global(i16 addrspace(1)* %p, i16 addrspace(1)* %r) #0 { 29 %v = load i16, i16 addrspace(1)* %p, align 1 30 store i16 %v, i16 addrspace(1)* %r, align 1 31 ret void 32} 33 34; FUNC-LABEL: {{^}}local_unaligned_load_store_i32: 35; GCN: ds_read_u8 36; GCN: ds_read_u8 37; GCN: ds_read_u8 38; GCN: ds_read_u8 39; GCN: ds_write_b8 40; GCN: ds_write_b8 41; GCN: ds_write_b8 42; GCN: ds_write_b8 43; GCN: s_endpgm 44define void @local_unaligned_load_store_i32(i32 addrspace(3)* %p, i32 addrspace(3)* %r) #0 { 45 %v = load i32, i32 addrspace(3)* %p, align 1 46 store i32 %v, i32 addrspace(3)* %r, align 1 47 ret void 48} 49 50; FUNC-LABEL: {{^}}global_unaligned_load_store_i32: 51; GCN-NOHSA: buffer_load_ubyte 52; GCN-NOHSA: buffer_load_ubyte 53; GCN-NOHSA: buffer_load_ubyte 54; GCN-NOHSA: buffer_load_ubyte 55; GCN-NOHSA: buffer_store_byte 56; GCN-NOHSA: buffer_store_byte 57; GCN-NOHSA: buffer_store_byte 58; GCN-NOHSA: buffer_store_byte 59 60; GCN-HSA: flat_load_ubyte 61; GCN-HSA: flat_load_ubyte 62; GCN-HSA: flat_load_ubyte 63; GCN-HSA: flat_load_ubyte 64; GCN-HSA: flat_store_byte 65; GCN-HSA: flat_store_byte 66; GCN-HSA: flat_store_byte 67; GCN-HSA: flat_store_byte 68define void @global_unaligned_load_store_i32(i32 addrspace(1)* %p, i32 addrspace(1)* %r) #0 { 69 %v = load i32, i32 addrspace(1)* %p, align 1 70 store i32 %v, i32 addrspace(1)* %r, align 1 71 ret void 72} 73 74; FUNC-LABEL: {{^}}global_align2_load_store_i32: 75; GCN-NOHSA: buffer_load_ushort 76; GCN-NOHSA: buffer_load_ushort 77; GCN-NOHSA: buffer_store_short 78; GCN-NOHSA: buffer_store_short 79 80; GCN-HSA: flat_load_ushort 81; GCN-HSA: flat_load_ushort 82; GCN-HSA: flat_store_short 83; GCN-HSA: flat_store_short 84define void @global_align2_load_store_i32(i32 addrspace(1)* %p, i32 addrspace(1)* %r) #0 { 85 %v = load i32, i32 addrspace(1)* %p, align 2 86 store i32 %v, i32 addrspace(1)* %r, align 2 87 ret void 88} 89 90; FUNC-LABEL: {{^}}local_align2_load_store_i32: 91; GCN: ds_read_u16 92; GCN: ds_read_u16 93; GCN: ds_write_b16 94; GCN: ds_write_b16 95define void @local_align2_load_store_i32(i32 addrspace(3)* %p, i32 addrspace(3)* %r) #0 { 96 %v = load i32, i32 addrspace(3)* %p, align 2 97 store i32 %v, i32 addrspace(3)* %r, align 2 98 ret void 99} 100 101; FIXME: Unnecessary packing and unpacking of bytes. 102; FUNC-LABEL: {{^}}local_unaligned_load_store_i64: 103; GCN: ds_read_u8 104; GCN: ds_read_u8 105; GCN: ds_read_u8 106; GCN: ds_read_u8 107; GCN: ds_read_u8 108; GCN: ds_read_u8 109; GCN: ds_read_u8 110; GCN: ds_read_u8 111 112; XGCN-NOT: v_or_b32 113; XGCN-NOT: v_lshl 114; GCN: ds_write_b8 115; XGCN-NOT: v_or_b32 116; XGCN-NOT: v_lshl 117 118; GCN: ds_write_b8 119; XGCN-NOT: v_or_b32 120; XGCN-NOT: v_lshl 121 122; GCN: ds_write_b8 123; XGCN-NOT: v_or_b32 124; XGCN-NOT: v_lshl 125 126; GCN: ds_write_b8 127; XGCN-NOT: v_or_b32 128; XGCN-NOT: v_lshl 129 130; GCN: ds_write_b8 131; XGCN-NOT: v_or_b32 132; XGCN-NOT: v_lshl 133 134; GCN: ds_write_b8 135; XGCN-NOT: v_or_b32 136; XGCN-NOT: v_lshl 137 138; GCN: ds_write_b8 139; XGCN-NOT: v_or_b32 140; XGCN-NOT: v_lshl 141; GCN: ds_write_b8 142; GCN: s_endpgm 143define void @local_unaligned_load_store_i64(i64 addrspace(3)* %p, i64 addrspace(3)* %r) { 144 %v = load i64, i64 addrspace(3)* %p, align 1 145 store i64 %v, i64 addrspace(3)* %r, align 1 146 ret void 147} 148 149; FUNC-LABEL: {{^}}local_unaligned_load_store_v2i32: 150; GCN: ds_read_u8 151; GCN: ds_read_u8 152; GCN: ds_read_u8 153; GCN: ds_read_u8 154; GCN: ds_read_u8 155; GCN: ds_read_u8 156; GCN: ds_read_u8 157; GCN: ds_read_u8 158 159; XGCN-NOT: v_or_b32 160; XGCN-NOT: v_lshl 161; GCN: ds_write_b8 162; XGCN-NOT: v_or_b32 163; XGCN-NOT: v_lshl 164 165; GCN: ds_write_b8 166; XGCN-NOT: v_or_b32 167; XGCN-NOT: v_lshl 168 169; GCN: ds_write_b8 170; XGCN-NOT: v_or_b32 171; XGCN-NOT: v_lshl 172 173; GCN: ds_write_b8 174; XGCN-NOT: v_or_b32 175; XGCN-NOT: v_lshl 176 177; GCN: ds_write_b8 178; XGCN-NOT: v_or_b32 179; XGCN-NOT: v_lshl 180 181; GCN: ds_write_b8 182; XGCN-NOT: v_or_b32 183; XGCN-NOT: v_lshl 184 185; GCN: ds_write_b8 186; XGCN-NOT: v_or_b32 187; XGCN-NOT: v_lshl 188; GCN: ds_write_b8 189; GCN: s_endpgm 190define void @local_unaligned_load_store_v2i32(<2 x i32> addrspace(3)* %p, <2 x i32> addrspace(3)* %r) { 191 %v = load <2 x i32>, <2 x i32> addrspace(3)* %p, align 1 192 store <2 x i32> %v, <2 x i32> addrspace(3)* %r, align 1 193 ret void 194} 195 196; FUNC-LABEL: {{^}}unaligned_load_store_i64_global: 197; GCN-NOHSA: buffer_load_ubyte 198; GCN-NOHSA: buffer_load_ubyte 199; GCN-NOHSA: buffer_load_ubyte 200; GCN-NOHSA: buffer_load_ubyte 201; GCN-NOHSA: buffer_load_ubyte 202; GCN-NOHSA: buffer_load_ubyte 203; GCN-NOHSA: buffer_load_ubyte 204; GCN-NOHSA: buffer_load_ubyte 205 206; GCN-HSA: flat_load_ubyte 207; GCN-HSA: flat_load_ubyte 208; GCN-HSA: flat_load_ubyte 209; GCN-HSA: flat_load_ubyte 210; GCN-HSA: flat_load_ubyte 211; GCN-HSA: flat_load_ubyte 212; GCN-HSA: flat_load_ubyte 213; GCN-HSA: flat_load_ubyte 214 215; XGCN-NOT: v_or_ 216; XGCN-NOT: v_lshl 217 218; GCN-NOHSA: buffer_store_byte 219; GCN-NOHSA: buffer_store_byte 220; GCN-NOHSA: buffer_store_byte 221; GCN-NOHSA: buffer_store_byte 222; GCN-NOHSA: buffer_store_byte 223; GCN-NOHSA: buffer_store_byte 224; GCN-NOHSA: buffer_store_byte 225; GCN-NOHSA: buffer_store_byte 226 227; GCN-HSA: flat_store_byte 228; GCN-HSA: flat_store_byte 229; GCN-HSA: flat_store_byte 230; GCN-HSA: flat_store_byte 231; GCN-HSA: flat_store_byte 232; GCN-HSA: flat_store_byte 233; GCN-HSA: flat_store_byte 234; GCN-HSA: flat_store_byte 235define void @unaligned_load_store_i64_global(i64 addrspace(1)* %p, i64 addrspace(1)* %r) #0 { 236 %v = load i64, i64 addrspace(1)* %p, align 1 237 store i64 %v, i64 addrspace(1)* %r, align 1 238 ret void 239} 240 241; FUNC-LABEL: {{^}}local_unaligned_load_store_v4i32: 242; GCN: ds_read_u8 243; GCN: ds_read_u8 244; GCN: ds_read_u8 245; GCN: ds_read_u8 246 247; GCN: ds_read_u8 248; GCN: ds_read_u8 249; GCN: ds_read_u8 250; GCN: ds_read_u8 251 252; GCN: ds_read_u8 253; GCN: ds_read_u8 254; GCN: ds_read_u8 255; GCN: ds_read_u8 256 257; GCN: ds_read_u8 258; GCN: ds_read_u8 259; GCN: ds_read_u8 260; GCN: ds_read_u8 261 262; GCN: ds_write_b8 263; GCN: ds_write_b8 264; GCN: ds_write_b8 265; GCN: ds_write_b8 266 267; GCN: ds_write_b8 268; GCN: ds_write_b8 269; GCN: ds_write_b8 270; GCN: ds_write_b8 271 272; GCN: ds_write_b8 273; GCN: ds_write_b8 274; GCN: ds_write_b8 275; GCN: ds_write_b8 276 277; GCN: ds_write_b8 278; GCN: ds_write_b8 279; GCN: ds_write_b8 280; GCN: ds_write_b8 281; GCN: s_endpgm 282define void @local_unaligned_load_store_v4i32(<4 x i32> addrspace(3)* %p, <4 x i32> addrspace(3)* %r) #0 { 283 %v = load <4 x i32>, <4 x i32> addrspace(3)* %p, align 1 284 store <4 x i32> %v, <4 x i32> addrspace(3)* %r, align 1 285 ret void 286} 287 288; FUNC-LABEL: {{^}}global_unaligned_load_store_v4i32: 289; GCN-NOHSA: buffer_load_ubyte 290; GCN-NOHSA: buffer_load_ubyte 291; GCN-NOHSA: buffer_load_ubyte 292; GCN-NOHSA: buffer_load_ubyte 293; GCN-NOHSA: buffer_load_ubyte 294; GCN-NOHSA: buffer_load_ubyte 295; GCN-NOHSA: buffer_load_ubyte 296; GCN-NOHSA: buffer_load_ubyte 297; GCN-NOHSA: buffer_load_ubyte 298; GCN-NOHSA: buffer_load_ubyte 299; GCN-NOHSA: buffer_load_ubyte 300; GCN-NOHSA: buffer_load_ubyte 301; GCN-NOHSA: buffer_load_ubyte 302; GCN-NOHSA: buffer_load_ubyte 303; GCN-NOHSA: buffer_load_ubyte 304; GCN-NOHSA: buffer_load_ubyte 305 306; GCN-NOHSA: buffer_store_byte 307; GCN-NOHSA: buffer_store_byte 308; GCN-NOHSA: buffer_store_byte 309; GCN-NOHSA: buffer_store_byte 310; GCN-NOHSA: buffer_store_byte 311; GCN-NOHSA: buffer_store_byte 312; GCN-NOHSA: buffer_store_byte 313; GCN-NOHSA: buffer_store_byte 314; GCN-NOHSA: buffer_store_byte 315; GCN-NOHSA: buffer_store_byte 316; GCN-NOHSA: buffer_store_byte 317; GCN-NOHSA: buffer_store_byte 318; GCN-NOHSA: buffer_store_byte 319; GCN-NOHSA: buffer_store_byte 320; GCN-NOHSA: buffer_store_byte 321; GCN-NOHSA: buffer_store_byte 322 323 324; GCN-HSA: flat_load_ubyte 325; GCN-HSA: flat_load_ubyte 326; GCN-HSA: flat_load_ubyte 327; GCN-HSA: flat_load_ubyte 328; GCN-HSA: flat_load_ubyte 329; GCN-HSA: flat_load_ubyte 330; GCN-HSA: flat_load_ubyte 331; GCN-HSA: flat_load_ubyte 332; GCN-HSA: flat_load_ubyte 333; GCN-HSA: flat_load_ubyte 334; GCN-HSA: flat_load_ubyte 335; GCN-HSA: flat_load_ubyte 336; GCN-HSA: flat_load_ubyte 337; GCN-HSA: flat_load_ubyte 338; GCN-HSA: flat_load_ubyte 339; GCN-HSA: flat_load_ubyte 340 341; GCN-HSA: flat_store_byte 342; GCN-HSA: flat_store_byte 343; GCN-HSA: flat_store_byte 344; GCN-HSA: flat_store_byte 345; GCN-HSA: flat_store_byte 346; GCN-HSA: flat_store_byte 347; GCN-HSA: flat_store_byte 348; GCN-HSA: flat_store_byte 349; GCN-HSA: flat_store_byte 350; GCN-HSA: flat_store_byte 351; GCN-HSA: flat_store_byte 352; GCN-HSA: flat_store_byte 353; GCN-HSA: flat_store_byte 354; GCN-HSA: flat_store_byte 355; GCN-HSA: flat_store_byte 356; GCN-HSA: flat_store_byte 357define void @global_unaligned_load_store_v4i32(<4 x i32> addrspace(1)* %p, <4 x i32> addrspace(1)* %r) #0 { 358 %v = load <4 x i32>, <4 x i32> addrspace(1)* %p, align 1 359 store <4 x i32> %v, <4 x i32> addrspace(1)* %r, align 1 360 ret void 361} 362 363; FUNC-LABEL: {{^}}local_load_i64_align_4: 364; GCN: ds_read2_b32 365define void @local_load_i64_align_4(i64 addrspace(1)* nocapture %out, i64 addrspace(3)* %in) #0 { 366 %val = load i64, i64 addrspace(3)* %in, align 4 367 store i64 %val, i64 addrspace(1)* %out, align 8 368 ret void 369} 370 371; FUNC-LABEL: {{^}}local_load_i64_align_4_with_offset 372; GCN: ds_read2_b32 v[{{[0-9]+}}:{{[0-9]+}}], v{{[0-9]}} offset0:8 offset1:9 373define void @local_load_i64_align_4_with_offset(i64 addrspace(1)* nocapture %out, i64 addrspace(3)* %in) #0 { 374 %ptr = getelementptr i64, i64 addrspace(3)* %in, i32 4 375 %val = load i64, i64 addrspace(3)* %ptr, align 4 376 store i64 %val, i64 addrspace(1)* %out, align 8 377 ret void 378} 379 380; FUNC-LABEL: {{^}}local_load_i64_align_4_with_split_offset: 381; The tests for the case where the lo offset is 8-bits, but the hi offset is 9-bits 382; GCN: ds_read2_b32 v[{{[0-9]+}}:{{[0-9]+}}], v{{[0-9]}} offset1:1 383; GCN: s_endpgm 384define void @local_load_i64_align_4_with_split_offset(i64 addrspace(1)* nocapture %out, i64 addrspace(3)* %in) #0 { 385 %ptr = bitcast i64 addrspace(3)* %in to i32 addrspace(3)* 386 %ptr255 = getelementptr i32, i32 addrspace(3)* %ptr, i32 255 387 %ptri64 = bitcast i32 addrspace(3)* %ptr255 to i64 addrspace(3)* 388 %val = load i64, i64 addrspace(3)* %ptri64, align 4 389 store i64 %val, i64 addrspace(1)* %out, align 8 390 ret void 391} 392 393; FUNC-LABEL: {{^}}local_load_i64_align_1: 394; GCN: ds_read_u8 395; GCN: ds_read_u8 396; GCN: ds_read_u8 397; GCN: ds_read_u8 398; GCN: ds_read_u8 399; GCN: ds_read_u8 400; GCN: ds_read_u8 401; GCN: ds_read_u8 402; GCN: store_dwordx2 403define void @local_load_i64_align_1(i64 addrspace(1)* nocapture %out, i64 addrspace(3)* %in) #0 { 404 %val = load i64, i64 addrspace(3)* %in, align 1 405 store i64 %val, i64 addrspace(1)* %out, align 8 406 ret void 407} 408 409; FUNC-LABEL: {{^}}local_store_i64_align_4: 410; GCN: ds_write2_b32 411define void @local_store_i64_align_4(i64 addrspace(3)* %out, i64 %val) #0 { 412 store i64 %val, i64 addrspace(3)* %out, align 4 413 ret void 414} 415 416; FUNC-LABEL: {{^}}local_store_i64_align_4_with_offset 417; GCN: ds_write2_b32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset0:8 offset1:9 418; GCN: s_endpgm 419define void @local_store_i64_align_4_with_offset(i64 addrspace(3)* %out) #0 { 420 %ptr = getelementptr i64, i64 addrspace(3)* %out, i32 4 421 store i64 0, i64 addrspace(3)* %ptr, align 4 422 ret void 423} 424 425; FUNC-LABEL: {{^}}local_store_i64_align_4_with_split_offset: 426; The tests for the case where the lo offset is 8-bits, but the hi offset is 9-bits 427; GCN: ds_write2_b32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset1:1 428; GCN: s_endpgm 429define void @local_store_i64_align_4_with_split_offset(i64 addrspace(3)* %out) #0 { 430 %ptr = bitcast i64 addrspace(3)* %out to i32 addrspace(3)* 431 %ptr255 = getelementptr i32, i32 addrspace(3)* %ptr, i32 255 432 %ptri64 = bitcast i32 addrspace(3)* %ptr255 to i64 addrspace(3)* 433 store i64 0, i64 addrspace(3)* %out, align 4 434 ret void 435} 436 437; FUNC-LABEL: {{^}}constant_load_unaligned_i16: 438; GCN-NOHSA: buffer_load_ushort 439; GCN-HSA: flat_load_ushort 440 441; EG: VTX_READ_16 T{{[0-9]+\.X, T[0-9]+\.X}} 442define void @constant_load_unaligned_i16(i32 addrspace(1)* %out, i16 addrspace(2)* %in) { 443entry: 444 %tmp0 = getelementptr i16, i16 addrspace(2)* %in, i32 1 445 %tmp1 = load i16, i16 addrspace(2)* %tmp0 446 %tmp2 = zext i16 %tmp1 to i32 447 store i32 %tmp2, i32 addrspace(1)* %out 448 ret void 449} 450 451; FUNC-LABEL: {{^}}constant_load_unaligned_i32: 452; GCN-NOHSA: buffer_load_ubyte 453; GCN-NOHSA: buffer_load_ubyte 454; GCN-NOHSA: buffer_load_ubyte 455; GCN-NOHSA: buffer_load_ubyte 456 457; GCN-HSA: flat_load_ubyte 458; GCN-HSA: flat_load_ubyte 459; GCN-HSA: flat_load_ubyte 460; GCN-HSA: flat_load_ubyte 461define void @constant_load_unaligned_i32(i32 addrspace(1)* %out, i32 addrspace(2)* %in) { 462entry: 463 %tmp0 = load i32, i32 addrspace(2)* %in, align 1 464 store i32 %tmp0, i32 addrspace(1)* %out 465 ret void 466} 467 468; FUNC-LABEL: {{^}}constant_load_unaligned_f32: 469; GCN-NOHSA: buffer_load_ubyte 470; GCN-NOHSA: buffer_load_ubyte 471; GCN-NOHSA: buffer_load_ubyte 472; GCN-NOHSA: buffer_load_ubyte 473 474; GCN-HSA: flat_load_ubyte 475; GCN-HSA: flat_load_ubyte 476; GCN-HSA: flat_load_ubyte 477; GCN-HSA: flat_load_ubyte 478define void @constant_load_unaligned_f32(float addrspace(1)* %out, float addrspace(2)* %in) { 479 %tmp1 = load float, float addrspace(2)* %in, align 1 480 store float %tmp1, float addrspace(1)* %out 481 ret void 482} 483 484attributes #0 = { nounwind } 485