Skip to content

Commit b28eebf

Browse files
authored
[RDF] Fix cover check when linking refs to defs (#113888)
During RDF graph construction, linkRefUp method links a register ref to its upward reaching defs until all RegUnits of the ref have been covered by defs. However, when a sub-register def covers some, but not all, of the RegUnits of a previous super-register def, a super-register ref is not linked to the super-register def. This can result in certain super register defs being dead code eliminated. This patch fixes the cover check for a register ref. A def must be skipped only when all RegUnits of that def have already been covered by a previously seen def.
1 parent 2186a00 commit b28eebf

File tree

2 files changed

+59
-8
lines changed

2 files changed

+59
-8
lines changed

llvm/lib/CodeGen/RDFGraph.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1515,15 +1515,13 @@ void DataFlowGraph::linkRefUp(Instr IA, NodeAddr<T> TA, DefStack &DS) {
15151515
for (auto I = DS.top(), E = DS.bottom(); I != E; I.down()) {
15161516
RegisterRef QR = I->Addr->getRegRef(*this);
15171517

1518-
// Skip all defs that are aliased to any of the defs that we have already
1519-
// seen. If this completes a cover of RR, stop the stack traversal.
1520-
bool Alias = Defs.hasAliasOf(QR);
1521-
bool Cover = Defs.insert(QR).hasCoverOf(RR);
1522-
if (Alias) {
1523-
if (Cover)
1524-
break;
1518+
// Skip all defs that we have already seen.
1519+
// If this completes a cover of RR, stop the stack traversal.
1520+
bool Seen = Defs.hasCoverOf(QR);
1521+
if (Seen)
15251522
continue;
1526-
}
1523+
1524+
bool Cover = Defs.insert(QR).hasCoverOf(RR);
15271525

15281526
// The reaching def.
15291527
Def RDA = *I;
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# RUN: llc -march=hexagon -run-pass hexagon-rdf-opt -verify-machineinstrs %s -o - | FileCheck %s
2+
3+
# Check that the L2_loadrd_io load from stack to $d6
4+
# register, in bb.0, is not considered as dead code by RDF
5+
# $d6 is used in A2_minp instruction in bb.1
6+
7+
#CHECK-LABEL: bb.0
8+
#CHECK: renamable $d6 = L2_loadrd_io %stack.{{[0-9]+}}, 0
9+
10+
--- |
11+
12+
define dso_local i32 @fred(ptr %a) local_unnamed_addr {
13+
ret i32 0
14+
}
15+
16+
...
17+
---
18+
name: fred
19+
tracksRegLiveness: true
20+
stack:
21+
- { id: 0, name: '', type: spill-slot, offset: 0, size: 8, alignment: 8,
22+
stack-id: default, callee-saved-register: '', callee-saved-restored: true,
23+
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
24+
25+
body: |
26+
bb.0:
27+
successors: %bb.1, %bb.2
28+
liveins: $d3:0x0000000000000003, $r5, $r8
29+
30+
renamable $p0 = C2_cmpgtui renamable $r8, 1
31+
renamable $r8 = A2_addi killed renamable $r8, -1
32+
renamable $d6 = L2_loadrd_io %stack.0, 0 :: (load (s64) from %stack.0)
33+
renamable $r12, renamable $r5 = L2_loadri_pi killed renamable $r5, 4 :: (load (s32) from %ir.a)
34+
J2_loop0r %bb.1, killed renamable $r8, implicit-def $lc0, implicit-def $sa0, implicit-def $usr
35+
J2_jumpf killed renamable $p0, %bb.2, implicit-def $pc
36+
J2_jump %bb.1, implicit-def $pc
37+
38+
bb.1:
39+
successors: %bb.2, %bb.1
40+
liveins: $d3:0x0000000000000003, $d6:0x0000000000000003, $r5
41+
42+
renamable $d3 = A2_minp killed renamable $d3, renamable $d6
43+
renamable $r12, renamable $r5 = L2_loadri_pi killed renamable $r5, 4 :: (load (s32) from %ir.a + 4)
44+
ENDLOOP0 %bb.1, implicit-def $pc, implicit-def $lc0, implicit $sa0, implicit $lc0
45+
J2_jump %bb.2, implicit-def $pc
46+
47+
bb.2:
48+
liveins: $d3:0x0000000000000003, $d6:0x0000000000000003
49+
50+
renamable $r0 = A2_tfr renamable $r6
51+
J2_jumpr $r31, implicit-def $pc, implicit $r0
52+
...
53+

0 commit comments

Comments
 (0)