[AMDGPU] Add True16 register classes.
[llvm-project.git] / llvm / test / CodeGen / AMDGPU / si-unify-exit-multiple-unreachables.ll
blobf9a17783f0d3523c30e34c1f618f616f39ec445c
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=amdgcn-amd-amdhsa -mcpu=gfx906 -stop-after=amdgpu-unify-divergent-exit-nodes | FileCheck %s --check-prefix=UNIFY
3 ; RUN: llc < %s -mtriple=amdgcn-amd-amdhsa -mcpu=gfx906 -verify-machineinstrs | FileCheck %s
5 declare void @llvm.trap()
6 declare i32 @llvm.amdgcn.workitem.id.x()
8 define amdgpu_kernel void @kernel(i32 %a, ptr addrspace(1) %x, i32 noundef %n) {
9 ; This used to bypass the structurization process because structurizer is unable to
10 ; handle multiple-exits CFG. This should be correctly structurized.
11 ; UNIFY-LABEL: define amdgpu_kernel void @kernel
12 ; UNIFY-LABEL: entry:
13 ; UNIFY:         %tid = call i32 @llvm.amdgcn.workitem.id.x()
14 ; UNIFY-NEXT:    %cmp = icmp eq i32 %n.load, 256
15 ; UNIFY-NEXT:    br i1 %cmp, label %if.then, label %if.else
16 ; UNIFY-LABEL: if.then:
17 ; UNIFY-NEXT:    %cmp1 = icmp eq i32 %a.load, 0
18 ; UNIFY-NEXT:    br i1 %cmp1, label %if.end6.sink.split, label %cond.false
19 ; UNIFY-LABEL: cond.false:
20 ; UNIFY-NEXT:    call void @llvm.trap()
21 ; UNIFY-NEXT:    br label %UnifiedUnreachableBlock
22 ; UNIFY-LABEL: if.else:
23 ; UNIFY-NEXT:    %cmp2 = icmp ult i32 %tid, 10
24 ; UNIFY-NEXT:    br i1 %cmp2, label %if.then3, label %UnifiedReturnBlock
25 ; UNIFY-LABEL: if.then3:
26 ; UNIFY-NEXT:    %cmp1.i7 = icmp eq i32 %a.load, 0
27 ; UNIFY-NEXT:    br i1 %cmp1.i7, label %if.end6.sink.split, label %cond.false.i8
28 ; UNIFY-LABEL: cond.false.i8:
29 ; UNIFY-NEXT:    call void @llvm.trap()
30 ; UNIFY-NEXT:    br label %UnifiedUnreachableBlock
31 ; UNIFY-LABEL: if.end6.sink.split:
32 ; UNIFY-NEXT:    %x.kernarg.offset = getelementptr inbounds i8, ptr addrspace(4) %kernel.kernarg.segment, i64 8
33 ; UNIFY-NEXT:    %x.load = load ptr addrspace(1), ptr addrspace(4) %x.kernarg.offset, align 8, !invariant.load !0
34 ; UNIFY-NEXT:    %idxprom = sext i32 %tid to i64
35 ; UNIFY-NEXT:    %x1 = getelementptr inbounds i32, ptr addrspace(1) %x.load, i64 %idxprom
36 ; UNIFY-NEXT:    store i32 %a.load, ptr addrspace(1) %x1, align 4
37 ; UNIFY-NEXT:    br label %UnifiedReturnBlock
38 ; UNIFY-LABEL: UnifiedUnreachableBlock:
39 ; UNIFY-NEXT:    call void @llvm.amdgcn.unreachable()
40 ; UNIFY-NEXT:    br label %UnifiedReturnBlock
41 ; UNIFY-LABEL: UnifiedReturnBlock:
42 ; UNIFY-NEXT:    ret void
44 ; CHECK-LABEL: kernel:
45 ; CHECK:       ; %bb.0: ; %entry
46 ; CHECK-NEXT:    s_load_dword s0, s[4:5], 0x10
47 ; CHECK-NEXT:    s_load_dword s10, s[4:5], 0x0
48 ; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
49 ; CHECK-NEXT:    s_cmpk_lg_i32 s0, 0x100
50 ; CHECK-NEXT:    s_cbranch_scc0 .LBB0_6
51 ; CHECK-NEXT:  ; %bb.1: ; %if.else
52 ; CHECK-NEXT:    v_cmp_gt_u32_e32 vcc, 10, v0
53 ; CHECK-NEXT:    s_mov_b64 s[6:7], 0
54 ; CHECK-NEXT:    s_mov_b64 s[2:3], 0
55 ; CHECK-NEXT:    s_mov_b64 s[0:1], 0
56 ; CHECK-NEXT:    s_and_saveexec_b64 s[8:9], vcc
57 ; CHECK-NEXT:    s_cbranch_execz .LBB0_5
58 ; CHECK-NEXT:  ; %bb.2: ; %if.then3
59 ; CHECK-NEXT:    s_cmp_lg_u32 s10, 0
60 ; CHECK-NEXT:    s_cbranch_scc1 .LBB0_14
61 ; CHECK-NEXT:  ; %bb.3:
62 ; CHECK-NEXT:    s_mov_b64 s[0:1], -1
63 ; CHECK-NEXT:  .LBB0_4: ; %Flow3
64 ; CHECK-NEXT:    s_and_b64 s[0:1], s[0:1], exec
65 ; CHECK-NEXT:    s_and_b64 s[2:3], s[2:3], exec
66 ; CHECK-NEXT:  .LBB0_5: ; %Flow2
67 ; CHECK-NEXT:    s_or_b64 exec, exec, s[8:9]
68 ; CHECK-NEXT:    s_and_b64 vcc, exec, s[6:7]
69 ; CHECK-NEXT:    s_cbranch_vccz .LBB0_8
70 ; CHECK-NEXT:    s_branch .LBB0_7
71 ; CHECK-NEXT:  .LBB0_6:
72 ; CHECK-NEXT:    s_mov_b64 s[2:3], 0
73 ; CHECK-NEXT:    s_mov_b64 s[0:1], 0
74 ; CHECK-NEXT:    s_cbranch_execz .LBB0_8
75 ; CHECK-NEXT:  .LBB0_7: ; %if.then
76 ; CHECK-NEXT:    s_cmp_lg_u32 s10, 0
77 ; CHECK-NEXT:    s_mov_b64 s[0:1], -1
78 ; CHECK-NEXT:    s_cbranch_scc1 .LBB0_13
79 ; CHECK-NEXT:  .LBB0_8: ; %Flow4
80 ; CHECK-NEXT:    s_and_saveexec_b64 s[6:7], s[2:3]
81 ; CHECK-NEXT:  .LBB0_9: ; %UnifiedUnreachableBlock
82 ; CHECK-NEXT:    ; divergent unreachable
83 ; CHECK-NEXT:  .LBB0_10: ; %Flow6
84 ; CHECK-NEXT:    s_or_b64 exec, exec, s[6:7]
85 ; CHECK-NEXT:    s_and_saveexec_b64 s[2:3], s[0:1]
86 ; CHECK-NEXT:    s_cbranch_execz .LBB0_12
87 ; CHECK-NEXT:  ; %bb.11: ; %if.end6.sink.split
88 ; CHECK-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x8
89 ; CHECK-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
90 ; CHECK-NEXT:    v_mov_b32_e32 v1, s10
91 ; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
92 ; CHECK-NEXT:    global_store_dword v0, v1, s[0:1]
93 ; CHECK-NEXT:  .LBB0_12: ; %UnifiedReturnBlock
94 ; CHECK-NEXT:    s_endpgm
95 ; CHECK-NEXT:  .LBB0_13: ; %cond.false
96 ; CHECK-NEXT:    s_mov_b64 s[0:1], 0
97 ; CHECK-NEXT:    s_or_b64 s[2:3], s[2:3], exec
98 ; CHECK-NEXT:    s_trap 2
99 ; CHECK-NEXT:    s_and_saveexec_b64 s[6:7], s[2:3]
100 ; CHECK-NEXT:    s_cbranch_execnz .LBB0_9
101 ; CHECK-NEXT:    s_branch .LBB0_10
102 ; CHECK-NEXT:  .LBB0_14: ; %cond.false.i8
103 ; CHECK-NEXT:    s_mov_b64 s[2:3], -1
104 ; CHECK-NEXT:    s_trap 2
105 ; CHECK-NEXT:    s_branch .LBB0_4
106 entry:
107   %tid = call i32 @llvm.amdgcn.workitem.id.x()
108   %cmp = icmp eq i32 %n, 256
109   br i1 %cmp, label %if.then, label %if.else
111 if.then:
112   %cmp1 = icmp eq i32 %a, 0
113   br i1 %cmp1, label %if.end6.sink.split, label %cond.false
115 cond.false:
116   call void @llvm.trap()
117   unreachable
119 if.else:
120   %cmp2 = icmp ult i32 %tid, 10
121   br i1 %cmp2, label %if.then3, label %if.end6
123 if.then3:
124   %cmp1.i7 = icmp eq i32 %a, 0
125   br i1 %cmp1.i7, label %if.end6.sink.split, label %cond.false.i8
127 cond.false.i8:
128   call void @llvm.trap()
129   unreachable
131 if.end6.sink.split:
132   %x1 = getelementptr inbounds i32, ptr addrspace(1) %x, i32 %tid
133   store i32 %a, ptr addrspace(1) %x1, align 4
134   br label %if.end6
136 if.end6:
137   ret void