| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 | |
| ; RUN: llc -mtriple=amdgpu9.50 < %s | FileCheck %s | |
| ; Block placement rotates these loops so that %body, not the LoopInfo header, | |
| ; is the backedge destination that gets aligned. The GFX950 fetch-window | |
| ; alignment decision must be based on the first instruction of %body. | |
| ; %body starts with an 8-byte v_mul_f64 while %header starts with a 4-byte | |
| ; s_cmp, so %body must be aligned. | |
| define amdgpu_kernel void @rotated_loop_8byte_top_block(ptr addrspace(1) %out, i32 %n, double %x) { | |
| ; CHECK-LABEL: rotated_loop_8byte_top_block: | |
| ; CHECK: ; %bb.0: ; %entry | |
| ; CHECK-NEXT: s_load_dwordx2 s[2:3], s[4:5], 0x34 | |
| ; CHECK-NEXT: s_load_dword s0, s[4:5], 0x2c | |
| ; CHECK-NEXT: s_mov_b32 s1, 0 | |
| ; CHECK-NEXT: s_waitcnt lgkmcnt(0) | |
| ; CHECK-NEXT: v_mov_b64_e32 v[0:1], s[2:3] | |
| ; CHECK-NEXT: s_cmp_ge_i32 s1, s0 | |
| ; CHECK-NEXT: s_cbranch_scc1 .LBB0_2 | |
| ; CHECK-NEXT: .p2align 5, , 4 | |
| ; CHECK-NEXT: .LBB0_1: ; %body | |
| ; CHECK-NEXT: ; =>This Inner Loop Header: Depth=1 | |
| ; CHECK-NEXT: v_mul_f64 v[0:1], v[0:1], v[0:1] | |
| ; CHECK-NEXT: s_add_i32 s1, s1, 1 | |
| ; CHECK-NEXT: s_cmp_ge_i32 s1, s0 | |
| ; CHECK-NEXT: s_cbranch_scc0 .LBB0_1 | |
| ; CHECK-NEXT: .LBB0_2: ; %exit | |
| ; CHECK-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 | |
| ; CHECK-NEXT: v_mov_b32_e32 v2, 0 | |
| ; CHECK-NEXT: s_waitcnt lgkmcnt(0) | |
| ; CHECK-NEXT: global_store_dwordx2 v2, v[0:1], s[0:1] | |
| ; CHECK-NEXT: s_endpgm | |
| entry: | |
| br label %header | |
| header: | |
| %i = phi i32 [ 0, %entry ], [ %i.next, %body ] | |
| %acc = phi double [ %x, %entry ], [ %acc.next, %body ] | |
| %cmp = icmp slt i32 %i, %n | |
| br i1 %cmp, label %body, label %exit | |
| body: | |
| %acc.next = fmul double %acc, %acc | |
| %i.next = add i32 %i, 1 | |
| br label %header | |
| exit: | |
| store double %acc, ptr addrspace(1) %out | |
| ret void | |
| } | |
| ; %body starts with a 4-byte s_add while %header starts with an 8-byte s_cmp | |
| ; with a literal operand, so %body must not be aligned. | |
| define amdgpu_kernel void @rotated_loop_4byte_top_block(ptr addrspace(1) %out, i32 %n, double %x) { | |
| ; CHECK-LABEL: rotated_loop_4byte_top_block: | |
| ; CHECK: ; %bb.0: ; %entry | |
| ; CHECK-NEXT: s_load_dwordx2 s[2:3], s[4:5], 0x34 | |
| ; CHECK-NEXT: s_load_dword s0, s[4:5], 0x2c | |
| ; CHECK-NEXT: s_mov_b32 s1, 0 | |
| ; CHECK-NEXT: s_waitcnt lgkmcnt(0) | |
| ; CHECK-NEXT: v_mov_b64_e32 v[0:1], s[2:3] | |
| ; CHECK-NEXT: .p2align 5, , 4 | |
| ; CHECK-NEXT: .LBB1_1: ; %header | |
| ; CHECK-NEXT: ; =>This Inner Loop Header: Depth=1 | |
| ; CHECK-NEXT: s_cmp_gt_i32 s1, 0xf423f | |
| ; CHECK-NEXT: v_mul_f64 v[0:1], v[0:1], v[0:1] | |
| ; CHECK-NEXT: s_cbranch_scc1 .LBB1_3 | |
| ; CHECK-NEXT: ; %bb.2: ; %body | |
| ; CHECK-NEXT: ; in Loop: Header=BB1_1 Depth=1 | |
| ; CHECK-NEXT: s_add_i32 s1, s1, s0 | |
| ; CHECK-NEXT: v_add_f64 v[0:1], v[0:1], 1.0 | |
| ; CHECK-NEXT: s_branch .LBB1_1 | |
| ; CHECK-NEXT: .LBB1_3: ; %exit | |
| ; CHECK-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 | |
| ; CHECK-NEXT: v_mov_b32_e32 v2, 0 | |
| ; CHECK-NEXT: s_waitcnt lgkmcnt(0) | |
| ; CHECK-NEXT: global_store_dwordx2 v2, v[0:1], s[0:1] | |
| ; CHECK-NEXT: s_endpgm | |
| entry: | |
| br label %header | |
| header: | |
| %i = phi i32 [ 0, %entry ], [ %i.next, %body ] | |
| %acc = phi double [ %x, %entry ], [ %acc.next, %body ] | |
| %acc.sq = fmul double %acc, %acc | |
| %cmp = icmp slt i32 %i, 1000000 | |
| br i1 %cmp, label %body, label %exit | |
| body: | |
| %i.next = add i32 %i, %n | |
| %acc.next = fadd double %acc.sq, 1.0 | |
| br label %header | |
| exit: | |
| store double %acc.sq, ptr addrspace(1) %out | |
| ret void | |
| } |