1# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2# RUN: llc -run-pass=thumb2-reduce-size %s -o - | FileCheck %s
3
4--- |
5  target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
6  target triple = "thumbv8m.main"
7
8  %list_head = type { %list_head*, %list_data* }
9  %list_data = type { i16, i16 }
10
11  define %list_head* @reg_reg_it_block(%list_head* %a, i16 zeroext %b) {
12  entry:
13    br label %while.begin
14
15  while.begin:                                      ; preds = %while.body.end, %entry
16    %list.addr.i = phi %list_head* [ %ld.5, %while.body.end ], [ %a, %entry ]
17    %info.i = getelementptr inbounds %list_head, %list_head* %list.addr.i, i32 0, i32 1
18    %ld.0 = load %list_data*, %list_data** %info.i, align 4
19    %data16.i1 = bitcast %list_data* %ld.0 to i16*
20    %ld.1 = load i16, i16* %data16.i1, align 2
21    %xor.1 = xor i16 %ld.1, %b
22    %cmp.i = icmp eq i16 %xor.1, 0
23    br i1 %cmp.i, label %exit, label %while.body.a
24
25  while.body.a:                                     ; preds = %while.begin
26    %next.i2 = bitcast %list_head* %list.addr.i to %list_head**
27    %ld.2 = load %list_head*, %list_head** %next.i2, align 4
28    %cmp.i.1 = icmp eq %list_head* %ld.2, null
29    br i1 %cmp.i.1, label %exit, label %it.block
30
31  it.block:                                         ; preds = %while.body.a
32    %info.i.1 = getelementptr inbounds %list_head, %list_head* %ld.2, i32 0, i32 1
33    %ld.3 = load %list_data*, %list_data** %info.i.1, align 4
34    %data16.i.13 = bitcast %list_data* %ld.3 to i16*
35    %ld.4 = load i16, i16* %data16.i.13, align 2
36    %xor.2 = xor i16 %ld.4, %b
37    %cmp.i.2 = icmp eq i16 %xor.2, 0
38    br i1 %cmp.i.2, label %exit, label %while.body.end
39
40  while.body.end:                                   ; preds = %it.block
41    %next.i.14 = bitcast %list_head* %ld.2 to %list_head**
42    %ld.5 = load %list_head*, %list_head** %next.i.14, align 4
43    %cmp.i.3 = icmp eq %list_head* %ld.5, null
44    br i1 %cmp.i.3, label %exit, label %while.begin
45
46  exit:                                             ; preds = %while.body.end, %it.block, %while.body.a, %while.begin
47    %res = phi %list_head* [ %list.addr.i, %while.begin ], [ %ld.2, %while.body.a ], [ %ld.2, %it.block ], [ %ld.5, %while.body.end ]
48    ret %list_head* %res
49  }
50
51  define i16 @op_not_killed(%list_head* %a, i16 zeroext %b) {
52  entry:
53    br label %while.begin
54
55  while.begin:                                      ; preds = %while.body.end, %entry
56    %list.addr.i = phi %list_head* [ %ld.5, %while.body.end ], [ %a, %entry ]
57    %info.i = getelementptr inbounds %list_head, %list_head* %list.addr.i, i32 0, i32 1
58    %ld.0 = load %list_data*, %list_data** %info.i, align 4
59    %data16.i1 = bitcast %list_data* %ld.0 to i16*
60    %ld.1 = load i16, i16* %data16.i1, align 2
61    %xor.1 = xor i16 %ld.1, %b
62    %cmp.i = icmp eq i16 %xor.1, 0
63    br i1 %cmp.i, label %exit, label %while.body.a
64
65  while.body.a:                                     ; preds = %while.begin
66    %next.i2 = bitcast %list_head* %list.addr.i to %list_head**
67    %ld.2 = load %list_head*, %list_head** %next.i2, align 4
68    %cmp.i.1 = icmp eq %list_head* %ld.2, null
69    br i1 %cmp.i.1, label %exit, label %it.block
70
71  it.block:                                         ; preds = %while.body.a
72    %info.i.1 = getelementptr inbounds %list_head, %list_head* %ld.2, i32 0, i32 1
73    %ld.3 = load %list_data*, %list_data** %info.i.1, align 4
74    %data16.i.13 = bitcast %list_data* %ld.3 to i16*
75    %ld.4 = load i16, i16* %data16.i.13, align 2
76    %xor.2 = xor i16 %ld.4, %b
77    %cmp.i.2 = icmp eq i16 %xor.2, 0
78    br i1 %cmp.i.2, label %exit, label %while.body.end
79
80  while.body.end:                                   ; preds = %it.block
81    %next.i.14 = bitcast %list_head* %ld.2 to %list_head**
82    %ld.5 = load %list_head*, %list_head** %next.i.14, align 4
83    %cmp.i.3 = icmp eq %list_head* %ld.5, null
84    br i1 %cmp.i.3, label %exit, label %while.begin
85
86  exit:                                             ; preds = %while.body.end, %it.block, %while.body.a, %while.begin
87    %res = phi i16 [ %ld.1, %while.begin ], [ %ld.1, %while.body.a ], [ %ld.4, %it.block ], [ %ld.4, %while.body.end ]
88    ret i16 %res
89  }
90
91...
92---
93name:            reg_reg_it_block
94tracksRegLiveness: true
95liveins:
96  - { reg: '$r0', virtual-reg: '' }
97  - { reg: '$r1', virtual-reg: '' }
98body:             |
99  ; CHECK-LABEL: name: reg_reg_it_block
100  ; CHECK: bb.0.entry:
101  ; CHECK:   successors: %bb.2(0x80000000)
102  ; CHECK:   liveins: $r0, $r1
103  ; CHECK:   t2B %bb.2, 14 /* CC::al */, $noreg
104  ; CHECK: bb.1.while.body.end:
105  ; CHECK:   successors: %bb.2(0x80000000)
106  ; CHECK:   liveins: $r0, $r1
107  ; CHECK:   renamable $r0 = tLDRi killed renamable $r0, 0, 14 /* CC::al */, $noreg :: (load (s32) from %ir.next.i.14)
108  ; CHECK:   tCMPi8 renamable $r0, 0, 14 /* CC::al */, $noreg, implicit-def $cpsr
109  ; CHECK:   BUNDLE implicit-def dead $itstate, implicit killed $cpsr, implicit $r0 {
110  ; CHECK:     t2IT 0, 8, implicit-def $itstate
111  ; CHECK:     tBX_RET 0 /* CC::eq */, killed $cpsr, implicit $r0, implicit internal killed $itstate
112  ; CHECK:   }
113  ; CHECK: bb.2.while.begin:
114  ; CHECK:   successors: %bb.4(0x04000000), %bb.3(0x7c000000)
115  ; CHECK:   liveins: $r0, $r1
116  ; CHECK:   renamable $r2 = tLDRi renamable $r0, 1, 14 /* CC::al */, $noreg :: (load (s32) from %ir.info.i)
117  ; CHECK:   renamable $r2 = tLDRHi killed renamable $r2, 0, 14 /* CC::al */, $noreg :: (load (s16) from %ir.data16.i1)
118  ; CHECK:   dead renamable $r2, $cpsr = tEOR killed renamable $r2, renamable $r1, 14 /* CC::al */, $noreg
119  ; CHECK:   t2Bcc %bb.4, 0 /* CC::eq */, killed $cpsr
120  ; CHECK: bb.3.while.body.a:
121  ; CHECK:   successors: %bb.4(0x4207fef8), %bb.1(0x3df80108)
122  ; CHECK:   liveins: $r0, $r1
123  ; CHECK:   renamable $r0 = tLDRi killed renamable $r0, 0, 14 /* CC::al */, $noreg :: (load (s32) from %ir.next.i2)
124  ; CHECK:   tCMPi8 renamable $r0, 0, 14 /* CC::al */, $noreg, implicit-def $cpsr
125  ; CHECK:   BUNDLE implicit-def dead $itstate, implicit-def dead $r2, implicit-def $cpsr, implicit $r0, implicit killed $cpsr, implicit $r1 {
126  ; CHECK:     t2IT 1, 30, implicit-def $itstate
127  ; CHECK:     renamable $r2 = tLDRi renamable $r0, 1, 1 /* CC::ne */, $cpsr, implicit internal $itstate :: (load (s32) from %ir.info.i.1)
128  ; CHECK:     renamable $r2 = tLDRHi internal killed renamable $r2, 0, 1 /* CC::ne */, $cpsr, implicit internal killed $r2, implicit internal $itstate :: (load (s16) from %ir.data16.i.13)
129  ; CHECK:     t2TEQrr internal killed renamable $r2, renamable $r1, 1 /* CC::ne */, killed $cpsr, implicit-def $cpsr, implicit internal killed $itstate
130  ; CHECK:   }
131  ; CHECK:   t2Bcc %bb.1, 1 /* CC::ne */, killed $cpsr
132  ; CHECK: bb.4.exit:
133  ; CHECK:   liveins: $r0
134  ; CHECK:   tBX_RET 14 /* CC::al */, $noreg, implicit killed $r0
135  bb.0.entry:
136    successors: %bb.1(0x80000000)
137    liveins: $r0, $r1
138
139    t2B %bb.1, 14, $noreg
140
141  bb.3.while.body.end:
142    successors: %bb.1(0x80000000)
143    liveins: $r0, $r1
144
145    renamable $r0 = tLDRi killed renamable $r0, 0, 14, $noreg :: (load (s32) from %ir.next.i.14)
146    tCMPi8 renamable $r0, 0, 14, $noreg, implicit-def $cpsr
147    BUNDLE implicit-def dead $itstate, implicit killed $cpsr, implicit $r0 {
148      t2IT 0, 8, implicit-def $itstate
149      tBX_RET 0, killed $cpsr, implicit $r0, implicit internal killed $itstate
150    }
151
152  bb.1.while.begin:
153    successors: %bb.4(0x04000000), %bb.2(0x7c000000)
154    liveins: $r0, $r1
155
156    renamable $r2 = tLDRi renamable $r0, 1, 14, $noreg :: (load (s32) from %ir.info.i)
157    renamable $r2 = tLDRHi killed renamable $r2, 0, 14, $noreg :: (load (s16) from %ir.data16.i1)
158    dead renamable $r2, $cpsr = tEOR killed renamable $r2, renamable $r1, 14, $noreg
159    t2Bcc %bb.4, 0, killed $cpsr
160
161  bb.2.while.body.a:
162    successors: %bb.4(0x80000000), %bb.3(0x78200000)
163    liveins: $r0, $r1
164
165    renamable $r0 = tLDRi killed renamable $r0, 0, 14, $noreg :: (load (s32) from %ir.next.i2)
166    tCMPi8 renamable $r0, 0, 14, $noreg, implicit-def $cpsr
167    BUNDLE implicit-def dead $itstate, implicit-def dead $r2, implicit-def $cpsr, implicit $r0, implicit killed $cpsr, implicit $r1 {
168      t2IT 1, 30, implicit-def $itstate
169      renamable $r2 = tLDRi renamable $r0, 1, 1, $cpsr, implicit internal $itstate :: (load (s32) from %ir.info.i.1)
170      renamable $r2 = tLDRHi internal killed renamable $r2, 0, 1, $cpsr, implicit internal killed $r2, implicit internal $itstate :: (load (s16) from %ir.data16.i.13)
171      t2TEQrr internal killed renamable $r2, renamable $r1, 1, killed $cpsr, implicit-def $cpsr, implicit internal killed $itstate
172    }
173    t2Bcc %bb.3, 1, killed $cpsr
174
175  bb.4.exit:
176    liveins: $r0
177
178    tBX_RET 14, $noreg, implicit killed $r0
179
180...
181---
182name:            op_not_killed
183tracksRegLiveness: true
184liveins:
185  - { reg: '$r0', virtual-reg: '' }
186  - { reg: '$r1', virtual-reg: '' }
187body:             |
188  ; CHECK-LABEL: name: op_not_killed
189  ; CHECK: bb.0.entry:
190  ; CHECK:   successors: %bb.1(0x80000000)
191  ; CHECK:   liveins: $r0, $r1
192  ; CHECK:   $r2 = tMOVr $r0, 14 /* CC::al */, $noreg
193  ; CHECK: bb.1.while.begin:
194  ; CHECK:   successors: %bb.5(0x04000000), %bb.2(0x7c000000)
195  ; CHECK:   liveins: $r1, $r2
196  ; CHECK:   renamable $r0 = tLDRi renamable $r2, 1, 14 /* CC::al */, $noreg :: (load (s32) from %ir.info.i)
197  ; CHECK:   renamable $r0 = tLDRHi killed renamable $r0, 0, 14 /* CC::al */, $noreg :: (load (s16) from %ir.data16.i1)
198  ; CHECK:   t2TEQrr renamable $r0, renamable $r1, 14 /* CC::al */, $noreg, implicit-def $cpsr
199  ; CHECK:   t2Bcc %bb.5, 0 /* CC::eq */, killed $cpsr
200  ; CHECK: bb.2.while.body.a:
201  ; CHECK:   successors: %bb.5(0x04000000), %bb.3(0x7c000000)
202  ; CHECK:   liveins: $r0, $r1, $r2
203  ; CHECK:   renamable $r2 = tLDRi killed renamable $r2, 0, 14 /* CC::al */, $noreg :: (load (s32) from %ir.next.i2)
204  ; CHECK:   tCMPi8 renamable $r2, 0, 14 /* CC::al */, $noreg, implicit-def $cpsr
205  ; CHECK:   t2Bcc %bb.5, 0 /* CC::eq */, killed $cpsr
206  ; CHECK: bb.3.it.block:
207  ; CHECK:   successors: %bb.5(0x04000000), %bb.4(0x7c000000)
208  ; CHECK:   liveins: $r1, $r2
209  ; CHECK:   renamable $r0 = tLDRi renamable $r2, 1, 14 /* CC::al */, $noreg :: (load (s32) from %ir.info.i.1)
210  ; CHECK:   renamable $r0 = tLDRHi killed renamable $r0, 0, 14 /* CC::al */, $noreg :: (load (s16) from %ir.data16.i.13)
211  ; CHECK:   t2TEQrr renamable $r0, renamable $r1, 14 /* CC::al */, $noreg, implicit-def $cpsr
212  ; CHECK:   t2Bcc %bb.5, 0 /* CC::eq */, killed $cpsr
213  ; CHECK: bb.4.while.body.end:
214  ; CHECK:   successors: %bb.5(0x04000000), %bb.1(0x7c000000)
215  ; CHECK:   liveins: $r0, $r1, $r2
216  ; CHECK:   renamable $r2 = tLDRi killed renamable $r2, 0, 14 /* CC::al */, $noreg :: (load (s32) from %ir.next.i.14)
217  ; CHECK:   tCMPi8 renamable $r2, 0, 14 /* CC::al */, $noreg, implicit-def $cpsr
218  ; CHECK:   t2Bcc %bb.1, 1 /* CC::ne */, killed $cpsr
219  ; CHECK: bb.5.exit:
220  ; CHECK:   liveins: $r0
221  ; CHECK:   tBX_RET 14 /* CC::al */, $noreg, implicit $r0
222  bb.0.entry:
223    successors: %bb.1(0x80000000)
224    liveins: $r0, $r1
225
226    $r2 = tMOVr $r0, 14, $noreg
227
228  bb.1.while.begin:
229    successors: %bb.5(0x04000000), %bb.2(0x7c000000)
230    liveins: $r1, $r2
231
232    renamable $r0 = t2LDRi12 renamable $r2, 4, 14, $noreg :: (load (s32) from %ir.info.i)
233    renamable $r0 = t2LDRHi12 killed renamable $r0, 0, 14, $noreg :: (load (s16) from %ir.data16.i1)
234    t2TEQrr renamable $r0, renamable $r1, 14, $noreg, implicit-def $cpsr
235    t2Bcc %bb.5, 0, killed $cpsr
236
237  bb.2.while.body.a:
238    successors: %bb.5(0x04000000), %bb.3(0x7c000000)
239    liveins: $r0, $r1, $r2
240
241    renamable $r2 = t2LDRi12 killed renamable $r2, 0, 14, $noreg :: (load (s32) from %ir.next.i2)
242    t2CMPri renamable $r2, 0, 14, $noreg, implicit-def $cpsr
243    t2Bcc %bb.5, 0, killed $cpsr
244
245  bb.3.it.block:
246    successors: %bb.5(0x04000000), %bb.4(0x7c000000)
247    liveins: $r1, $r2
248
249    renamable $r0 = t2LDRi12 renamable $r2, 4, 14, $noreg :: (load (s32) from %ir.info.i.1)
250    renamable $r0 = t2LDRHi12 killed renamable $r0, 0, 14, $noreg :: (load (s16) from %ir.data16.i.13)
251    t2TEQrr renamable $r0, renamable $r1, 14, $noreg, implicit-def $cpsr
252    t2Bcc %bb.5, 0, killed $cpsr
253
254  bb.4.while.body.end:
255    successors: %bb.5(0x04000000), %bb.1(0x7c000000)
256    liveins: $r0, $r1, $r2
257
258    renamable $r2 = t2LDRi12 killed renamable $r2, 0, 14, $noreg :: (load (s32) from %ir.next.i.14)
259    t2CMPri renamable $r2, 0, 14, $noreg, implicit-def $cpsr
260    t2Bcc %bb.1, 1, killed $cpsr
261
262  bb.5.exit:
263    liveins: $r0
264
265    tBX_RET 14, $noreg, implicit $r0
266
267...
268