llvm.org GIT mirror llvm / a4025df
Fix PR5614: parts of a physical register def may be killed the rest. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@90180 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 10 years ago
3 changed file(s) with 95 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
162162 SmallVector &Defs);
163163 void UpdatePhysRegDefs(MachineInstr *MI, SmallVector &Defs);
164164
165 /// FindLastPartialDef - Return the last partial def of the specified register.
166 /// Also returns the sub-registers that're defined by the instruction.
165 /// FindLastRefOrPartRef - Return the last reference or partial reference of
166 /// the specified register.
167 MachineInstr *FindLastRefOrPartRef(unsigned Reg);
168
169 /// FindLastPartialDef - Return the last partial def of the specified
170 /// register. Also returns the sub-registers that're defined by the
171 /// instruction.
167172 MachineInstr *FindLastPartialDef(unsigned Reg,
168173 SmallSet &PartDefRegs);
169174
278278 PhysRegUse[SubReg] = MI;
279279 }
280280
281 /// FindLastRefOrPartRef - Return the last reference or partial reference of
282 /// the specified register.
283 MachineInstr *LiveVariables::FindLastRefOrPartRef(unsigned Reg) {
284 MachineInstr *LastDef = PhysRegDef[Reg];
285 MachineInstr *LastUse = PhysRegUse[Reg];
286 if (!LastDef && !LastUse)
287 return false;
288
289 MachineInstr *LastRefOrPartRef = LastUse ? LastUse : LastDef;
290 unsigned LastRefOrPartRefDist = DistanceMap[LastRefOrPartRef];
291 MachineInstr *LastPartDef = 0;
292 unsigned LastPartDefDist = 0;
293 for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
294 unsigned SubReg = *SubRegs; ++SubRegs) {
295 MachineInstr *Def = PhysRegDef[SubReg];
296 if (Def && Def != LastDef) {
297 // There was a def of this sub-register in between. This is a partial
298 // def, keep track of the last one.
299 unsigned Dist = DistanceMap[Def];
300 if (Dist > LastPartDefDist) {
301 LastPartDefDist = Dist;
302 LastPartDef = Def;
303 }
304 continue;
305 }
306 if (MachineInstr *Use = PhysRegUse[SubReg]) {
307 unsigned Dist = DistanceMap[Use];
308 if (Dist > LastRefOrPartRefDist) {
309 LastRefOrPartRefDist = Dist;
310 LastRefOrPartRef = Use;
311 }
312 }
313 }
314
315 return LastRefOrPartRef;
316 }
317
281318 bool LiveVariables::HandlePhysRegKill(unsigned Reg, MachineInstr *MI) {
282319 MachineInstr *LastDef = PhysRegDef[Reg];
283320 MachineInstr *LastUse = PhysRegUse[Reg];
372409 if (NeedDef)
373410 PhysRegDef[Reg]->addOperand(MachineOperand::CreateReg(SubReg,
374411 true/*IsDef*/, true/*IsImp*/));
375 LastRefOrPartRef->addRegisterKilled(SubReg, TRI, true);
412 MachineInstr *LastSubRef = FindLastRefOrPartRef(SubReg);
413 if (LastSubRef)
414 LastSubRef->addRegisterKilled(SubReg, TRI, true);
415 else {
416 LastRefOrPartRef->addRegisterKilled(SubReg, TRI, true);
417 PhysRegUse[SubReg] = LastRefOrPartRef;
418 for (const unsigned *SSRegs = TRI->getSubRegisters(SubReg);
419 unsigned SSReg = *SSRegs; ++SSRegs)
420 PhysRegUse[SSReg] = LastRefOrPartRef;
421 }
376422 for (const unsigned *SS = TRI->getSubRegisters(SubReg); *SS; ++SS)
377423 PartUses.erase(*SS);
378424 }
0 ; RUN: llc -mtriple=armv7-eabi -mcpu=cortex-a8 < %s
1 ; PR5614
2
3 %"als" = type { i32 (...)** }
4 %"av" = type { %"als" }
5 %"c" = type { %"lsm", %"Vec3", %"av"*, float, i8, float, %"lsm", i8, %"Vec3", %"Vec3", %"Vec3", float, float, float, %"Vec3", %"Vec3" }
6 %"lsm" = type { %"als", %"Vec3", %"Vec3", %"Vec3", %"Vec3" }
7 %"Vec3" = type { float, float, float }
8
9 define arm_aapcs_vfpcc void @foo(%"c"* %this, %"Vec3"* nocapture %adjustment) {
10 entry:
11 switch i32 undef, label %return [
12 i32 1, label %bb
13 i32 2, label %bb72
14 i32 3, label %bb31
15 i32 4, label %bb79
16 i32 5, label %bb104
17 ]
18
19 bb: ; preds = %entry
20 ret void
21
22 bb31: ; preds = %entry
23 %0 = call arm_aapcs_vfpcc %"Vec3" undef(%"lsm"* undef) ; <%"Vec3"> [#uses=1]
24 %mrv_gr69 = extractvalue %"Vec3" %0, 1 ; [#uses=1]
25 %1 = fsub float %mrv_gr69, undef ; [#uses=1]
26 store float %1, float* undef, align 4
27 ret void
28
29 bb72: ; preds = %entry
30 ret void
31
32 bb79: ; preds = %entry
33 ret void
34
35 bb104: ; preds = %entry
36 ret void
37
38 return: ; preds = %entry
39 ret void
40 }