Skip to content

Commit edfdce2

Browse files
committed
[PHIElimination] Fix accounting for undef uses when updating LiveVariables
PHI elimination updates LiveVariables info as described here: // We only need to update the LiveVariables kill of SrcReg if this was the // last PHI use of SrcReg to be lowered on this CFG edge and it is not live // out of the predecessor. We can also ignore undef sources. Unfortunately if the last use also happened to be an undef use then it would fail to update the LiveVariables at all. Fix this by not counting undef uses in the VRegPHIUse map. Thanks to Mikael Holmén for the test case! Differential Revision: https://reviews.llvm.org/D111552
1 parent 2e1ad93 commit edfdce2

File tree

2 files changed

+114
-7
lines changed

2 files changed

+114
-7
lines changed

llvm/lib/CodeGen/PHIElimination.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ namespace {
107107
using BBVRegPair = std::pair<unsigned, Register>;
108108
using VRegPHIUse = DenseMap<BBVRegPair, unsigned>;
109109

110+
// Count the number of non-undef PHI uses of each register in each BB.
110111
VRegPHIUse VRegPHIUseCount;
111112

112113
// Defs of PHI sources which are implicit_def.
@@ -426,9 +427,13 @@ void PHIElimination::LowerPHINode(MachineBasicBlock &MBB,
426427
}
427428

428429
// Adjust the VRegPHIUseCount map to account for the removal of this PHI node.
429-
for (unsigned i = 1; i != MPhi->getNumOperands(); i += 2)
430-
--VRegPHIUseCount[BBVRegPair(MPhi->getOperand(i+1).getMBB()->getNumber(),
431-
MPhi->getOperand(i).getReg())];
430+
for (unsigned i = 1; i != MPhi->getNumOperands(); i += 2) {
431+
if (!MPhi->getOperand(i).isUndef()) {
432+
--VRegPHIUseCount[BBVRegPair(
433+
MPhi->getOperand(i + 1).getMBB()->getNumber(),
434+
MPhi->getOperand(i).getReg())];
435+
}
436+
}
432437

433438
// Now loop over all of the incoming arguments, changing them to copy into the
434439
// IncomingReg register in the corresponding predecessor basic block.
@@ -630,14 +635,19 @@ void PHIElimination::LowerPHINode(MachineBasicBlock &MBB,
630635
/// used in a PHI node. We map that to the BB the vreg is coming from. This is
631636
/// used later to determine when the vreg is killed in the BB.
632637
void PHIElimination::analyzePHINodes(const MachineFunction& MF) {
633-
for (const auto &MBB : MF)
638+
for (const auto &MBB : MF) {
634639
for (const auto &BBI : MBB) {
635640
if (!BBI.isPHI())
636641
break;
637-
for (unsigned i = 1, e = BBI.getNumOperands(); i != e; i += 2)
638-
++VRegPHIUseCount[BBVRegPair(BBI.getOperand(i+1).getMBB()->getNumber(),
639-
BBI.getOperand(i).getReg())];
642+
for (unsigned i = 1, e = BBI.getNumOperands(); i != e; i += 2) {
643+
if (!BBI.getOperand(i).isUndef()) {
644+
++VRegPHIUseCount[BBVRegPair(
645+
BBI.getOperand(i + 1).getMBB()->getNumber(),
646+
BBI.getOperand(i).getReg())];
647+
}
648+
}
640649
}
650+
}
641651
}
642652

643653
bool PHIElimination::SplitPHIEdges(MachineFunction &MF,
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
# RUN: llc -mtriple=x86_64-- -verify-machineinstrs -o - %s -run-pass=livevars,phi-node-elimination,twoaddressinstruction | FileCheck %s
3+
4+
--- |
5+
@b114 = external global i16, align 1
6+
7+
define void @f245() {
8+
entry:
9+
unreachable
10+
}
11+
...
12+
---
13+
name: f245
14+
tracksRegLiveness: true
15+
body: |
16+
; CHECK-LABEL: name: f245
17+
; CHECK: bb.0:
18+
; CHECK-NEXT: successors: %bb.5(0x40000000), %bb.1(0x40000000)
19+
; CHECK-NEXT: {{ $}}
20+
; CHECK-NEXT: [[MOV64rm:%[0-9]+]]:gr64 = MOV64rm $rip, 1, $noreg, target-flags(x86-gotpcrel) @b114, $noreg
21+
; CHECK-NEXT: [[MOV16rm:%[0-9]+]]:gr16 = MOV16rm killed [[MOV64rm]], 1, $noreg, 0, $noreg :: (load (s16) from @b114, align 1)
22+
; CHECK-NEXT: TEST8ri undef %2:gr8, 1, implicit-def $eflags
23+
; CHECK-NEXT: JCC_1 %bb.5, 5, implicit killed $eflags
24+
; CHECK-NEXT: {{ $}}
25+
; CHECK-NEXT: bb.1:
26+
; CHECK-NEXT: successors: %bb.2(0x80000000)
27+
; CHECK-NEXT: {{ $}}
28+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr16 = COPY killed [[MOV16rm]]
29+
; CHECK-NEXT: JMP_1 %bb.2
30+
; CHECK-NEXT: {{ $}}
31+
; CHECK-NEXT: bb.2:
32+
; CHECK-NEXT: successors: %bb.4(0x40000000), %bb.3(0x40000000)
33+
; CHECK-NEXT: {{ $}}
34+
; CHECK-NEXT: dead %5:gr16 = IMPLICIT_DEF
35+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr16 = COPY killed [[COPY]]
36+
; CHECK-NEXT: TEST8ri undef %7:gr8, 1, implicit-def $eflags
37+
; CHECK-NEXT: JCC_1 %bb.4, 5, implicit killed $eflags
38+
; CHECK-NEXT: JMP_1 %bb.3
39+
; CHECK-NEXT: {{ $}}
40+
; CHECK-NEXT: bb.3:
41+
; CHECK-NEXT: successors: %bb.6(0x40000000), %bb.4(0x40000000)
42+
; CHECK-NEXT: {{ $}}
43+
; CHECK-NEXT: [[MOV32r0_:%[0-9]+]]:gr32 = MOV32r0 implicit-def dead $eflags
44+
; CHECK-NEXT: dead %9:gr16 = COPY killed [[MOV32r0_]].sub_16bit
45+
; CHECK-NEXT: CMP16ri8 killed [[COPY1]], 0, implicit-def $eflags
46+
; CHECK-NEXT: JCC_1 %bb.6, 5, implicit killed $eflags
47+
; CHECK-NEXT: {{ $}}
48+
; CHECK-NEXT: bb.4:
49+
; CHECK-NEXT: successors: %bb.2(0x80000000)
50+
; CHECK-NEXT: {{ $}}
51+
; CHECK-NEXT: [[DEF:%[0-9]+]]:gr16 = IMPLICIT_DEF
52+
; CHECK-NEXT: JMP_1 %bb.2
53+
; CHECK-NEXT: {{ $}}
54+
; CHECK-NEXT: bb.5:
55+
; CHECK-NEXT: RETQ
56+
; CHECK-NEXT: {{ $}}
57+
; CHECK-NEXT: bb.6:
58+
bb.0:
59+
successors: %bb.6(0x40000000), %bb.1(0x40000000)
60+
61+
%5:gr64 = MOV64rm $rip, 1, $noreg, target-flags(x86-gotpcrel) @b114, $noreg
62+
%6:gr16 = MOV16rm killed %5, 1, $noreg, 0, $noreg :: (load (s16) from @b114, align 1)
63+
TEST8ri undef %4:gr8, 1, implicit-def $eflags
64+
JCC_1 %bb.6, 5, implicit killed $eflags
65+
66+
bb.1:
67+
successors: %bb.2(0x80000000)
68+
69+
JMP_1 %bb.2
70+
71+
bb.2:
72+
successors: %bb.5(0x40000000), %bb.4(0x40000000)
73+
74+
%1:gr16 = PHI %6, %bb.1, undef %10:gr16, %bb.5
75+
dead %2:gr16 = PHI undef %6, %bb.1, undef %3:gr16, %bb.5
76+
TEST8ri undef %7:gr8, 1, implicit-def $eflags
77+
JCC_1 %bb.5, 5, implicit killed $eflags
78+
JMP_1 %bb.4
79+
80+
bb.4:
81+
successors: %bb.7(0x40000000), %bb.5(0x40000000)
82+
83+
%8:gr32 = MOV32r0 implicit-def dead $eflags
84+
%9:gr16 = COPY killed %8.sub_16bit
85+
CMP16ri8 killed %1, 0, implicit-def $eflags
86+
JCC_1 %bb.7, 5, implicit killed $eflags
87+
88+
bb.5:
89+
successors: %bb.2(0x80000000)
90+
91+
JMP_1 %bb.2
92+
93+
bb.6:
94+
RETQ
95+
96+
bb.7:
97+
...

0 commit comments

Comments
 (0)