llvm.org GIT mirror llvm / f4523b0
ARM: avoid clobbering register in v6 jump-table expansion. If we got unlucky with register allocation and actual constpool placement, we could end up producing a tTBB_JT with an index that's already been clobbered. Technically, we might be able to fix this situation up with a MOV, but I think the constant islands pass is complex enough without having to deal with more weird edge-cases. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297871 91177308-0d34-0410-b5e6-96231b3b80d8 Tim Northover 3 years ago
6 changed file(s) with 399 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
380380 StringRef Name;
381381 unsigned Alignment = 0;
382382 bool ExposesReturnsTwice = false;
383 bool NoVRegs;
383384 // GISel MachineFunctionProperties.
384385 bool Legalized = false;
385386 bool RegBankSelected = false;
404405 YamlIO.mapRequired("name", MF.Name);
405406 YamlIO.mapOptional("alignment", MF.Alignment);
406407 YamlIO.mapOptional("exposesReturnsTwice", MF.ExposesReturnsTwice);
408 YamlIO.mapOptional("noVRegs", MF.NoVRegs);
407409 YamlIO.mapOptional("legalized", MF.Legalized);
408410 YamlIO.mapOptional("regBankSelected", MF.RegBankSelected);
409411 YamlIO.mapOptional("selected", MF.Selected);
331331 MF.setAlignment(YamlMF.Alignment);
332332 MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);
333333
334 if (YamlMF.NoVRegs)
335 MF.getProperties().set(MachineFunctionProperties::Property::NoVRegs);
334336 if (YamlMF.Legalized)
335337 MF.getProperties().set(MachineFunctionProperties::Property::Legalized);
336338 if (YamlMF.RegBankSelected)
174174 YamlMF.Alignment = MF.getAlignment();
175175 YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice();
176176
177 YamlMF.NoVRegs = MF.getProperties().hasProperty(
178 MachineFunctionProperties::Property::NoVRegs);
177179 YamlMF.Legalized = MF.getProperties().hasProperty(
178180 MachineFunctionProperties::Property::Legalized);
179181 YamlMF.RegBankSelected = MF.getProperties().hasProperty(
21032103 IdxReg = Shift->getOperand(2).getReg();
21042104 unsigned ShiftedIdxReg = Shift->getOperand(0).getReg();
21052105
2106 // It's important that IdxReg is live until the actual TBB/TBH. Most of
2107 // the range is checked later, but the LEA might still clobber it and not
2108 // actually get removed.
2109 if (BaseReg == IdxReg && !jumpTableFollowsTB(MI, User.CPEMI))
2110 continue;
2111
21062112 MachineInstr *Load = User.MI->getNextNode();
21072113 if (Load->getOpcode() != ARM::tLDRr)
21082114 continue;
21342140 // IdxReg gets redefined in the middle of the sequence.
21352141 continue;
21362142 }
2137
2143
21382144 // Now safe to delete the load and lsl. The LEA will be removed later.
21392145 CanDeleteLEA = true;
21402146 Shift->eraseFromParent();
21412147 Load->eraseFromParent();
21422148 DeadSize += 4;
21432149 }
2144
2150
21452151 DEBUG(dbgs() << "Shrink JT: " << *MI);
21462152 MachineInstr *CPEMI = User.CPEMI;
21472153 unsigned Opc = ByteOk ? ARM::t2TBB_JT : ARM::t2TBH_JT;
0 # RUN: llc -run-pass=arm-cp-islands -o - %s | FileCheck %s
1
2 # Test created by tweaking the register allocation after stopping the IR below
3 # just before constant islands. We were forwarding the table index to the end of
4 # the block, even though the LEA clobbered it.
5
6 # CHECK-LABEL: name: foo
7 # CHECK: tBR_JT
8 # This order is important. If the jump-table comes first then the
9 # transformation is valid because the LEA can be removed, see second test.
10 # CHECK: CONSTPOOL_ENTRY
11 # CHECK: JUMPTABLE_ADDRS
12
13 # CHECK-LABEL: name: bar
14 # CHECK: tTBB_JT %pc, killed %r1
15
16 --- |
17 ; ModuleID = 'simple.ll'
18 source_filename = "simple.ll"
19 target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
20 target triple = "thumbv6m-none--eabi"
21
22 define void @foo(i8 %in, i32* %addr) {
23 store i32 12345678, i32* %addr
24 %1 = call i32 @llvm.arm.space(i32 980, i32 undef)
25 %2 = zext i8 %in to i32
26 switch i32 %2, label %default [
27 i32 0, label %d1
28 i32 1, label %d2
29 i32 3, label %d3
30 i32 4, label %d4
31 i32 5, label %d5
32 i32 6, label %d6
33 i32 7, label %d7
34 i32 2, label %d8
35 i32 8, label %d9
36 i32 9, label %d10
37 i32 19, label %d11
38 i32 20, label %d12
39 i32 21, label %d13
40 i32 22, label %d14
41 i32 24, label %d15
42 i32 25, label %d16
43 i32 26, label %d17
44 ]
45
46 default: ; preds = %0
47 unreachable
48
49 d1: ; preds = %0
50 unreachable
51
52 d2: ; preds = %0
53 unreachable
54
55 d3: ; preds = %0
56 unreachable
57
58 d4: ; preds = %0
59 unreachable
60
61 d5: ; preds = %0
62 unreachable
63
64 d6: ; preds = %0
65 unreachable
66
67 d7: ; preds = %0
68 unreachable
69
70 d8: ; preds = %0
71 unreachable
72
73 d9: ; preds = %0
74 unreachable
75
76 d10: ; preds = %0
77 unreachable
78
79 d11: ; preds = %0
80 unreachable
81
82 d12: ; preds = %0
83 unreachable
84
85 d13: ; preds = %0
86 unreachable
87
88 d14: ; preds = %0
89 unreachable
90
91 d15: ; preds = %0
92 unreachable
93
94 d16: ; preds = %0
95 unreachable
96
97 d17: ; preds = %0
98 unreachable
99 }
100
101 define void @bar(i8 %in, i32* %addr) {
102 store i32 12345678, i32* %addr
103 %1 = zext i8 %in to i32
104 switch i32 %1, label %default [
105 i32 0, label %d1
106 i32 1, label %d2
107 i32 3, label %d3
108 i32 4, label %d4
109 i32 5, label %d5
110 i32 6, label %d6
111 i32 7, label %d7
112 i32 2, label %d8
113 i32 8, label %d9
114 i32 9, label %d10
115 i32 19, label %d11
116 i32 20, label %d12
117 i32 21, label %d13
118 i32 22, label %d14
119 i32 24, label %d15
120 i32 25, label %d16
121 i32 26, label %d17
122 ]
123
124 default: ; preds = %0
125 unreachable
126
127 d1: ; preds = %0
128 unreachable
129
130 d2: ; preds = %0
131 unreachable
132
133 d3: ; preds = %0
134 unreachable
135
136 d4: ; preds = %0
137 unreachable
138
139 d5: ; preds = %0
140 unreachable
141
142 d6: ; preds = %0
143 unreachable
144
145 d7: ; preds = %0
146 unreachable
147
148 d8: ; preds = %0
149 unreachable
150
151 d9: ; preds = %0
152 unreachable
153
154 d10: ; preds = %0
155 unreachable
156
157 d11: ; preds = %0
158 unreachable
159
160 d12: ; preds = %0
161 unreachable
162
163 d13: ; preds = %0
164 unreachable
165
166 d14: ; preds = %0
167 unreachable
168
169 d15: ; preds = %0
170 unreachable
171
172 d16: ; preds = %0
173 unreachable
174
175 d17: ; preds = %0
176 unreachable
177 }
178
179 ; Function Attrs: nounwind
180 declare i32 @llvm.arm.space(i32, i32) #0
181
182 ; Function Attrs: nounwind
183 declare void @llvm.stackprotector(i8*, i8**) #0
184
185 attributes #0 = { nounwind }
186
187 ...
188 ---
189 name: foo
190 alignment: 1
191 exposesReturnsTwice: false
192 noVRegs: true
193 legalized: false
194 regBankSelected: false
195 selected: false
196 tracksRegLiveness: true
197 liveins:
198 - { reg: '%r0' }
199 - { reg: '%r1' }
200 frameInfo:
201 isFrameAddressTaken: false
202 isReturnAddressTaken: false
203 hasStackMap: false
204 hasPatchPoint: false
205 stackSize: 0
206 offsetAdjustment: 0
207 maxAlignment: 0
208 adjustsStack: false
209 hasCalls: false
210 maxCallFrameSize: 0
211 hasOpaqueSPAdjustment: false
212 hasVAStart: false
213 hasMustTailInVarArgFunc: false
214 constants:
215 - id: 0
216 value: i32 12345678
217 alignment: 4
218 jumpTable:
219 kind: inline
220 entries:
221 - id: 0
222 blocks: [ '%bb.3.d2', '%bb.9.d8', '%bb.4.d3', '%bb.5.d4',
223 '%bb.6.d5', '%bb.7.d6', '%bb.8.d7', '%bb.10.d9',
224 '%bb.11.d10', '%bb.2.d1', '%bb.2.d1', '%bb.2.d1',
225 '%bb.2.d1', '%bb.2.d1', '%bb.2.d1', '%bb.2.d1',
226 '%bb.2.d1', '%bb.2.d1', '%bb.12.d11', '%bb.13.d12',
227 '%bb.14.d13', '%bb.15.d14', '%bb.2.d1', '%bb.16.d15',
228 '%bb.17.d16', '%bb.18.d17' ]
229 body: |
230 bb.0 (%ir-block.0):
231 successors: %bb.2.d1(0x03c3c3c4), %bb.1(0x7c3c3c3c)
232 liveins: %r0, %r1
233
234 %r2 = tLDRpci %const.0, 14, _
235 tSTRi killed %r2, killed %r1, 0, 14, _ :: (store 4 into %ir.addr)
236 dead %r1 = SPACE 980, undef %r0
237 %r0 = tUXTB killed %r0, 14, _
238 %r1, dead %cpsr = tSUBi3 killed %r0, 1, 14, _
239 tCMPi8 %r1, 25, 14, _, implicit-def %cpsr
240 tBcc %bb.2.d1, 8, killed %cpsr
241
242 bb.1 (%ir-block.0):
243 successors: %bb.3.d2(0x07c549d2), %bb.9.d8(0x07c549d2), %bb.4.d3(0x07c549d2), %bb.5.d4(0x07c549d2), %bb.6.d5(0x07c549d2), %bb.7.d6(0x07c549d2), %bb.8.d7(0x07c549d2), %bb.10.d9(0x07c549d2), %bb.11.d10(0x07c549d2), %bb.2.d1(0x03ab62db), %bb.12.d11(0x07c549d2), %bb.13.d12(0x07c549d2), %bb.14.d13(0x07c549d2), %bb.15.d14(0x07c549d2), %bb.16.d15(0x07c549d2), %bb.17.d16(0x07c549d2), %bb.18.d17(0x07c549d2)
244 liveins: %r1
245
246 %r0, dead %cpsr = tLSLri killed %r1, 2, 14, _
247 %r1 = tLEApcrelJT %jump-table.0, 14, _
248 %r0 = tLDRr killed %r0, killed %r1, 14, _ :: (load 4 from jump-table)
249 tBR_JTr killed %r0, %jump-table.0
250
251 bb.3.d2:
252
253 bb.9.d8:
254
255 bb.4.d3:
256
257 bb.5.d4:
258
259 bb.6.d5:
260
261 bb.7.d6:
262
263 bb.8.d7:
264
265 bb.10.d9:
266
267 bb.11.d10:
268
269 bb.2.d1:
270
271 bb.12.d11:
272
273 bb.13.d12:
274
275 bb.14.d13:
276
277 bb.15.d14:
278
279 bb.16.d15:
280
281 bb.17.d16:
282
283 bb.18.d17:
284
285 ...
286
287 ---
288 name: bar
289 alignment: 1
290 exposesReturnsTwice: false
291 noVRegs: true
292 legalized: false
293 regBankSelected: false
294 selected: false
295 tracksRegLiveness: true
296 liveins:
297 - { reg: '%r0' }
298 - { reg: '%r1' }
299 frameInfo:
300 isFrameAddressTaken: false
301 isReturnAddressTaken: false
302 hasStackMap: false
303 hasPatchPoint: false
304 stackSize: 0
305 offsetAdjustment: 0
306 maxAlignment: 0
307 adjustsStack: false
308 hasCalls: false
309 maxCallFrameSize: 0
310 hasOpaqueSPAdjustment: false
311 hasVAStart: false
312 hasMustTailInVarArgFunc: false
313 constants:
314 - id: 0
315 value: i32 12345678
316 alignment: 4
317 jumpTable:
318 kind: inline
319 entries:
320 - id: 0
321 blocks: [ '%bb.3.d2', '%bb.9.d8', '%bb.4.d3', '%bb.5.d4',
322 '%bb.6.d5', '%bb.7.d6', '%bb.8.d7', '%bb.10.d9',
323 '%bb.11.d10', '%bb.2.d1', '%bb.2.d1', '%bb.2.d1',
324 '%bb.2.d1', '%bb.2.d1', '%bb.2.d1', '%bb.2.d1',
325 '%bb.2.d1', '%bb.2.d1', '%bb.12.d11', '%bb.13.d12',
326 '%bb.14.d13', '%bb.15.d14', '%bb.2.d1', '%bb.16.d15',
327 '%bb.17.d16', '%bb.18.d17' ]
328 body: |
329 bb.0 (%ir-block.0):
330 successors: %bb.2.d1(0x03c3c3c4), %bb.1(0x7c3c3c3c)
331 liveins: %r0, %r1
332
333 %r2 = tLDRpci %const.0, 14, _
334 tSTRi killed %r2, killed %r1, 0, 14, _ :: (store 4 into %ir.addr)
335 %r0 = tUXTB killed %r0, 14, _
336 %r1, dead %cpsr = tSUBi3 killed %r0, 1, 14, _
337 tCMPi8 %r1, 25, 14, _, implicit-def %cpsr
338 tBcc %bb.2.d1, 8, killed %cpsr
339
340 bb.1 (%ir-block.0):
341 successors: %bb.3.d2(0x07c549d2), %bb.9.d8(0x07c549d2), %bb.4.d3(0x07c549d2), %bb.5.d4(0x07c549d2), %bb.6.d5(0x07c549d2), %bb.7.d6(0x07c549d2), %bb.8.d7(0x07c549d2), %bb.10.d9(0x07c549d2), %bb.11.d10(0x07c549d2), %bb.2.d1(0x03ab62db), %bb.12.d11(0x07c549d2), %bb.13.d12(0x07c549d2), %bb.14.d13(0x07c549d2), %bb.15.d14(0x07c549d2), %bb.16.d15(0x07c549d2), %bb.17.d16(0x07c549d2), %bb.18.d17(0x07c549d2)
342 liveins: %r1
343
344 %r0, dead %cpsr = tLSLri killed %r1, 2, 14, _
345 %r1 = tLEApcrelJT %jump-table.0, 14, _
346 %r0 = tLDRr killed %r0, killed %r1, 14, _ :: (load 4 from jump-table)
347 tBR_JTr killed %r0, %jump-table.0
348
349 bb.3.d2:
350
351 bb.9.d8:
352
353 bb.4.d3:
354
355 bb.5.d4:
356
357 bb.6.d5:
358
359 bb.7.d6:
360
361 bb.8.d7:
362
363 bb.10.d9:
364
365 bb.11.d10:
366
367 bb.2.d1:
368
369 bb.12.d11:
370
371 bb.13.d12:
372
373 bb.14.d13:
374
375 bb.15.d14:
376
377 bb.16.d15:
378
379 bb.17.d16:
380
381 bb.18.d17:
382
383 ...
44 ; CHECK-LABEL: name: test_void_return
55 ; CHECK: alignment: 4
66 ; CHECK-NEXT: exposesReturnsTwice: false
7 ; CHECK-NEXT: noVRegs: false
78 ; CHECK-NEXT: legalized: false
89 ; CHECK-NEXT: regBankSelected: false
910 ; CHECK-NEXT: selected: false