llvm.org GIT mirror llvm / bfe8afa
After r147827 and r147902, it's now possible for unallocatable registers to be live across BBs before register allocation. This miscompiled 197.parser when a cmp + b are optimized to a cbnz instruction even though the CPSR def is live-in a successor. cbnz r6, LBB89_12 ... LBB89_12: ble LBB89_1 The fix consists of two parts. 1) Teach LiveVariables that some unallocatable registers might be liveouts so don't mark their last use as kill if they are. 2) ARM constantpool island pass shouldn't form cbz / cbnz if the conditional branch does not kill CPSR. rdar://10676853 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148168 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 8 years ago
3 changed file(s) with 130 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
260260 Processed.insert(*SS);
261261 }
262262 }
263 }
264 else if (LastDef && !PhysRegUse[Reg] &&
265 !LastDef->findRegisterDefOperand(Reg))
263 } else if (LastDef && !PhysRegUse[Reg] &&
264 !LastDef->findRegisterDefOperand(Reg))
266265 // Last def defines the super register, add an implicit def of reg.
267 LastDef->addOperand(MachineOperand::CreateReg(Reg,
268 true/*IsDef*/, true/*IsImp*/));
266 LastDef->addOperand(MachineOperand::CreateReg(Reg, true/*IsDef*/,
267 true/*IsImp*/));
269268
270269 // Remember this use.
271270 PhysRegUse[Reg] = MI;
606605 }
607606 }
608607
608 // MachineCSE may CSE instructions which write to non-allocatable physical
609 // registers across MBBs. Remember if any reserved register is liveout.
610 SmallSet LiveOuts;
611 for (MachineBasicBlock::const_succ_iterator SI = MBB->succ_begin(),
612 SE = MBB->succ_end(); SI != SE; ++SI) {
613 MachineBasicBlock *SuccMBB = *SI;
614 if (SuccMBB->isLandingPad())
615 continue;
616 for (MachineBasicBlock::livein_iterator LI = SuccMBB->livein_begin(),
617 LE = SuccMBB->livein_end(); LI != LE; ++LI) {
618 unsigned LReg = *LI;
619 if (!TRI->isInAllocatableClass(LReg))
620 // Ignore other live-ins, e.g. those that are live into landing pads.
621 LiveOuts.insert(LReg);
622 }
623 }
624
609625 // Loop over PhysRegDef / PhysRegUse, killing any registers that are
610626 // available at the end of the basic block.
611627 for (unsigned i = 0; i != NumRegs; ++i)
612 if (PhysRegDef[i] || PhysRegUse[i])
628 if ((PhysRegDef[i] || PhysRegUse[i]) && !LiveOuts.count(i))
613629 HandlePhysRegDef(i, 0, Defs);
614630
615631 std::fill(PhysRegDef, PhysRegDef + NumRegs, (MachineInstr*)0);
17901790 if (Opcode != ARM::tBcc)
17911791 continue;
17921792
1793 // If the conditional branch doesn't kill CPSR, then CPSR can be liveout
1794 // so this transformation is not safe.
1795 if (!Br.MI->killsRegister(ARM::CPSR))
1796 continue;
1797
17931798 NewOpc = 0;
17941799 unsigned PredReg = 0;
17951800 ARMCC::CondCodes Pred = llvm::getInstrPredicate(Br.MI, PredReg);
0 ; RUN: llc < %s -mtriple=thumbv7-apple-ios -relocation-model=pic -disable-fp-elim -mcpu=cortex-a8 | FileCheck %s
1 ; rdar://10676853
2
3 %struct.Dict_node_struct = type { i8*, %struct.Word_file_struct*, %struct.Exp_struct*, %struct.Dict_node_struct*, %struct.Dict_node_struct* }
4 %struct.Word_file_struct = type { [60 x i8], i32, %struct.Word_file_struct* }
5 %struct.Exp_struct = type { i8, i8, i8, i8, %union.anon }
6 %union.anon = type { %struct.E_list_struct* }
7 %struct.E_list_struct = type { %struct.E_list_struct*, %struct.Exp_struct* }
8
9 @lookup_list = external hidden unnamed_addr global %struct.Dict_node_struct*, align 4
10
11 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
12
13 define hidden fastcc void @rdictionary_lookup(%struct.Dict_node_struct* %dn, i8* nocapture %s) nounwind ssp {
14 ; CHECK: rdictionary_lookup:
15 entry:
16 br label %tailrecurse
17
18 tailrecurse: ; preds = %if.then10, %entry
19 %dn.tr = phi %struct.Dict_node_struct* [ %dn, %entry ], [ %9, %if.then10 ]
20 %cmp = icmp eq %struct.Dict_node_struct* %dn.tr, null
21 br i1 %cmp, label %if.end11, label %if.end
22
23 if.end: ; preds = %tailrecurse
24 %string = getelementptr inbounds %struct.Dict_node_struct* %dn.tr, i32 0, i32 0
25 %0 = load i8** %string, align 4
26 br label %while.cond.i
27
28 while.cond.i: ; preds = %while.body.i, %if.end
29 %1 = phi i8* [ %s, %if.end ], [ %incdec.ptr.i, %while.body.i ]
30 %storemerge.i = phi i8* [ %0, %if.end ], [ %incdec.ptr6.i, %while.body.i ]
31 %2 = load i8* %1, align 1
32 %cmp.i = icmp eq i8 %2, 0
33 %.pre.i = load i8* %storemerge.i, align 1
34 br i1 %cmp.i, label %lor.lhs.false.i, label %land.end.i
35
36 land.end.i: ; preds = %while.cond.i
37 %cmp4.i = icmp eq i8 %2, %.pre.i
38 br i1 %cmp4.i, label %while.body.i, label %while.end.i
39
40 while.body.i: ; preds = %land.end.i
41 %incdec.ptr.i = getelementptr inbounds i8* %1, i32 1
42 %incdec.ptr6.i = getelementptr inbounds i8* %storemerge.i, i32 1
43 br label %while.cond.i
44
45 while.end.i: ; preds = %land.end.i
46 %cmp8.i = icmp eq i8 %2, 42
47 br i1 %cmp8.i, label %if.end3, label %lor.lhs.false.i
48
49 lor.lhs.false.i: ; preds = %while.end.i, %while.cond.i
50 %3 = phi i8 [ %2, %while.end.i ], [ 0, %while.cond.i ]
51 %cmp11.i = icmp eq i8 %.pre.i, 42
52 br i1 %cmp11.i, label %if.end3, label %dict_match.exit
53
54 dict_match.exit: ; preds = %lor.lhs.false.i
55 %cmp14.i = icmp eq i8 %3, 46
56 %conv16.i = sext i8 %3 to i32
57 %.conv16.i = select i1 %cmp14.i, i32 0, i32 %conv16.i
58 %cmp18.i = icmp eq i8 %.pre.i, 46
59 %conv22.i = sext i8 %.pre.i to i32
60 %cond24.i = select i1 %cmp18.i, i32 0, i32 %conv22.i
61 %sub.i = sub nsw i32 %.conv16.i, %cond24.i
62 %cmp1 = icmp sgt i32 %sub.i, -1
63 br i1 %cmp1, label %if.end3, label %if.then10
64
65 if.end3: ; preds = %dict_match.exit, %lor.lhs.false.i, %while.end.i
66 ; CHECK: %if.end3
67 ; CHECK: cmp
68 ; CHECK-NOT: cbnz
69 %storemerge1.i3 = phi i32 [ %sub.i, %dict_match.exit ], [ 0, %lor.lhs.false.i ], [ 0, %while.end.i ]
70 %right = getelementptr inbounds %struct.Dict_node_struct* %dn.tr, i32 0, i32 4
71 %4 = load %struct.Dict_node_struct** %right, align 4
72 tail call fastcc void @rdictionary_lookup(%struct.Dict_node_struct* %4, i8* %s)
73 %cmp4 = icmp eq i32 %storemerge1.i3, 0
74 br i1 %cmp4, label %if.then5, label %if.end8
75
76 if.then5: ; preds = %if.end3
77 %call6 = tail call fastcc i8* @xalloc(i32 20)
78 %5 = bitcast i8* %call6 to %struct.Dict_node_struct*
79 %6 = bitcast %struct.Dict_node_struct* %dn.tr to i8*
80 tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %call6, i8* %6, i32 16, i32 4, i1 false)
81 %7 = load %struct.Dict_node_struct** @lookup_list, align 4
82 %right7 = getelementptr inbounds i8* %call6, i32 16
83 %8 = bitcast i8* %right7 to %struct.Dict_node_struct**
84 store %struct.Dict_node_struct* %7, %struct.Dict_node_struct** %8, align 4
85 store %struct.Dict_node_struct* %5, %struct.Dict_node_struct** @lookup_list, align 4
86 br label %if.then10
87
88 if.end8: ; preds = %if.end3
89 %cmp9 = icmp slt i32 %storemerge1.i3, 1
90 br i1 %cmp9, label %if.then10, label %if.end11
91
92 if.then10: ; preds = %if.end8, %if.then5, %dict_match.exit
93 %left = getelementptr inbounds %struct.Dict_node_struct* %dn.tr, i32 0, i32 3
94 %9 = load %struct.Dict_node_struct** %left, align 4
95 br label %tailrecurse
96
97 if.end11: ; preds = %if.end8, %tailrecurse
98 ret void
99 }
100
101 ; Materializable
102 declare hidden fastcc i8* @xalloc(i32) nounwind ssp