1; RUN: opt -S -codegenprepare -mtriple=amdgcn-unknown-unknown -mcpu=tahiti < %s | FileCheck -check-prefix=OPT -check-prefix=OPT-SI %s 2; RUN: opt -S -codegenprepare -mtriple=amdgcn-unknown-unknown -mcpu=bonaire < %s | FileCheck -check-prefix=OPT -check-prefix=OPT-CI %s 3; RUN: opt -S -codegenprepare -mtriple=amdgcn-unknown-unknown -mcpu=tonga -mattr=-flat-for-global < %s | FileCheck -check-prefix=OPT -check-prefix=OPT-VI %s 4; RUN: llc -march=amdgcn -mcpu=tahiti -mattr=-promote-alloca -amdgpu-sroa=0 < %s | FileCheck -check-prefix=GCN -check-prefix=SI %s 5; RUN: llc -march=amdgcn -mcpu=bonaire -mattr=-promote-alloca -amdgpu-sroa=0 < %s | FileCheck -check-prefix=GCN -check-prefix=CI %s 6; RUN: llc -march=amdgcn -mcpu=tonga -mattr=-flat-for-global -mattr=-promote-alloca -amdgpu-sroa=0 < %s | FileCheck -check-prefix=GCN -check-prefix=VI %s 7 8; OPT-LABEL: @test_sink_global_small_offset_i32( 9; OPT-CI-NOT: getelementptr i32, i32 addrspace(1)* %in 10; OPT-VI: getelementptr i32, i32 addrspace(1)* %in 11; OPT: br i1 12; OPT-CI: ptrtoint 13 14; GCN-LABEL: {{^}}test_sink_global_small_offset_i32: 15; GCN: {{^}}BB0_2: 16define void @test_sink_global_small_offset_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) { 17entry: 18 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 999999 19 %in.gep = getelementptr i32, i32 addrspace(1)* %in, i64 7 20 %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0 21 %tmp0 = icmp eq i32 %tid, 0 22 br i1 %tmp0, label %endif, label %if 23 24if: 25 %tmp1 = load i32, i32 addrspace(1)* %in.gep 26 br label %endif 27 28endif: 29 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ] 30 store i32 %x, i32 addrspace(1)* %out.gep 31 br label %done 32 33done: 34 ret void 35} 36 37; OPT-LABEL: @test_sink_global_small_max_i32_ds_offset( 38; OPT: %in.gep = getelementptr i8, i8 addrspace(1)* %in, i64 65535 39; OPT: br i1 40 41; GCN-LABEL: {{^}}test_sink_global_small_max_i32_ds_offset: 42; GCN: s_and_saveexec_b64 43; GCN: buffer_load_sbyte {{v[0-9]+}}, off, {{s\[[0-9]+:[0-9]+\]}}, s{{[0-9]+$}} 44; GCN: {{^}}BB1_2: 45; GCN: s_or_b64 exec 46define void @test_sink_global_small_max_i32_ds_offset(i32 addrspace(1)* %out, i8 addrspace(1)* %in) { 47entry: 48 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 99999 49 %in.gep = getelementptr i8, i8 addrspace(1)* %in, i64 65535 50 %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0 51 %tmp0 = icmp eq i32 %tid, 0 52 br i1 %tmp0, label %endif, label %if 53 54if: 55 %tmp1 = load i8, i8 addrspace(1)* %in.gep 56 %tmp2 = sext i8 %tmp1 to i32 57 br label %endif 58 59endif: 60 %x = phi i32 [ %tmp2, %if ], [ 0, %entry ] 61 store i32 %x, i32 addrspace(1)* %out.gep 62 br label %done 63 64done: 65 ret void 66} 67 68; GCN-LABEL: {{^}}test_sink_global_small_max_mubuf_offset: 69; GCN: s_and_saveexec_b64 70; GCN: buffer_load_sbyte {{v[0-9]+}}, off, {{s\[[0-9]+:[0-9]+\]}}, 0 offset:4095{{$}} 71; GCN: {{^}}BB2_2: 72; GCN: s_or_b64 exec 73define void @test_sink_global_small_max_mubuf_offset(i32 addrspace(1)* %out, i8 addrspace(1)* %in) { 74entry: 75 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i32 1024 76 %in.gep = getelementptr i8, i8 addrspace(1)* %in, i64 4095 77 %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0 78 %tmp0 = icmp eq i32 %tid, 0 79 br i1 %tmp0, label %endif, label %if 80 81if: 82 %tmp1 = load i8, i8 addrspace(1)* %in.gep 83 %tmp2 = sext i8 %tmp1 to i32 84 br label %endif 85 86endif: 87 %x = phi i32 [ %tmp2, %if ], [ 0, %entry ] 88 store i32 %x, i32 addrspace(1)* %out.gep 89 br label %done 90 91done: 92 ret void 93} 94 95; GCN-LABEL: {{^}}test_sink_global_small_max_plus_1_mubuf_offset: 96; GCN: s_and_saveexec_b64 97; GCN: buffer_load_sbyte {{v[0-9]+}}, off, {{s\[[0-9]+:[0-9]+\]}}, s{{[0-9]+$}} 98; GCN: {{^}}BB3_2: 99; GCN: s_or_b64 exec 100define void @test_sink_global_small_max_plus_1_mubuf_offset(i32 addrspace(1)* %out, i8 addrspace(1)* %in) { 101entry: 102 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 99999 103 %in.gep = getelementptr i8, i8 addrspace(1)* %in, i64 4096 104 %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0 105 %tmp0 = icmp eq i32 %tid, 0 106 br i1 %tmp0, label %endif, label %if 107 108if: 109 %tmp1 = load i8, i8 addrspace(1)* %in.gep 110 %tmp2 = sext i8 %tmp1 to i32 111 br label %endif 112 113endif: 114 %x = phi i32 [ %tmp2, %if ], [ 0, %entry ] 115 store i32 %x, i32 addrspace(1)* %out.gep 116 br label %done 117 118done: 119 ret void 120} 121 122; OPT-LABEL: @test_sink_scratch_small_offset_i32( 123; OPT-NOT: getelementptr [512 x i32] 124; OPT: br i1 125; OPT: ptrtoint 126 127; GCN-LABEL: {{^}}test_sink_scratch_small_offset_i32: 128; GCN: s_and_saveexec_b64 129; GCN: buffer_store_dword {{v[0-9]+}}, off, {{s\[[0-9]+:[0-9]+\]}}, {{s[0-9]+}} offset:4092{{$}} 130; GCN: buffer_load_dword {{v[0-9]+}}, off, {{s\[[0-9]+:[0-9]+\]}}, {{s[0-9]+}} offset:4092{{$}} 131; GCN: {{^}}BB4_2: 132define void @test_sink_scratch_small_offset_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %arg) { 133entry: 134 %alloca = alloca [512 x i32], align 4 135 %out.gep.0 = getelementptr i32, i32 addrspace(1)* %out, i64 999998 136 %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i64 999999 137 %add.arg = add i32 %arg, 8 138 %alloca.gep = getelementptr [512 x i32], [512 x i32]* %alloca, i32 0, i32 1022 139 %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0 140 %tmp0 = icmp eq i32 %tid, 0 141 br i1 %tmp0, label %endif, label %if 142 143if: 144 store volatile i32 123, i32* %alloca.gep 145 %tmp1 = load volatile i32, i32* %alloca.gep 146 br label %endif 147 148endif: 149 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ] 150 store i32 %x, i32 addrspace(1)* %out.gep.0 151 %load = load volatile i32, i32* %alloca.gep 152 store i32 %load, i32 addrspace(1)* %out.gep.1 153 br label %done 154 155done: 156 ret void 157} 158 159; This ends up not fitting due to the reserved 4 bytes at offset 0 160; OPT-LABEL: @test_sink_scratch_small_offset_i32_reserved( 161; OPT-NOT: getelementptr [512 x i32] 162; OPT: br i1 163; OPT: ptrtoint 164 165; GCN-LABEL: {{^}}test_sink_scratch_small_offset_i32_reserved: 166; GCN: s_and_saveexec_b64 167; GCN: v_mov_b32_e32 [[BASE_FI0:v[0-9]+]], 4 168; GCN: buffer_store_dword {{v[0-9]+}}, [[BASE_FI0]], {{s\[[0-9]+:[0-9]+\]}}, {{s[0-9]+}} offen offset:4092{{$}} 169; GCN: v_mov_b32_e32 [[BASE_FI1:v[0-9]+]], 4 170; GCN: buffer_load_dword {{v[0-9]+}}, [[BASE_FI1]], {{s\[[0-9]+:[0-9]+\]}}, {{s[0-9]+}} offen offset:4092{{$}} 171; GCN: {{^BB[0-9]+}}_2: 172 173define void @test_sink_scratch_small_offset_i32_reserved(i32 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %arg) { 174entry: 175 %alloca = alloca [512 x i32], align 4 176 %out.gep.0 = getelementptr i32, i32 addrspace(1)* %out, i64 999998 177 %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i64 999999 178 %add.arg = add i32 %arg, 8 179 %alloca.gep = getelementptr [512 x i32], [512 x i32]* %alloca, i32 0, i32 1023 180 %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0 181 %tmp0 = icmp eq i32 %tid, 0 182 br i1 %tmp0, label %endif, label %if 183 184if: 185 store volatile i32 123, i32* %alloca.gep 186 %tmp1 = load volatile i32, i32* %alloca.gep 187 br label %endif 188 189endif: 190 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ] 191 store i32 %x, i32 addrspace(1)* %out.gep.0 192 %load = load volatile i32, i32* %alloca.gep 193 store i32 %load, i32 addrspace(1)* %out.gep.1 194 br label %done 195 196done: 197 ret void 198} 199 200; OPT-LABEL: @test_no_sink_scratch_large_offset_i32( 201; OPT: %alloca.gep = getelementptr [512 x i32], [512 x i32]* %alloca, i32 0, i32 1024 202; OPT: br i1 203; OPT-NOT: ptrtoint 204 205; GCN-LABEL: {{^}}test_no_sink_scratch_large_offset_i32: 206; GCN: s_and_saveexec_b64 207; GCN: buffer_store_dword {{v[0-9]+}}, {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, {{s[0-9]+}} offen{{$}} 208; GCN: buffer_load_dword {{v[0-9]+}}, {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, {{s[0-9]+}} offen{{$}} 209; GCN: {{^BB[0-9]+}}_2: 210define void @test_no_sink_scratch_large_offset_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %arg) { 211entry: 212 %alloca = alloca [512 x i32], align 4 213 %out.gep.0 = getelementptr i32, i32 addrspace(1)* %out, i64 999998 214 %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i64 999999 215 %add.arg = add i32 %arg, 8 216 %alloca.gep = getelementptr [512 x i32], [512 x i32]* %alloca, i32 0, i32 1024 217 %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0 218 %tmp0 = icmp eq i32 %tid, 0 219 br i1 %tmp0, label %endif, label %if 220 221if: 222 store volatile i32 123, i32* %alloca.gep 223 %tmp1 = load volatile i32, i32* %alloca.gep 224 br label %endif 225 226endif: 227 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ] 228 store i32 %x, i32 addrspace(1)* %out.gep.0 229 %load = load volatile i32, i32* %alloca.gep 230 store i32 %load, i32 addrspace(1)* %out.gep.1 231 br label %done 232 233done: 234 ret void 235} 236 237; GCN-LABEL: {{^}}test_sink_global_vreg_sreg_i32: 238; GCN: s_and_saveexec_b64 239; CI: buffer_load_dword {{v[0-9]+}}, {{v\[[0-9]+:[0-9]+\]}}, {{s\[[0-9]+:[0-9]+\]}}, 0 addr64{{$}} 240; VI: flat_load_dword v{{[0-9]+}}, v[{{[0-9]+:[0-9]+}}] 241; GCN: {{^BB[0-9]+}}_2: 242define void @test_sink_global_vreg_sreg_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %offset) { 243entry: 244 %offset.ext = zext i32 %offset to i64 245 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 999999 246 %in.gep = getelementptr i32, i32 addrspace(1)* %in, i64 %offset.ext 247 %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0 248 %tmp0 = icmp eq i32 %tid, 0 249 br i1 %tmp0, label %endif, label %if 250 251if: 252 %tmp1 = load i32, i32 addrspace(1)* %in.gep 253 br label %endif 254 255endif: 256 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ] 257 store i32 %x, i32 addrspace(1)* %out.gep 258 br label %done 259 260done: 261 ret void 262} 263 264; OPT-LABEL: @test_sink_constant_small_offset_i32 265; OPT-NOT: getelementptr i32, i32 addrspace(2)* 266; OPT: br i1 267 268; GCN-LABEL: {{^}}test_sink_constant_small_offset_i32: 269; GCN: s_and_saveexec_b64 270; SI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0x7{{$}} 271; GCN: s_or_b64 exec, exec 272define void @test_sink_constant_small_offset_i32(i32 addrspace(1)* %out, i32 addrspace(2)* %in) { 273entry: 274 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 999999 275 %in.gep = getelementptr i32, i32 addrspace(2)* %in, i64 7 276 %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0 277 %tmp0 = icmp eq i32 %tid, 0 278 br i1 %tmp0, label %endif, label %if 279 280if: 281 %tmp1 = load i32, i32 addrspace(2)* %in.gep 282 br label %endif 283 284endif: 285 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ] 286 store i32 %x, i32 addrspace(1)* %out.gep 287 br label %done 288 289done: 290 ret void 291} 292 293; OPT-LABEL: @test_sink_constant_max_8_bit_offset_i32 294; OPT-NOT: getelementptr i32, i32 addrspace(2)* 295; OPT: br i1 296 297; GCN-LABEL: {{^}}test_sink_constant_max_8_bit_offset_i32: 298; GCN: s_and_saveexec_b64 299; SI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0xff{{$}} 300; GCN: s_or_b64 exec, exec 301define void @test_sink_constant_max_8_bit_offset_i32(i32 addrspace(1)* %out, i32 addrspace(2)* %in) { 302entry: 303 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 999999 304 %in.gep = getelementptr i32, i32 addrspace(2)* %in, i64 255 305 %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0 306 %tmp0 = icmp eq i32 %tid, 0 307 br i1 %tmp0, label %endif, label %if 308 309if: 310 %tmp1 = load i32, i32 addrspace(2)* %in.gep 311 br label %endif 312 313endif: 314 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ] 315 store i32 %x, i32 addrspace(1)* %out.gep 316 br label %done 317 318done: 319 ret void 320} 321 322; OPT-LABEL: @test_sink_constant_max_8_bit_offset_p1_i32 323; OPT-SI: getelementptr i32, i32 addrspace(2)* 324; OPT-CI-NOT: getelementptr i32, i32 addrspace(2)* 325; OPT-VI-NOT: getelementptr i32, i32 addrspace(2)* 326; OPT: br i1 327 328; GCN-LABEL: {{^}}test_sink_constant_max_8_bit_offset_p1_i32: 329; GCN: s_and_saveexec_b64 330; SI: s_movk_i32 [[OFFSET:s[0-9]+]], 0x400 331 332; SI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, [[OFFSET]]{{$}} 333; GCN: s_or_b64 exec, exec 334define void @test_sink_constant_max_8_bit_offset_p1_i32(i32 addrspace(1)* %out, i32 addrspace(2)* %in) { 335entry: 336 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 999999 337 %in.gep = getelementptr i32, i32 addrspace(2)* %in, i64 256 338 %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0 339 %tmp0 = icmp eq i32 %tid, 0 340 br i1 %tmp0, label %endif, label %if 341 342if: 343 %tmp1 = load i32, i32 addrspace(2)* %in.gep 344 br label %endif 345 346endif: 347 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ] 348 store i32 %x, i32 addrspace(1)* %out.gep 349 br label %done 350 351done: 352 ret void 353} 354 355; OPT-LABEL: @test_sink_constant_max_32_bit_offset_i32 356; OPT-SI: getelementptr i32, i32 addrspace(2)* 357; OPT-CI-NOT: getelementptr i32, i32 addrspace(2)* 358; OPT: br i1 359 360; GCN-LABEL: {{^}}test_sink_constant_max_32_bit_offset_i32: 361; GCN: s_and_saveexec_b64 362; GCN: s_add_u32 s{{[0-9]+}}, s{{[0-9]+}}, -4{{$}} 363; GCN: s_addc_u32 s{{[0-9]+}}, s{{[0-9]+}}, 3{{$}} 364; SI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0x0{{$}} 365; GCN: s_or_b64 exec, exec 366define void @test_sink_constant_max_32_bit_offset_i32(i32 addrspace(1)* %out, i32 addrspace(2)* %in) { 367entry: 368 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 999999 369 %in.gep = getelementptr i32, i32 addrspace(2)* %in, i64 4294967295 370 %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0 371 %tmp0 = icmp eq i32 %tid, 0 372 br i1 %tmp0, label %endif, label %if 373 374if: 375 %tmp1 = load i32, i32 addrspace(2)* %in.gep 376 br label %endif 377 378endif: 379 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ] 380 store i32 %x, i32 addrspace(1)* %out.gep 381 br label %done 382 383done: 384 ret void 385} 386 387; OPT-LABEL: @test_sink_constant_max_32_bit_offset_p1_i32 388; OPT: getelementptr i32, i32 addrspace(2)* 389; OPT: br i1 390 391; GCN-LABEL: {{^}}test_sink_constant_max_32_bit_offset_p1_i32: 392; GCN: s_and_saveexec_b64 393; GCN: s_add_u32 394; GCN: s_addc_u32 395; SI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0x0{{$}} 396; GCN: s_or_b64 exec, exec 397define void @test_sink_constant_max_32_bit_offset_p1_i32(i32 addrspace(1)* %out, i32 addrspace(2)* %in) { 398entry: 399 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 999999 400 %in.gep = getelementptr i32, i32 addrspace(2)* %in, i64 17179869181 401 %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0 402 %tmp0 = icmp eq i32 %tid, 0 403 br i1 %tmp0, label %endif, label %if 404 405if: 406 %tmp1 = load i32, i32 addrspace(2)* %in.gep 407 br label %endif 408 409endif: 410 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ] 411 store i32 %x, i32 addrspace(1)* %out.gep 412 br label %done 413 414done: 415 ret void 416} 417 418; GCN-LABEL: {{^}}test_sink_constant_max_20_bit_byte_offset_i32: 419; GCN: s_and_saveexec_b64 420; SI: s_mov_b32 [[OFFSET:s[0-9]+]], 0xffffc{{$}} 421; SI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, [[OFFSET]]{{$}} 422 423; CI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0x3ffff{{$}} 424; VI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0xffffc{{$}} 425 426; GCN: s_or_b64 exec, exec 427define void @test_sink_constant_max_20_bit_byte_offset_i32(i32 addrspace(1)* %out, i32 addrspace(2)* %in) { 428entry: 429 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 999999 430 %in.gep = getelementptr i32, i32 addrspace(2)* %in, i64 262143 431 %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0 432 %tmp0 = icmp eq i32 %tid, 0 433 br i1 %tmp0, label %endif, label %if 434 435if: 436 %tmp1 = load i32, i32 addrspace(2)* %in.gep 437 br label %endif 438 439endif: 440 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ] 441 store i32 %x, i32 addrspace(1)* %out.gep 442 br label %done 443 444done: 445 ret void 446} 447 448; OPT-LABEL: @test_sink_constant_max_20_bit_byte_offset_p1_i32 449; OPT-SI: getelementptr i32, i32 addrspace(2)* 450; OPT-CI-NOT: getelementptr i32, i32 addrspace(2)* 451; OPT-VI: getelementptr i32, i32 addrspace(2)* 452; OPT: br i1 453 454; GCN-LABEL: {{^}}test_sink_constant_max_20_bit_byte_offset_p1_i32: 455; GCN: s_and_saveexec_b64 456; SI: s_mov_b32 [[OFFSET:s[0-9]+]], 0x100000{{$}} 457; SI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, [[OFFSET]]{{$}} 458 459; CI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0x40000{{$}} 460 461; VI: s_mov_b32 [[OFFSET:s[0-9]+]], 0x100000{{$}} 462; VI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, [[OFFSET]]{{$}} 463 464; GCN: s_or_b64 exec, exec 465define void @test_sink_constant_max_20_bit_byte_offset_p1_i32(i32 addrspace(1)* %out, i32 addrspace(2)* %in) { 466entry: 467 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 999999 468 %in.gep = getelementptr i32, i32 addrspace(2)* %in, i64 262144 469 %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0 470 %tmp0 = icmp eq i32 %tid, 0 471 br i1 %tmp0, label %endif, label %if 472 473if: 474 %tmp1 = load i32, i32 addrspace(2)* %in.gep 475 br label %endif 476 477endif: 478 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ] 479 store i32 %x, i32 addrspace(1)* %out.gep 480 br label %done 481 482done: 483 ret void 484} 485 486%struct.foo = type { [3 x float], [3 x float] } 487 488; OPT-LABEL: @sink_ds_address( 489; OPT: ptrtoint %struct.foo addrspace(3)* %ptr to i64 490 491; GCN-LABEL: {{^}}sink_ds_address: 492; GCN: s_load_dword [[SREG1:s[0-9]+]], 493; GCN: v_mov_b32_e32 [[VREG1:v[0-9]+]], [[SREG1]] 494; GCN-DAG: ds_read2_b32 v[{{[0-9+:[0-9]+}}], [[VREG1]] offset0:3 offset1:5 495define void @sink_ds_address(%struct.foo addrspace(3)* nocapture %ptr) nounwind { 496entry: 497 %x = getelementptr inbounds %struct.foo, %struct.foo addrspace(3)* %ptr, i32 0, i32 1, i32 0 498 %y = getelementptr inbounds %struct.foo, %struct.foo addrspace(3)* %ptr, i32 0, i32 1, i32 2 499 br label %bb32 500 501bb32: 502 %a = load float, float addrspace(3)* %x, align 4 503 %b = load float, float addrspace(3)* %y, align 4 504 %cmp = fcmp one float %a, %b 505 br i1 %cmp, label %bb34, label %bb33 506 507bb33: 508 unreachable 509 510bb34: 511 unreachable 512} 513 514; Address offset is not a multiple of 4. This is a valid mubuf offset, 515; but not smrd. 516 517; OPT-LABEL: @test_sink_constant_small_max_mubuf_offset_load_i32_align_1( 518; OPT: br i1 %tmp0, 519; OPT: if: 520; OPT: %sunkaddr = ptrtoint i8 addrspace(2)* %in to i64 521; OPT: %sunkaddr1 = add i64 %sunkaddr, 4095 522define void @test_sink_constant_small_max_mubuf_offset_load_i32_align_1(i32 addrspace(1)* %out, i8 addrspace(2)* %in) { 523entry: 524 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i32 1024 525 %in.gep = getelementptr i8, i8 addrspace(2)* %in, i64 4095 526 %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0 527 %tmp0 = icmp eq i32 %tid, 0 528 br i1 %tmp0, label %endif, label %if 529 530if: 531 %bitcast = bitcast i8 addrspace(2)* %in.gep to i32 addrspace(2)* 532 %tmp1 = load i32, i32 addrspace(2)* %bitcast, align 1 533 br label %endif 534 535endif: 536 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ] 537 store i32 %x, i32 addrspace(1)* %out.gep 538 br label %done 539 540done: 541 ret void 542} 543 544declare i32 @llvm.amdgcn.mbcnt.lo(i32, i32) #0 545 546attributes #0 = { nounwind readnone } 547attributes #1 = { nounwind } 548