Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 37d2d7a

Browse files
committed
AArch64LoadStoreOptimizer: Update kill flags when merging stores
Kill flags need to be updated correctly when moving stores up/down to form store pair instructions. Those invalid flags have been ignored before but as of r290014 they are recognized when using -mllvm -verify-machineinstrs. Also simplifies test/CodeGen/AArch64/ldst-opt-dbg-limit.mir, renames it to ldst-opt.mir test and adds a new tests for this change. Differential Revision: https://reviews.llvm.org/D28875 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292625 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent eb2c5a9 commit 37d2d7a

File tree

3 files changed

+155
-135
lines changed

3 files changed

+155
-135
lines changed

lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -687,9 +687,30 @@ AArch64LoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
687687
MachineInstrBuilder MIB;
688688
DebugLoc DL = I->getDebugLoc();
689689
MachineBasicBlock *MBB = I->getParent();
690+
MachineOperand RegOp0 = getLdStRegOp(*RtMI);
691+
MachineOperand RegOp1 = getLdStRegOp(*Rt2MI);
692+
// Kill flags may become invalid when moving stores for pairing.
693+
if (RegOp0.isUse()) {
694+
if (!MergeForward) {
695+
// Clear kill flags on store if moving upwards. Example:
696+
// STRWui %w0, ...
697+
// USE %w1
698+
// STRWui kill %w1 ; need to clear kill flag when moving STRWui upwards
699+
RegOp0.setIsKill(false);
700+
RegOp1.setIsKill(false);
701+
} else {
702+
// Clear kill flags of the first stores register. Example:
703+
// STRWui %w1, ...
704+
// USE kill %w1 ; need to clear kill flag when moving STRWui downwards
705+
// STRW %w0
706+
unsigned Reg = getLdStRegOp(*I).getReg();
707+
for (MachineInstr &MI : make_range(std::next(I), Paired))
708+
MI.clearRegisterKills(Reg, TRI);
709+
}
710+
}
690711
MIB = BuildMI(*MBB, InsertionPoint, DL, TII->get(getMatchingPairOpcode(Opc)))
691-
.add(getLdStRegOp(*RtMI))
692-
.add(getLdStRegOp(*Rt2MI))
712+
.add(RegOp0)
713+
.add(RegOp1)
693714
.add(BaseRegOp)
694715
.addImm(OffsetImm)
695716
.setMemRefs(I->mergeMemRefsWith(*Paired));

test/CodeGen/AArch64/ldst-opt-dbg-limit.mir

Lines changed: 0 additions & 133 deletions
This file was deleted.

test/CodeGen/AArch64/ldst-opt.mir

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# RUN: llc -mtriple=aarch64--linux-gnu -run-pass=aarch64-ldst-opt %s -verify-machineinstrs -o - 2>&1 | FileCheck %s
2+
--- |
3+
define void @promote-load-from-store() { ret void }
4+
define void @store-pair() { ret void }
5+
define void @store-pair-clearkill0() { ret void }
6+
define void @store-pair-clearkill1() { ret void }
7+
...
8+
---
9+
name: promote-load-from-store
10+
tracksRegLiveness: true
11+
body: |
12+
bb.0:
13+
liveins: %w1, %x0, %lr
14+
15+
STRWui killed %w1, %x0, 0 :: (store 4)
16+
CFI_INSTRUCTION 0
17+
CFI_INSTRUCTION 0
18+
CFI_INSTRUCTION 0
19+
CFI_INSTRUCTION 0
20+
CFI_INSTRUCTION 0
21+
CFI_INSTRUCTION 0
22+
CFI_INSTRUCTION 0
23+
CFI_INSTRUCTION 0
24+
CFI_INSTRUCTION 0
25+
CFI_INSTRUCTION 0
26+
CFI_INSTRUCTION 0
27+
CFI_INSTRUCTION 0
28+
CFI_INSTRUCTION 0
29+
CFI_INSTRUCTION 0
30+
CFI_INSTRUCTION 0
31+
CFI_INSTRUCTION 0
32+
CFI_INSTRUCTION 0
33+
CFI_INSTRUCTION 0
34+
CFI_INSTRUCTION 0
35+
CFI_INSTRUCTION 0
36+
%w0 = LDRHHui killed %x0, 1 :: (load 2)
37+
RET %lr, implicit %w0
38+
39+
...
40+
# Don't count transient instructions towards search limits.
41+
# CHECK-LABEL: name: promote-load-from-store
42+
# CHECK: STRWui %w1
43+
# CHECK: UBFMWri %w1
44+
---
45+
name: store-pair
46+
tracksRegLiveness: true
47+
body: |
48+
bb.0:
49+
liveins: %w1, %x0, %lr
50+
51+
STRWui %w1, %x0, 0 :: (store 4)
52+
CFI_INSTRUCTION 0
53+
CFI_INSTRUCTION 0
54+
CFI_INSTRUCTION 0
55+
CFI_INSTRUCTION 0
56+
CFI_INSTRUCTION 0
57+
CFI_INSTRUCTION 0
58+
CFI_INSTRUCTION 0
59+
CFI_INSTRUCTION 0
60+
CFI_INSTRUCTION 0
61+
CFI_INSTRUCTION 0
62+
CFI_INSTRUCTION 0
63+
CFI_INSTRUCTION 0
64+
CFI_INSTRUCTION 0
65+
CFI_INSTRUCTION 0
66+
CFI_INSTRUCTION 0
67+
CFI_INSTRUCTION 0
68+
CFI_INSTRUCTION 0
69+
CFI_INSTRUCTION 0
70+
CFI_INSTRUCTION 0
71+
CFI_INSTRUCTION 0
72+
STRWui killed %w1, killed %x0, 1 :: (store 4)
73+
RET %lr
74+
75+
...
76+
# CHECK-LABEL: name: store-pair
77+
# CHECK: STPWi
78+
---
79+
name: store-pair-clearkill0
80+
tracksRegLiveness: true
81+
body: |
82+
bb.0:
83+
liveins: %w1, %x0, %lr
84+
85+
STRWui %w1, %x0, 0 :: (store 4)
86+
%w2 = COPY %w1
87+
%x3 = COPY %x0
88+
STRWui killed %w1, killed %x0, 1 :: (store 4)
89+
RET %lr
90+
...
91+
# When merging a lower store with an upper one, we must clear kill flags on
92+
# the lower store.
93+
# CHECK-LABEL: store-pair-clearkill0
94+
# CHECK-NOT: STPWi %w1, killed %w1, %x0, 0 :: (store 4)
95+
# CHECK: STPWi %w1, %w1, %x0, 0 :: (store 4)
96+
# CHECK: %w2 = COPY %w1
97+
# CHECK: RET %lr
98+
---
99+
name: store-pair-clearkill1
100+
tracksRegLiveness: true
101+
body: |
102+
bb.0:
103+
liveins: %x0, %lr
104+
105+
%w1 = MOVi32imm 13
106+
%w2 = MOVi32imm 7
107+
STRWui %w1, %x0, 1 :: (store 4)
108+
%w2 = COPY killed %w1
109+
STRWui killed %w2, %x0, 0 :: (store 4)
110+
111+
%w1 = MOVi32imm 42
112+
%w2 = MOVi32imm 7
113+
STRWui %w1, %x0, 0 :: (store 4)
114+
%w2 = COPY killed %w1
115+
STRWui killed %w2, killed %x0, 1 :: (store 4)
116+
117+
RET %lr
118+
...
119+
# When merging an upper store with a lower one, kill flags along the way need
120+
# to be removed; In this case the kill flag on %w1.
121+
# CHECK-LABEL: store-pair-clearkill1
122+
# CHECK: %w1 = MOVi32imm
123+
# CHECK: %w2 = MOVi32imm
124+
# CHECK-NOT: %w2 = COPY killed %w1
125+
# CHECK: %w2 = COPY %w1
126+
# CHECK: STPWi killed %w2, %w1, %x0, 0
127+
128+
# CHECK: %w1 = MOVi32imm
129+
# CHECK: %w2 = MOVi32imm
130+
# CHECK-NOT: %w2 = COPY killed %w1
131+
# CHECK: %w2 = COPY %w1
132+
# CHECK: STPWi %w1, killed %w2, killed %x0, 0

0 commit comments

Comments
 (0)