Skip to content

Commit eb75af2

Browse files
committed
Reapply "SystemZ: Fold copy of vector immediate to gr128" (#91099)
This reverts commit a415b4d. Modify the instruction in place to transform it into a REG_SEQUENCE, which is what other implementations of foldImmediate do. Also start erasing the def instruction if there are no other uses. Fixes #91110.
1 parent e2c8925 commit eb75af2

File tree

3 files changed

+264
-0
lines changed

3 files changed

+264
-0
lines changed

llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,48 @@ bool SystemZInstrInfo::foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI,
640640
Register Reg,
641641
MachineRegisterInfo *MRI) const {
642642
unsigned DefOpc = DefMI.getOpcode();
643+
644+
if (DefOpc == SystemZ::VGBM) {
645+
int64_t ImmVal = DefMI.getOperand(1).getImm();
646+
if (ImmVal != 0) // TODO: Handle other values
647+
return false;
648+
649+
// Fold gr128 = COPY (vr128 VGBM imm)
650+
//
651+
// %tmp:gr64 = LGHI 0
652+
// to gr128 = REG_SEQUENCE %tmp, %tmp
653+
assert(DefMI.getOperand(0).getReg() == Reg);
654+
655+
if (!UseMI.isCopy())
656+
return false;
657+
658+
Register CopyDstReg = UseMI.getOperand(0).getReg();
659+
if (CopyDstReg.isVirtual() &&
660+
MRI->getRegClass(CopyDstReg) == &SystemZ::GR128BitRegClass &&
661+
MRI->hasOneNonDBGUse(Reg)) {
662+
// TODO: Handle physical registers
663+
// TODO: Handle gr64 uses with subregister indexes
664+
// TODO: Should this multi-use cases?
665+
Register TmpReg = MRI->createVirtualRegister(&SystemZ::GR64BitRegClass);
666+
MachineBasicBlock &MBB = *UseMI.getParent();
667+
668+
loadImmediate(MBB, UseMI.getIterator(), TmpReg, ImmVal);
669+
670+
UseMI.setDesc(get(SystemZ::REG_SEQUENCE));
671+
UseMI.getOperand(1).setReg(TmpReg);
672+
MachineInstrBuilder(*MBB.getParent(), &UseMI)
673+
.addImm(SystemZ::subreg_h64)
674+
.addReg(TmpReg)
675+
.addImm(SystemZ::subreg_l64);
676+
677+
if (MRI->use_nodbg_empty(Reg))
678+
DefMI.eraseFromParent();
679+
return true;
680+
}
681+
682+
return false;
683+
}
684+
643685
if (DefOpc != SystemZ::LHIMux && DefOpc != SystemZ::LHI &&
644686
DefOpc != SystemZ::LGHI)
645687
return false;
@@ -2237,3 +2279,16 @@ areMemAccessesTriviallyDisjoint(const MachineInstr &MIa,
22372279

22382280
return false;
22392281
}
2282+
2283+
bool SystemZInstrInfo::getConstValDefinedInReg(const MachineInstr &MI,
2284+
const Register Reg,
2285+
int64_t &ImmVal) const {
2286+
2287+
if (MI.getOpcode() == SystemZ::VGBM && Reg == MI.getOperand(0).getReg()) {
2288+
ImmVal = MI.getOperand(1).getImm();
2289+
// TODO: Handle non-0 values
2290+
return ImmVal == 0;
2291+
}
2292+
2293+
return false;
2294+
}

llvm/lib/Target/SystemZ/SystemZInstrInfo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,9 @@ class SystemZInstrInfo : public SystemZGenInstrInfo {
383383
bool
384384
areMemAccessesTriviallyDisjoint(const MachineInstr &MIa,
385385
const MachineInstr &MIb) const override;
386+
387+
bool getConstValDefinedInReg(const MachineInstr &MI, const Register Reg,
388+
int64_t &ImmVal) const override;
386389
};
387390

388391
} // end namespace llvm
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4
2+
# RUN: llc -mtriple=s390x-linux-gnu -mcpu=z13 -run-pass=peephole-opt -o - %s | FileCheck %s
3+
4+
---
5+
name: fold_vgbm_0_copyvr128_to_gr128_virtreg
6+
tracksRegLiveness: true
7+
body: |
8+
bb.0:
9+
liveins: $r2d
10+
; CHECK-LABEL: name: fold_vgbm_0_copyvr128_to_gr128_virtreg
11+
; CHECK: liveins: $r2d
12+
; CHECK-NEXT: {{ $}}
13+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64bit = COPY $r2d
14+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:addr64bit = COPY [[COPY]]
15+
; CHECK-NEXT: [[LGHI:%[0-9]+]]:gr64bit = LGHI 0
16+
; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:gr128bit = REG_SEQUENCE [[LGHI]], %subreg.subreg_h64, [[LGHI]], %subreg.subreg_l64
17+
; CHECK-NEXT: $r0q = COPY [[REG_SEQUENCE]]
18+
; CHECK-NEXT: Return implicit $r0q
19+
%0:gr64bit = COPY $r2d
20+
%1:addr64bit = COPY %0
21+
%2:vr128bit = VGBM 0
22+
%3:gr128bit = COPY %2
23+
$r0q = COPY %3
24+
Return implicit $r0q
25+
...
26+
27+
---
28+
name: fold_vgbm_0_copyvr128_to_gr128_virtreg_dbg_use
29+
tracksRegLiveness: true
30+
body: |
31+
bb.0:
32+
liveins: $r2d
33+
; CHECK-LABEL: name: fold_vgbm_0_copyvr128_to_gr128_virtreg_dbg_use
34+
; CHECK: liveins: $r2d
35+
; CHECK-NEXT: {{ $}}
36+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64bit = COPY $r2d
37+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:addr64bit = COPY [[COPY]]
38+
; CHECK-NEXT: [[LGHI:%[0-9]+]]:gr64bit = LGHI 0
39+
; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:gr128bit = REG_SEQUENCE [[LGHI]], %subreg.subreg_h64, [[LGHI]], %subreg.subreg_l64
40+
; CHECK-NEXT: DBG_VALUE %2:vr128bit
41+
; CHECK-NEXT: $r0q = COPY [[REG_SEQUENCE]]
42+
; CHECK-NEXT: Return implicit $r0q
43+
%0:gr64bit = COPY $r2d
44+
%1:addr64bit = COPY %0
45+
%2:vr128bit = VGBM 0
46+
%3:gr128bit = COPY %2
47+
DBG_VALUE %2
48+
$r0q = COPY %3
49+
Return implicit $r0q
50+
...
51+
52+
---
53+
name: fold_vgbm_0_copyvr128_to_gr128_virtreg_multi_use
54+
tracksRegLiveness: true
55+
body: |
56+
bb.0:
57+
liveins: $r2d
58+
; CHECK-LABEL: name: fold_vgbm_0_copyvr128_to_gr128_virtreg_multi_use
59+
; CHECK: liveins: $r2d
60+
; CHECK-NEXT: {{ $}}
61+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64bit = COPY $r2d
62+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:addr64bit = COPY [[COPY]]
63+
; CHECK-NEXT: [[VGBM:%[0-9]+]]:vr128bit = VGBM 0
64+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr128bit = COPY [[VGBM]]
65+
; CHECK-NEXT: $r0q = COPY [[COPY2]]
66+
; CHECK-NEXT: $r2q = COPY [[COPY2]]
67+
; CHECK-NEXT: Return implicit $r0q, implicit $r2q
68+
%0:gr64bit = COPY $r2d
69+
%1:addr64bit = COPY %0
70+
%2:vr128bit = VGBM 0
71+
%3:gr128bit = COPY %2
72+
%4:gr128bit = COPY %2
73+
$r0q = COPY %3
74+
$r2q = COPY %4
75+
Return implicit $r0q, implicit $r2q
76+
...
77+
78+
---
79+
name: fold_vgbm_0_copyvr128_to_gr128_physreg
80+
tracksRegLiveness: true
81+
body: |
82+
bb.0:
83+
liveins: $r2d
84+
; CHECK-LABEL: name: fold_vgbm_0_copyvr128_to_gr128_physreg
85+
; CHECK: liveins: $r2d
86+
; CHECK-NEXT: {{ $}}
87+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64bit = COPY $r2d
88+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:addr64bit = COPY [[COPY]]
89+
; CHECK-NEXT: [[VGBM:%[0-9]+]]:vr128bit = VGBM 0
90+
; CHECK-NEXT: $r0q = COPY [[VGBM]]
91+
; CHECK-NEXT: Return implicit $r0q
92+
%0:gr64bit = COPY $r2d
93+
%1:addr64bit = COPY %0
94+
%2:vr128bit = VGBM 0
95+
$r0q = COPY %2
96+
Return implicit $r0q
97+
...
98+
99+
---
100+
name: no_fold_vgbm_0_copyvr128_to_vr128_virtreg
101+
tracksRegLiveness: true
102+
body: |
103+
bb.0:
104+
liveins: $r2d
105+
; CHECK-LABEL: name: no_fold_vgbm_0_copyvr128_to_vr128_virtreg
106+
; CHECK: liveins: $r2d
107+
; CHECK-NEXT: {{ $}}
108+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64bit = COPY $r2d
109+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:addr64bit = COPY [[COPY]]
110+
; CHECK-NEXT: [[VGBM:%[0-9]+]]:vr128bit = VGBM 0
111+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:vr128bit = COPY [[VGBM]]
112+
; CHECK-NEXT: $v0 = COPY [[COPY2]]
113+
; CHECK-NEXT: Return implicit $v0
114+
%0:gr64bit = COPY $r2d
115+
%1:addr64bit = COPY %0
116+
%2:vr128bit = VGBM 0
117+
%3:vr128bit = COPY %2
118+
$v0 = COPY %3
119+
Return implicit $v0
120+
...
121+
122+
---
123+
name: no_fold_vgbm_0_copyvr128_to_vr128_physreg
124+
tracksRegLiveness: true
125+
body: |
126+
bb.0:
127+
liveins: $r2d
128+
; CHECK-LABEL: name: no_fold_vgbm_0_copyvr128_to_vr128_physreg
129+
; CHECK: liveins: $r2d
130+
; CHECK-NEXT: {{ $}}
131+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64bit = COPY $r2d
132+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:addr64bit = COPY [[COPY]]
133+
; CHECK-NEXT: [[VGBM:%[0-9]+]]:vr128bit = VGBM 0
134+
; CHECK-NEXT: $v0 = COPY [[VGBM]]
135+
; CHECK-NEXT: Return implicit $v0
136+
%0:gr64bit = COPY $r2d
137+
%1:addr64bit = COPY %0
138+
%2:vr128bit = VGBM 0
139+
$v0 = COPY %2
140+
Return implicit $v0
141+
...
142+
143+
---
144+
name: fold_vgbm_1_copyvr128_to_gr128_virtreg
145+
tracksRegLiveness: true
146+
body: |
147+
bb.0:
148+
liveins: $r2d
149+
; CHECK-LABEL: name: fold_vgbm_1_copyvr128_to_gr128_virtreg
150+
; CHECK: liveins: $r2d
151+
; CHECK-NEXT: {{ $}}
152+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64bit = COPY $r2d
153+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:addr64bit = COPY [[COPY]]
154+
; CHECK-NEXT: [[VGBM:%[0-9]+]]:vr128bit = VGBM 1
155+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr128bit = COPY [[VGBM]]
156+
; CHECK-NEXT: $r0q = COPY [[COPY2]]
157+
; CHECK-NEXT: Return implicit $r0q
158+
%0:gr64bit = COPY $r2d
159+
%1:addr64bit = COPY %0
160+
%2:vr128bit = VGBM 1
161+
%3:gr128bit = COPY %2
162+
$r0q = COPY %3
163+
Return implicit $r0q
164+
...
165+
166+
---
167+
name: no_fold_vgbm_0_noncopy_use
168+
tracksRegLiveness: true
169+
body: |
170+
bb.0:
171+
liveins: $r2d
172+
; CHECK-LABEL: name: no_fold_vgbm_0_noncopy_use
173+
; CHECK: liveins: $r2d
174+
; CHECK-NEXT: {{ $}}
175+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64bit = COPY $r2d
176+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:addr64bit = COPY [[COPY]]
177+
; CHECK-NEXT: [[VGBM:%[0-9]+]]:vr128bit = VGBM 0
178+
; CHECK-NEXT: Return implicit [[VGBM]]
179+
%0:gr64bit = COPY $r2d
180+
%1:addr64bit = COPY %0
181+
%2:vr128bit = VGBM 0
182+
Return implicit %2
183+
...
184+
185+
---
186+
name: fold_vgbm_0_copyvr128_to_gr64_subreg_h64
187+
tracksRegLiveness: true
188+
body: |
189+
bb.0:
190+
liveins: $r2d
191+
; CHECK-LABEL: name: fold_vgbm_0_copyvr128_to_gr64_subreg_h64
192+
; CHECK: liveins: $r2d
193+
; CHECK-NEXT: {{ $}}
194+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64bit = COPY $r2d
195+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:addr64bit = COPY [[COPY]]
196+
; CHECK-NEXT: [[VGBM:%[0-9]+]]:vr128bit = VGBM 0
197+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr64bit = COPY [[VGBM]].subreg_h64
198+
; CHECK-NEXT: $r0d = COPY [[COPY2]]
199+
; CHECK-NEXT: Return implicit $r0d
200+
%0:gr64bit = COPY $r2d
201+
%1:addr64bit = COPY %0
202+
%2:vr128bit = VGBM 0
203+
%3:gr64bit = COPY %2.subreg_h64
204+
$r0d = COPY %3
205+
Return implicit $r0d
206+
...

0 commit comments

Comments
 (0)