[ARM] MVE compare vector splat combine
[llvm-complete.git] / test / CodeGen / Thumb2 / LowOverheadLoops / end-positive-offset.mir
blob2712714c81b1f9e0aa7ded3d2c6af418a8348e6d
1 # RUN: llc -run-pass=arm-low-overhead-loops %s -verify-machineinstrs -o - | FileCheck %s
3 # CHECK-NOT: DoLoopStart
4 # CHECK-NOT: DLS
5 # CHECK: bb.2.for.body:
6 # CHECK:   t2CMPri $lr, 0, 14, $cpsr, implicit-def $cpsr
7 # CHECK:   t2Bcc %bb.4, 1, $cpsr
8 # CHECK:   tB %bb.3, 14, $noreg
9 # CHECK: bb.3.for.cond.cleanup:
10 # CHECK: bb.4.for.header:
12 --- |
13   target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
14   target triple = "thumbv8.1m.main-unknown-unknown"
15   
16   define void @size_limit(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %N) #0 {
17   entry:
18     call void @llvm.set.loop.iterations.i32(i32 %N)
19     br label %for.body.preheader
20   
21   for.body.preheader:                               ; preds = %entry
22     %scevgep = getelementptr i32, i32* %a, i32 -1
23     %scevgep4 = getelementptr i32, i32* %c, i32 -1
24     %scevgep8 = getelementptr i32, i32* %b, i32 -1
25     br label %for.header
26   
27   for.body:                                         ; preds = %for.header
28     %scevgep11 = getelementptr i32, i32* %lsr.iv9, i32 1
29     %ld1 = load i32, i32* %scevgep11, align 4
30     %scevgep7 = getelementptr i32, i32* %lsr.iv5, i32 1
31     %ld2 = load i32, i32* %scevgep7, align 4
32     %mul = mul nsw i32 %ld2, %ld1
33     %scevgep3 = getelementptr i32, i32* %lsr.iv1, i32 1
34     store i32 %mul, i32* %scevgep3, align 4
35     %scevgep2 = getelementptr i32, i32* %lsr.iv1, i32 1
36     %scevgep6 = getelementptr i32, i32* %lsr.iv5, i32 1
37     %scevgep10 = getelementptr i32, i32* %lsr.iv9, i32 1
38     %count.next = call i32 @llvm.loop.decrement.reg.i32.i32.i32(i32 %count, i32 1)
39     %cmp = icmp ne i32 %count.next, 0
40     br i1 %cmp, label %for.cond.cleanup, label %for.header
41   
42   for.cond.cleanup:                                 ; preds = %for.body
43     ret void
44   
45   for.header:                                       ; preds = %for.body, %for.body.preheader
46     %lsr.iv9 = phi i32* [ %scevgep8, %for.body.preheader ], [ %scevgep10, %for.body ]
47     %lsr.iv5 = phi i32* [ %scevgep4, %for.body.preheader ], [ %scevgep6, %for.body ]
48     %lsr.iv1 = phi i32* [ %scevgep, %for.body.preheader ], [ %scevgep2, %for.body ]
49     %count = phi i32 [ %N, %for.body.preheader ], [ %count.next, %for.body ]
50     br label %for.body
51   }
52   
53   ; Function Attrs: nounwind
54   declare i32 @llvm.arm.space(i32, i32) #1
55   
56   ; Function Attrs: noduplicate nounwind
57   declare void @llvm.set.loop.iterations.i32(i32) #2
58   
59   ; Function Attrs: noduplicate nounwind
60   declare i32 @llvm.loop.decrement.reg.i32.i32.i32(i32, i32) #2
61   
62   ; Function Attrs: nounwind
63   declare void @llvm.stackprotector(i8*, i8**) #3
64   
65   attributes #0 = { "target-features"="+lob" }
66   attributes #1 = { nounwind "target-features"="+lob" }
67   attributes #2 = { noduplicate nounwind "target-features"="+lob" }
68   attributes #3 = { nounwind }
70 ...
71 ---
72 name:            size_limit
73 alignment:       1
74 exposesReturnsTwice: false
75 legalized:       false
76 regBankSelected: false
77 selected:        false
78 failedISel:      false
79 tracksRegLiveness: false
80 hasWinCFI:       false
81 registers:       []
82 liveins:         
83   - { reg: '$r0', virtual-reg: '' }
84   - { reg: '$r1', virtual-reg: '' }
85   - { reg: '$r2', virtual-reg: '' }
86   - { reg: '$r3', virtual-reg: '' }
87 frameInfo:       
88   isFrameAddressTaken: false
89   isReturnAddressTaken: false
90   hasStackMap:     false
91   hasPatchPoint:   false
92   stackSize:       56
93   offsetAdjustment: 0
94   maxAlignment:    4
95   adjustsStack:    false
96   hasCalls:        false
97   stackProtector:  ''
98   maxCallFrameSize: 0
99   cvBytesOfCalleeSavedRegisters: 0
100   hasOpaqueSPAdjustment: false
101   hasVAStart:      false
102   hasMustTailInVarArgFunc: false
103   localFrameSize:  0
104   savePoint:       ''
105   restorePoint:    ''
106 fixedStack:      []
107 stack:           
108   - { id: 0, name: '', type: spill-slot, offset: -12, size: 4, alignment: 4, 
109       stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
110       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
111   - { id: 1, name: '', type: spill-slot, offset: -16, size: 4, alignment: 4, 
112       stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
113       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
114   - { id: 2, name: '', type: spill-slot, offset: -20, size: 4, alignment: 4, 
115       stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
116       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
117   - { id: 3, name: '', type: spill-slot, offset: -24, size: 4, alignment: 4, 
118       stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
119       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
120   - { id: 4, name: '', type: spill-slot, offset: -28, size: 4, alignment: 4, 
121       stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
122       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
123   - { id: 5, name: '', type: spill-slot, offset: -32, size: 4, alignment: 4, 
124       stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
125       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
126   - { id: 6, name: '', type: spill-slot, offset: -36, size: 4, alignment: 4, 
127       stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
128       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
129   - { id: 7, name: '', type: spill-slot, offset: -40, size: 4, alignment: 4, 
130       stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
131       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
132   - { id: 8, name: '', type: spill-slot, offset: -44, size: 4, alignment: 4, 
133       stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
134       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
135   - { id: 9, name: '', type: spill-slot, offset: -48, size: 4, alignment: 4, 
136       stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
137       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
138   - { id: 10, name: '', type: spill-slot, offset: -52, size: 4, alignment: 4, 
139       stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
140       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
141   - { id: 11, name: '', type: spill-slot, offset: -56, size: 4, alignment: 4, 
142       stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
143       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
144   - { id: 12, name: '', type: spill-slot, offset: -4, size: 4, alignment: 4, 
145       stack-id: default, callee-saved-register: '$lr', callee-saved-restored: false, 
146       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
147   - { id: 13, name: '', type: spill-slot, offset: -8, size: 4, alignment: 4, 
148       stack-id: default, callee-saved-register: '$r4', callee-saved-restored: true, 
149       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
150 callSites:       []
151 constants:       []
152 machineFunctionInfo: {}
153 body:             |
154   bb.0.entry:
155     successors: %bb.1(0x80000000)
156   
157     frame-setup tPUSH 14, $noreg, killed $r4, killed $lr, implicit-def $sp, implicit $sp
158     frame-setup CFI_INSTRUCTION def_cfa_offset 8
159     frame-setup CFI_INSTRUCTION offset $lr, -4
160     frame-setup CFI_INSTRUCTION offset $r4, -8
161     $sp = frame-setup tSUBspi $sp, 12, 14, $noreg
162     frame-setup CFI_INSTRUCTION def_cfa_offset 56
163     t2DoLoopStart renamable $r3
164     tSTRspi killed $r3, $sp, 11, 14, $noreg :: (store 4 into %stack.0)
165     tSTRspi killed $r2, $sp, 10, 14, $noreg :: (store 4 into %stack.1)
166     tSTRspi killed $r1, $sp, 9, 14, $noreg :: (store 4 into %stack.2)
167     tSTRspi killed $r0, $sp, 8, 14, $noreg :: (store 4 into %stack.3)
168     tB %bb.1, 14, $noreg
169   
170   bb.1.for.body.preheader:
171     successors: %bb.4(0x80000000)
172   
173     $r0 = tLDRspi $sp, 8, 14, $noreg :: (load 4 from %stack.3)
174     renamable $r1, dead $cpsr = tSUBi3 killed renamable $r0, 4, 14, $noreg
175     $r2 = tLDRspi $sp, 10, 14, $noreg :: (load 4 from %stack.1)
176     renamable $r3, dead $cpsr = tSUBi3 killed renamable $r2, 4, 14, $noreg
177     $r12 = t2LDRi12 $sp, 36, 14, $noreg :: (load 4 from %stack.2)
178     renamable $lr = t2SUBri killed renamable $r12, 4, 14, $noreg, $noreg
179     $r4 = tLDRspi $sp, 11, 14, $noreg :: (load 4 from %stack.0)
180     t2STRi12 killed $lr, $sp, 28, 14, $noreg :: (store 4 into %stack.4)
181     tSTRspi killed $r3, $sp, 6, 14, $noreg :: (store 4 into %stack.5)
182     tSTRspi killed $r1, $sp, 5, 14, $noreg :: (store 4 into %stack.6)
183     tSTRspi killed $r4, $sp, 4, 14, $noreg :: (store 4 into %stack.7)
184     tB %bb.4, 14, $noreg
185   
186   bb.2.for.body:
187     successors: %bb.3(0x40000000), %bb.4(0x40000000)
188   
189     $r0 = tLDRspi $sp, 3, 14, $noreg :: (load 4 from %stack.8)
190     renamable $r1, renamable $r0 = t2LDR_PRE renamable $r0, 4, 14, $noreg :: (load 4 from %ir.scevgep11)
191     $r2 = tLDRspi $sp, 2, 14, $noreg :: (load 4 from %stack.9)
192     renamable $r3, renamable $r2 = t2LDR_PRE renamable $r2, 4, 14, $noreg :: (load 4 from %ir.scevgep7)
193     renamable $r1, dead $cpsr = nsw tMUL killed renamable $r3, killed renamable $r1, 14, $noreg
194     $r3 = tLDRspi $sp, 1, 14, $noreg :: (load 4 from %stack.10)
195     early-clobber renamable $r3 = t2STR_PRE killed renamable $r1, renamable $r3, 4, 14, $noreg :: (store 4 into %ir.scevgep3)
196     $r1 = tLDRspi $sp, 0, 14, $noreg :: (load 4 from %stack.11)
197     $lr = tMOVr killed $r1, 14, $noreg
198     renamable $lr = t2LoopDec killed renamable $lr, 1
199     $r12 = tMOVr $lr, 14, $noreg
200     tSTRspi killed $r0, $sp, 7, 14, $noreg :: (store 4 into %stack.4)
201     tSTRspi killed $r2, $sp, 6, 14, $noreg :: (store 4 into %stack.5)
202     tSTRspi killed $r3, $sp, 5, 14, $noreg :: (store 4 into %stack.6)
203     t2STRi12 killed $r12, $sp, 16, 14, $noreg :: (store 4 into %stack.7)
204     t2LoopEnd killed renamable $lr, %bb.4
205     tB %bb.3, 14, $noreg
206   
207   bb.3.for.cond.cleanup:
208     $sp = tADDspi $sp, 12, 14, $noreg
209     tPOP_RET 14, $noreg, def $r4, def $pc
210   
211   bb.4.for.header:
212     successors: %bb.2(0x80000000)
213   
214     $r0 = tLDRspi $sp, 4, 14, $noreg :: (load 4 from %stack.7)
215     $r1 = tLDRspi $sp, 5, 14, $noreg :: (load 4 from %stack.6)
216     $r2 = tLDRspi $sp, 6, 14, $noreg :: (load 4 from %stack.5)
217     $r3 = tLDRspi $sp, 7, 14, $noreg :: (load 4 from %stack.4)
218     tSTRspi killed $r0, $sp, 0, 14, $noreg :: (store 4 into %stack.11)
219     tSTRspi killed $r1, $sp, 1, 14, $noreg :: (store 4 into %stack.10)
220     tSTRspi killed $r2, $sp, 2, 14, $noreg :: (store 4 into %stack.9)
221     tSTRspi killed $r3, $sp, 3, 14, $noreg :: (store 4 into %stack.8)
222     tB %bb.2, 14, $noreg