Skip to content

Commit 49c5f4d

Browse files
authored
SystemZ: Fold copy of vector immediate to gr128 (#90706)
If materializing a constant in a vector register that is just going to be copied to general registers, directly materialize the immediate in the gpr. This will avoid a few lit test regressions in a future commit.
1 parent ac46eea commit 49c5f4d

File tree

3 files changed

+243
-0
lines changed

3 files changed

+243
-0
lines changed

llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,51 @@ 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+
// FIXME: probably should be DefMI's DebugLoc but this matches
669+
// loadImmediate's guessing
670+
const DebugLoc &DL = UseMI.getDebugLoc();
671+
672+
loadImmediate(MBB, UseMI.getIterator(), TmpReg, ImmVal);
673+
674+
BuildMI(MBB, UseMI.getIterator(), DL, get(SystemZ::REG_SEQUENCE),
675+
CopyDstReg)
676+
.addReg(TmpReg)
677+
.addImm(SystemZ::subreg_h64)
678+
.addReg(TmpReg)
679+
.addImm(SystemZ::subreg_l64);
680+
681+
UseMI.eraseFromParent();
682+
return true;
683+
}
684+
685+
return false;
686+
}
687+
643688
if (DefOpc != SystemZ::LHIMux && DefOpc != SystemZ::LHI &&
644689
DefOpc != SystemZ::LGHI)
645690
return false;
@@ -2237,3 +2282,16 @@ areMemAccessesTriviallyDisjoint(const MachineInstr &MIa,
22372282

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

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: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
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: [[VGBM:%[0-9]+]]:vr128bit = VGBM 0
16+
; CHECK-NEXT: [[LGHI:%[0-9]+]]:gr64bit = LGHI 0
17+
; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:gr128bit = REG_SEQUENCE [[LGHI]], %subreg.subreg_h64, [[LGHI]], %subreg.subreg_l64
18+
; CHECK-NEXT: $r0q = COPY [[REG_SEQUENCE]]
19+
; CHECK-NEXT: Return implicit $r0q
20+
%0:gr64bit = COPY $r2d
21+
%1:addr64bit = COPY %0
22+
%2:vr128bit = VGBM 0
23+
%3:gr128bit = COPY %2
24+
$r0q = COPY %3
25+
Return implicit $r0q
26+
...
27+
28+
---
29+
name: fold_vgbm_0_copyvr128_to_gr128_virtreg_multi_use
30+
tracksRegLiveness: true
31+
body: |
32+
bb.0:
33+
liveins: $r2d
34+
; CHECK-LABEL: name: fold_vgbm_0_copyvr128_to_gr128_virtreg_multi_use
35+
; CHECK: liveins: $r2d
36+
; CHECK-NEXT: {{ $}}
37+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64bit = COPY $r2d
38+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:addr64bit = COPY [[COPY]]
39+
; CHECK-NEXT: [[VGBM:%[0-9]+]]:vr128bit = VGBM 0
40+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr128bit = COPY [[VGBM]]
41+
; CHECK-NEXT: $r0q = COPY [[COPY2]]
42+
; CHECK-NEXT: $r2q = COPY [[COPY2]]
43+
; CHECK-NEXT: Return implicit $r0q, implicit $r2q
44+
%0:gr64bit = COPY $r2d
45+
%1:addr64bit = COPY %0
46+
%2:vr128bit = VGBM 0
47+
%3:gr128bit = COPY %2
48+
%4:gr128bit = COPY %2
49+
$r0q = COPY %3
50+
$r2q = COPY %4
51+
Return implicit $r0q, implicit $r2q
52+
...
53+
54+
---
55+
name: fold_vgbm_0_copyvr128_to_gr128_physreg
56+
tracksRegLiveness: true
57+
body: |
58+
bb.0:
59+
liveins: $r2d
60+
; CHECK-LABEL: name: fold_vgbm_0_copyvr128_to_gr128_physreg
61+
; CHECK: liveins: $r2d
62+
; CHECK-NEXT: {{ $}}
63+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64bit = COPY $r2d
64+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:addr64bit = COPY [[COPY]]
65+
; CHECK-NEXT: [[VGBM:%[0-9]+]]:vr128bit = VGBM 0
66+
; CHECK-NEXT: $r0q = COPY [[VGBM]]
67+
; CHECK-NEXT: Return implicit $r0q
68+
%0:gr64bit = COPY $r2d
69+
%1:addr64bit = COPY %0
70+
%2:vr128bit = VGBM 0
71+
$r0q = COPY %2
72+
Return implicit $r0q
73+
...
74+
75+
---
76+
name: no_fold_vgbm_0_copyvr128_to_vr128_virtreg
77+
tracksRegLiveness: true
78+
body: |
79+
bb.0:
80+
liveins: $r2d
81+
; CHECK-LABEL: name: no_fold_vgbm_0_copyvr128_to_vr128_virtreg
82+
; CHECK: liveins: $r2d
83+
; CHECK-NEXT: {{ $}}
84+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64bit = COPY $r2d
85+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:addr64bit = COPY [[COPY]]
86+
; CHECK-NEXT: [[VGBM:%[0-9]+]]:vr128bit = VGBM 0
87+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:vr128bit = COPY [[VGBM]]
88+
; CHECK-NEXT: $v0 = COPY [[COPY2]]
89+
; CHECK-NEXT: Return implicit $v0
90+
%0:gr64bit = COPY $r2d
91+
%1:addr64bit = COPY %0
92+
%2:vr128bit = VGBM 0
93+
%3:vr128bit = COPY %2
94+
$v0 = COPY %3
95+
Return implicit $v0
96+
...
97+
98+
---
99+
name: no_fold_vgbm_0_copyvr128_to_vr128_physreg
100+
tracksRegLiveness: true
101+
body: |
102+
bb.0:
103+
liveins: $r2d
104+
; CHECK-LABEL: name: no_fold_vgbm_0_copyvr128_to_vr128_physreg
105+
; CHECK: liveins: $r2d
106+
; CHECK-NEXT: {{ $}}
107+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64bit = COPY $r2d
108+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:addr64bit = COPY [[COPY]]
109+
; CHECK-NEXT: [[VGBM:%[0-9]+]]:vr128bit = VGBM 0
110+
; CHECK-NEXT: $v0 = COPY [[VGBM]]
111+
; CHECK-NEXT: Return implicit $v0
112+
%0:gr64bit = COPY $r2d
113+
%1:addr64bit = COPY %0
114+
%2:vr128bit = VGBM 0
115+
$v0 = COPY %2
116+
Return implicit $v0
117+
...
118+
119+
---
120+
name: fold_vgbm_1_copyvr128_to_gr128_virtreg
121+
tracksRegLiveness: true
122+
body: |
123+
bb.0:
124+
liveins: $r2d
125+
; CHECK-LABEL: name: fold_vgbm_1_copyvr128_to_gr128_virtreg
126+
; CHECK: liveins: $r2d
127+
; CHECK-NEXT: {{ $}}
128+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64bit = COPY $r2d
129+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:addr64bit = COPY [[COPY]]
130+
; CHECK-NEXT: [[VGBM:%[0-9]+]]:vr128bit = VGBM 1
131+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr128bit = COPY [[VGBM]]
132+
; CHECK-NEXT: $r0q = COPY [[COPY2]]
133+
; CHECK-NEXT: Return implicit $r0q
134+
%0:gr64bit = COPY $r2d
135+
%1:addr64bit = COPY %0
136+
%2:vr128bit = VGBM 1
137+
%3:gr128bit = COPY %2
138+
$r0q = COPY %3
139+
Return implicit $r0q
140+
...
141+
142+
---
143+
name: no_fold_vgbm_0_noncopy_use
144+
tracksRegLiveness: true
145+
body: |
146+
bb.0:
147+
liveins: $r2d
148+
; CHECK-LABEL: name: no_fold_vgbm_0_noncopy_use
149+
; CHECK: liveins: $r2d
150+
; CHECK-NEXT: {{ $}}
151+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64bit = COPY $r2d
152+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:addr64bit = COPY [[COPY]]
153+
; CHECK-NEXT: [[VGBM:%[0-9]+]]:vr128bit = VGBM 0
154+
; CHECK-NEXT: Return implicit [[VGBM]]
155+
%0:gr64bit = COPY $r2d
156+
%1:addr64bit = COPY %0
157+
%2:vr128bit = VGBM 0
158+
Return implicit %2
159+
...
160+
161+
---
162+
name: fold_vgbm_0_copyvr128_to_gr64_subreg_h64
163+
tracksRegLiveness: true
164+
body: |
165+
bb.0:
166+
liveins: $r2d
167+
; CHECK-LABEL: name: fold_vgbm_0_copyvr128_to_gr64_subreg_h64
168+
; CHECK: liveins: $r2d
169+
; CHECK-NEXT: {{ $}}
170+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64bit = COPY $r2d
171+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:addr64bit = COPY [[COPY]]
172+
; CHECK-NEXT: [[VGBM:%[0-9]+]]:vr128bit = VGBM 0
173+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr64bit = COPY [[VGBM]].subreg_h64
174+
; CHECK-NEXT: $r0d = COPY [[COPY2]]
175+
; CHECK-NEXT: Return implicit $r0d
176+
%0:gr64bit = COPY $r2d
177+
%1:addr64bit = COPY %0
178+
%2:vr128bit = VGBM 0
179+
%3:gr64bit = COPY %2.subreg_h64
180+
$r0d = COPY %3
181+
Return implicit $r0d
182+
...

0 commit comments

Comments
 (0)