1 # RUN: llc -run-pass=prologepilog %s -o - | FileCheck %s
2 # Tests to check that CPSR is saved and restored if live when we emit tMOVi32imm
3 # to resolve a frame offset.
6 target triple = "thumbv6m-arm-none-eabi"
8 define void @test_def_in_block(i32 %x) #0 {
10 %var = alloca i32, align 4
11 %dummy = alloca [2048 x i8], align 1
12 %cmp = icmp eq i32 %x, 0
13 store i32 %x, ptr %var, align 4
14 br i1 %cmp, label %if.then, label %if.end
23 define void @test_live_in(i32 %x) #0 {
25 %var = alloca i32, align 4
26 %dummy = alloca [2048 x i8], align 1
27 %cmp = icmp eq i32 %x, 0
28 br i1 %cmp, label %if.then, label %if.end
31 store i32 %x, ptr %var, align 4
32 %cmp1 = icmp slt i32 %x, 0
33 br i1 %cmp1, label %if.then2, label %if.end
42 define void @test_live_out(i32 %x) #0 {
44 %var = alloca i32, align 4
45 %dummy = alloca [2048 x i8], align 1
46 %cmp = icmp eq i32 %x, 0
47 store i32 %x, ptr %var, align 4
51 br i1 %cmp, label %if.then2, label %if.end
60 define void @test_live_out_def_after_mov(i32 %x) #0 {
62 %var = alloca i32, align 4
63 %dummy = alloca [2048 x i8], align 1
64 store i32 %x, ptr %var, align 4
65 %cmp = icmp eq i32 %x, 0
69 br i1 %cmp, label %if.then2, label %if.end
78 attributes #0 = { "target-features"="+execute-only" }
81 name: test_def_in_block
83 exposesReturnsTwice: false
85 regBankSelected: false
88 tracksRegLiveness: true
91 callsUnwindInit: false
97 failsVerification: false
98 tracksDebugUserValues: false
101 - { reg: '$r0', virtual-reg: '' }
103 isFrameAddressTaken: false
104 isReturnAddressTaken: false
115 cvBytesOfCalleeSavedRegisters: 0
116 hasOpaqueSPAdjustment: false
118 hasMustTailInVarArgFunc: false
125 - { id: 0, name: var, type: default, offset: 0, size: 4, alignment: 4,
126 stack-id: default, callee-saved-register: '', callee-saved-restored: true,
127 local-offset: -4, debug-info-variable: '', debug-info-expression: '',
128 debug-info-location: '' }
129 - { id: 1, name: dummy, type: default, offset: 0, size: 2048, alignment: 1,
130 stack-id: default, callee-saved-register: '', callee-saved-restored: true,
131 local-offset: -2052, debug-info-variable: '', debug-info-expression: '',
132 debug-info-location: '' }
135 debugValueSubstitutions: []
137 machineFunctionInfo: {}
140 successors: %bb.1(0x40000000), %bb.2(0x40000000)
143 ; CHECK-LABEL: name: test_def_in_block
144 ; CHECK-LABEL: bb.0.entry:
145 ; CHECK: tCMPi8 renamable $r0, 0, 14 /* CC::al */, $noreg, implicit-def $cpsr
146 ; CHECK-NEXT: $r2 = t2MRS_M 2048, 14 /* CC::al */, $noreg, implicit $cpsr
147 ; CHECK-NEXT: $r1 = tMOVi32imm 2048, implicit-def $cpsr
148 ; CHECK-NEXT: t2MSR_M 2048, killed $r2, 14 /* CC::al */, $noreg, implicit-def $cpsr
149 ; CHECK-NEXT: $r1 = tADDhirr $r1, killed $sp, 14 /* CC::al */, $noreg
150 ; CHECK-NEXT: tSTRi renamable $r0, killed $r1, 0, 14 /* CC::al */, $noreg :: (store (s32) into %ir.var)
152 tCMPi8 renamable $r0, 0, 14 /* CC::al */, $noreg, implicit-def $cpsr
153 tSTRspi renamable $r0, %stack.0.var, 0, 14 /* CC::al */, $noreg :: (store (s32) into %ir.var)
154 tBcc %bb.1, 1 /* CC::ne */, killed $cpsr
155 tB %bb.2, 14 /* CC::al */, $noreg
158 successors: %bb.2(0x80000000)
160 tB %bb.2, 14 /* CC::al */, $noreg
163 tBX_RET 14 /* CC::al */, $noreg
169 exposesReturnsTwice: false
171 regBankSelected: false
174 tracksRegLiveness: true
177 callsUnwindInit: false
183 failsVerification: false
184 tracksDebugUserValues: false
187 - { reg: '$r0', virtual-reg: '' }
189 isFrameAddressTaken: false
190 isReturnAddressTaken: false
201 cvBytesOfCalleeSavedRegisters: 0
202 hasOpaqueSPAdjustment: false
204 hasMustTailInVarArgFunc: false
211 - { id: 0, name: var, type: default, offset: 0, size: 4, alignment: 4,
212 stack-id: default, callee-saved-register: '', callee-saved-restored: true,
213 local-offset: -4, debug-info-variable: '', debug-info-expression: '',
214 debug-info-location: '' }
215 - { id: 1, name: dummy, type: default, offset: 0, size: 2048, alignment: 1,
216 stack-id: default, callee-saved-register: '', callee-saved-restored: true,
217 local-offset: -2052, debug-info-variable: '', debug-info-expression: '',
218 debug-info-location: '' }
221 debugValueSubstitutions: []
223 machineFunctionInfo: {}
226 successors: %bb.1(0x40000000), %bb.3(0x40000000)
229 tCMPi8 renamable $r0, 0, 14 /* CC::al */, $noreg, implicit-def $cpsr
230 tBcc %bb.3, 1 /* CC::ne */, $cpsr
231 tB %bb.1, 14 /* CC::al */, $noreg
234 successors: %bb.2(0x40000000), %bb.3(0x40000000)
237 ; CHECK-LABEL: name: test_live_in
238 ; CHECK-LABEL: bb.1.if.then:
239 ; CHECK: $r2 = t2MRS_M 2048, 14 /* CC::al */, $noreg, implicit $cpsr
240 ; CHECK-NEXT: $r1 = tMOVi32imm 2048, implicit-def $cpsr
241 ; CHECK-NEXT: t2MSR_M 2048, killed $r2, 14 /* CC::al */, $noreg, implicit-def $cpsr
242 ; CHECK-NEXT: $r1 = tADDhirr $r1, killed $sp, 14 /* CC::al */, $noreg
243 ; CHECK-NEXT: tSTRi renamable $r0, killed $r1, 0, 14 /* CC::al */, $noreg :: (store (s32) into %ir.var)
245 tSTRspi renamable $r0, %stack.0.var, 0, 14 /* CC::al */, $noreg :: (store (s32) into %ir.var)
246 tBcc %bb.3, 5 /* CC::pl */, killed $cpsr
247 tB %bb.2, 14 /* CC::al */, $noreg
250 successors: %bb.3(0x80000000)
252 tB %bb.3, 14 /* CC::al */, $noreg
255 tBX_RET 14 /* CC::al */, $noreg
261 exposesReturnsTwice: false
263 regBankSelected: false
266 tracksRegLiveness: true
269 callsUnwindInit: false
275 failsVerification: false
276 tracksDebugUserValues: false
279 - { reg: '$r0', virtual-reg: '' }
281 isFrameAddressTaken: false
282 isReturnAddressTaken: false
293 cvBytesOfCalleeSavedRegisters: 0
294 hasOpaqueSPAdjustment: false
296 hasMustTailInVarArgFunc: false
303 - { id: 0, name: var, type: default, offset: 0, size: 4, alignment: 4,
304 stack-id: default, callee-saved-register: '', callee-saved-restored: true,
305 local-offset: -4, debug-info-variable: '', debug-info-expression: '',
306 debug-info-location: '' }
307 - { id: 1, name: dummy, type: default, offset: 0, size: 2048, alignment: 1,
308 stack-id: default, callee-saved-register: '', callee-saved-restored: true,
309 local-offset: -2052, debug-info-variable: '', debug-info-expression: '',
310 debug-info-location: '' }
313 debugValueSubstitutions: []
315 machineFunctionInfo: {}
318 successors: %bb.1(0x40000000)
321 ; CHECK-LABEL: name: test_live_out
322 ; CHECK-LABEL: bb.0.entry:
323 ; CHECK: tCMPi8 renamable $r0, 0, 14 /* CC::al */, $noreg, implicit-def $cpsr
324 ; CHECK-NEXT: $r2 = t2MRS_M 2048, 14 /* CC::al */, $noreg, implicit $cpsr
325 ; CHECK-NEXT: $r1 = tMOVi32imm 2048, implicit-def $cpsr
326 ; CHECK-NEXT: t2MSR_M 2048, killed $r2, 14 /* CC::al */, $noreg, implicit-def $cpsr
327 ; CHECK-NEXT: $r1 = tADDhirr $r1, killed $sp, 14 /* CC::al */, $noreg
328 ; CHECK-NEXT: tSTRi renamable $r0, killed $r1, 0, 14 /* CC::al */, $noreg :: (store (s32) into %ir.var)
330 tCMPi8 renamable $r0, 0, 14 /* CC::al */, $noreg, implicit-def $cpsr
331 tSTRspi renamable $r0, %stack.0.var, 0, 14 /* CC::al */, $noreg :: (store (s32) into %ir.var)
332 tB %bb.1, 14 /* CC::al */, $noreg
335 successors: %bb.2(0x40000000), %bb.3(0x40000000)
338 tBcc %bb.3, 5 /* CC::pl */, killed $cpsr
339 tB %bb.2, 14 /* CC::al */, $noreg
342 successors: %bb.3(0x80000000)
344 tB %bb.3, 14 /* CC::al */, $noreg
347 tBX_RET 14 /* CC::al */, $noreg
351 name: test_live_out_def_after_mov
353 exposesReturnsTwice: false
355 regBankSelected: false
358 tracksRegLiveness: true
361 callsUnwindInit: false
367 failsVerification: false
368 tracksDebugUserValues: false
371 - { reg: '$r0', virtual-reg: '' }
373 isFrameAddressTaken: false
374 isReturnAddressTaken: false
385 cvBytesOfCalleeSavedRegisters: 0
386 hasOpaqueSPAdjustment: false
388 hasMustTailInVarArgFunc: false
395 - { id: 0, name: var, type: default, offset: 0, size: 4, alignment: 4,
396 stack-id: default, callee-saved-register: '', callee-saved-restored: true,
397 local-offset: -4, debug-info-variable: '', debug-info-expression: '',
398 debug-info-location: '' }
399 - { id: 1, name: dummy, type: default, offset: 0, size: 2048, alignment: 1,
400 stack-id: default, callee-saved-register: '', callee-saved-restored: true,
401 local-offset: -2052, debug-info-variable: '', debug-info-expression: '',
402 debug-info-location: '' }
405 debugValueSubstitutions: []
407 machineFunctionInfo: {}
410 successors: %bb.1(0x40000000)
413 ; Here the live-out cpsr is defined after the tMOVi32imm, so cpsr doesn't
415 ; CHECK-LABEL: name: test_live_out
416 ; CHECK-LABEL: bb.0.entry:
417 ; CHECK: $r1 = tMOVi32imm 2048, implicit-def $cpsr
418 ; CHECK-NEXT: $r1 = tADDhirr $r1, killed $sp, 14 /* CC::al */, $noreg
419 ; CHECK-NEXT: tSTRi renamable $r0, killed $r1, 0, 14 /* CC::al */, $noreg :: (store (s32) into %ir.var)
420 ; CHECK-NEXT: tCMPi8 renamable $r0, 0, 14 /* CC::al */, $noreg, implicit-def $cpsr
422 tSTRspi renamable $r0, %stack.0.var, 0, 14 /* CC::al */, $noreg :: (store (s32) into %ir.var)
423 tCMPi8 renamable $r0, 0, 14 /* CC::al */, $noreg, implicit-def $cpsr
424 tB %bb.1, 14 /* CC::al */, $noreg
427 successors: %bb.2(0x40000000), %bb.3(0x40000000)
430 tBcc %bb.3, 5 /* CC::pl */, killed $cpsr
431 tB %bb.2, 14 /* CC::al */, $noreg
434 successors: %bb.3(0x80000000)
436 tB %bb.3, 14 /* CC::al */, $noreg
439 tBX_RET 14 /* CC::al */, $noreg