Skip to content

Commit 7f3787c

Browse files
committed
[PowerPC] Bail out of redundant LI elimination on an implicit kill
The transformation currently does not differentiate between explicit and implicit kills. However, it is not valid to later simply clear an implicit kill flag since the kill could be due to a call or return. Fixes: https://bugs.llvm.org/show_bug.cgi?id=45374
1 parent 4275eb1 commit 7f3787c

File tree

2 files changed

+124
-0
lines changed

2 files changed

+124
-0
lines changed

llvm/lib/Target/PowerPC/PPCPreEmitPeephole.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,16 @@ namespace {
109109
// Track the operand that kill Reg. We would unset the kill flag of
110110
// the operand if there is a following redundant load immediate.
111111
int KillIdx = AfterBBI->findRegisterUseOperandIdx(Reg, true, TRI);
112+
113+
// We can't just clear implicit kills, so if we encounter one, stop
114+
// looking further.
115+
if (KillIdx != -1 && AfterBBI->getOperand(KillIdx).isImplicit()) {
116+
LLVM_DEBUG(dbgs()
117+
<< "Encountered an implicit kill, cannot proceed: ");
118+
LLVM_DEBUG(AfterBBI->dump());
119+
break;
120+
}
121+
112122
if (KillIdx != -1) {
113123
assert(!DeadOrKillToUnset && "Shouldn't kill same register twice");
114124
DeadOrKillToUnset = &AfterBBI->getOperand(KillIdx);
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
# RUN: llc -mcpu=pwr9 -mtriple=powerpc64le-unknown-unknown -run-pass \
3+
# RUN: ppc-pre-emit-peephole %s -o - | FileCheck %s
4+
--- |
5+
; ModuleID = 'a.ll'
6+
source_filename = "a.ll"
7+
target datalayout = "e-m:e-i64:64-n32:64"
8+
9+
; Function Attrs: nounwind
10+
define dso_local signext i32 @b(i32 signext %a, i32* nocapture %b) local_unnamed_addr #0 {
11+
entry:
12+
%call = tail call signext i32 @g(i32 signext %a)
13+
store i32 %call, i32* %b, align 4
14+
%call1 = tail call signext i32 @g(i32 signext %a)
15+
ret i32 %call1
16+
}
17+
18+
; Function Attrs: nounwind
19+
declare signext i32 @g(i32 signext) local_unnamed_addr #0
20+
21+
; Function Attrs: nounwind
22+
declare void @llvm.stackprotector(i8*, i8**) #0
23+
24+
attributes #0 = { nounwind }
25+
26+
...
27+
---
28+
name: b
29+
alignment: 16
30+
exposesReturnsTwice: false
31+
legalized: false
32+
regBankSelected: false
33+
selected: false
34+
failedISel: false
35+
tracksRegLiveness: true
36+
hasWinCFI: false
37+
registers: []
38+
liveins:
39+
- { reg: '$x3', virtual-reg: '' }
40+
- { reg: '$x4', virtual-reg: '' }
41+
frameInfo:
42+
isFrameAddressTaken: false
43+
isReturnAddressTaken: false
44+
hasStackMap: false
45+
hasPatchPoint: false
46+
stackSize: 64
47+
offsetAdjustment: 0
48+
maxAlignment: 1
49+
adjustsStack: true
50+
hasCalls: true
51+
stackProtector: ''
52+
maxCallFrameSize: 32
53+
cvBytesOfCalleeSavedRegisters: 0
54+
hasOpaqueSPAdjustment: false
55+
hasVAStart: false
56+
hasMustTailInVarArgFunc: false
57+
localFrameSize: 0
58+
savePoint: ''
59+
restorePoint: ''
60+
fixedStack:
61+
- { id: 0, type: spill-slot, offset: -80, size: 8, alignment: 16, stack-id: default,
62+
callee-saved-register: '$x30', callee-saved-restored: true, debug-info-variable: '',
63+
debug-info-expression: '', debug-info-___location: '' }
64+
- { id: 1, type: spill-slot, offset: -88, size: 8, alignment: 8, stack-id: default,
65+
callee-saved-register: '$x29', callee-saved-restored: true, debug-info-variable: '',
66+
debug-info-expression: '', debug-info-___location: '' }
67+
stack: []
68+
callSites: []
69+
constants: []
70+
machineFunctionInfo: {}
71+
body: |
72+
bb.0.entry:
73+
liveins: $x3, $x4, $x29, $x30
74+
75+
; CHECK-LABEL: name: b
76+
; CHECK: liveins: $x3, $x4, $x29, $x30
77+
; CHECK: $x0 = MFLR8 implicit $lr8
78+
; CHECK: STD killed $x29, -24, $x1 :: (store 8 into %fixed-stack.0)
79+
; CHECK: STD killed $x30, -16, $x1 :: (store 8 into %fixed-stack.1, align 16)
80+
; CHECK: STD killed $x0, 16, $x1
81+
; CHECK: $x1 = STDU $x1, -64, $x1
82+
; CHECK: $x30 = OR8 killed $x4, $x4
83+
; CHECK: dead $r4 = LI 10, implicit-def $x4
84+
; CHECK: $x29 = OR8 $x3, $x3
85+
; CHECK: BL8_NOP @g, csr_ppc64_r2_altivec, implicit-def dead $lr8, implicit $rm, implicit killed $x3, implicit killed $x4, implicit $x2, implicit-def $r1, implicit-def $x3
86+
; CHECK: STW8 killed renamable $x3, 0, killed renamable $x30 :: (store 4 into %ir.b)
87+
; CHECK: $x3 = OR8 killed $x29, $x29
88+
; CHECK: BL8_NOP @g, csr_ppc64_r2_altivec, implicit-def dead $lr8, implicit $rm, implicit killed $x3, implicit $x2, implicit-def $r1, implicit-def $x3
89+
; CHECK: $x1 = ADDI8 $x1, 64
90+
; CHECK: $x0 = LD 16, $x1
91+
; CHECK: $x30 = LD -16, $x1 :: (load 8 from %fixed-stack.1, align 16)
92+
; CHECK: $x29 = LD -24, $x1 :: (load 8 from %fixed-stack.0)
93+
; CHECK: MTLR8 killed $x0, implicit-def $lr8
94+
; CHECK: BLR8 implicit $lr8, implicit $rm, implicit killed $x3
95+
$x0 = MFLR8 implicit $lr8
96+
STD killed $x29, -24, $x1 :: (store 8 into %fixed-stack.1)
97+
STD killed $x30, -16, $x1 :: (store 8 into %fixed-stack.0, align 16)
98+
STD killed $x0, 16, $x1
99+
$x1 = STDU $x1, -64, $x1
100+
$x30 = OR8 killed $x4, $x4
101+
dead $r4 = LI 10, implicit-def $x4
102+
$x29 = OR8 $x3, $x3
103+
BL8_NOP @g, csr_ppc64_r2_altivec, implicit-def dead $lr8, implicit $rm, implicit killed $x3, implicit killed $x4, implicit $x2, implicit-def $r1, implicit-def $x3
104+
STW8 killed renamable $x3, 0, killed renamable $x30 :: (store 4 into %ir.b)
105+
$x3 = OR8 killed $x29, $x29
106+
BL8_NOP @g, csr_ppc64_r2_altivec, implicit-def dead $lr8, implicit $rm, implicit killed $x3, implicit $x2, implicit-def $r1, implicit-def $x3
107+
$x1 = ADDI8 $x1, 64
108+
$x0 = LD 16, $x1
109+
$x30 = LD -16, $x1 :: (load 8 from %fixed-stack.0, align 16)
110+
$x29 = LD -24, $x1 :: (load 8 from %fixed-stack.1)
111+
MTLR8 killed $x0, implicit-def $lr8
112+
BLR8 implicit $lr8, implicit $rm, implicit killed $x3
113+
114+
...

0 commit comments

Comments
 (0)