Skip to content

SystemZ: Fold copy of vector immediate to gr128 #90706

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,51 @@ bool SystemZInstrInfo::foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI,
Register Reg,
MachineRegisterInfo *MRI) const {
unsigned DefOpc = DefMI.getOpcode();

if (DefOpc == SystemZ::VGBM) {
int64_t ImmVal = DefMI.getOperand(1).getImm();
if (ImmVal != 0) // TODO: Handle other values
return false;

// Fold gr128 = COPY (vr128 VGBM imm)
//
// %tmp:gr64 = LGHI 0
// to gr128 = REG_SEQUENCE %tmp, %tmp
assert(DefMI.getOperand(0).getReg() == Reg);

if (!UseMI.isCopy())
return false;

Register CopyDstReg = UseMI.getOperand(0).getReg();
if (CopyDstReg.isVirtual() &&
MRI->getRegClass(CopyDstReg) == &SystemZ::GR128BitRegClass &&
MRI->hasOneNonDBGUse(Reg)) {
// TODO: Handle physical registers
// TODO: Handle gr64 uses with subregister indexes
// TODO: Should this multi-use cases?
Register TmpReg = MRI->createVirtualRegister(&SystemZ::GR64BitRegClass);
MachineBasicBlock &MBB = *UseMI.getParent();

// FIXME: probably should be DefMI's DebugLoc but this matches
// loadImmediate's guessing
const DebugLoc &DL = UseMI.getDebugLoc();

loadImmediate(MBB, UseMI.getIterator(), TmpReg, ImmVal);

BuildMI(MBB, UseMI.getIterator(), DL, get(SystemZ::REG_SEQUENCE),
CopyDstReg)
.addReg(TmpReg)
.addImm(SystemZ::subreg_h64)
.addReg(TmpReg)
.addImm(SystemZ::subreg_l64);

UseMI.eraseFromParent();
return true;
}

return false;
}

if (DefOpc != SystemZ::LHIMux && DefOpc != SystemZ::LHI &&
DefOpc != SystemZ::LGHI)
return false;
Expand Down Expand Up @@ -2237,3 +2282,16 @@ areMemAccessesTriviallyDisjoint(const MachineInstr &MIa,

return false;
}

bool SystemZInstrInfo::getConstValDefinedInReg(const MachineInstr &MI,
const Register Reg,
int64_t &ImmVal) const {

if (MI.getOpcode() == SystemZ::VGBM && Reg == MI.getOperand(0).getReg()) {
ImmVal = MI.getOperand(1).getImm();
// TODO: Handle non-0 values
return ImmVal == 0;
}

return false;
}
3 changes: 3 additions & 0 deletions llvm/lib/Target/SystemZ/SystemZInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,9 @@ class SystemZInstrInfo : public SystemZGenInstrInfo {
bool
areMemAccessesTriviallyDisjoint(const MachineInstr &MIa,
const MachineInstr &MIb) const override;

bool getConstValDefinedInReg(const MachineInstr &MI, const Register Reg,
int64_t &ImmVal) const override;
};

} // end namespace llvm
Expand Down
182 changes: 182 additions & 0 deletions llvm/test/CodeGen/SystemZ/fold-copy-vector-immediate.mir
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4
# RUN: llc -mtriple=s390x-linux-gnu -mcpu=z13 -run-pass=peephole-opt -o - %s | FileCheck %s

---
name: fold_vgbm_0_copyvr128_to_gr128_virtreg
tracksRegLiveness: true
body: |
bb.0:
liveins: $r2d
; CHECK-LABEL: name: fold_vgbm_0_copyvr128_to_gr128_virtreg
; CHECK: liveins: $r2d
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64bit = COPY $r2d
; CHECK-NEXT: [[COPY1:%[0-9]+]]:addr64bit = COPY [[COPY]]
; CHECK-NEXT: [[VGBM:%[0-9]+]]:vr128bit = VGBM 0
; CHECK-NEXT: [[LGHI:%[0-9]+]]:gr64bit = LGHI 0
; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:gr128bit = REG_SEQUENCE [[LGHI]], %subreg.subreg_h64, [[LGHI]], %subreg.subreg_l64
; CHECK-NEXT: $r0q = COPY [[REG_SEQUENCE]]
; CHECK-NEXT: Return implicit $r0q
%0:gr64bit = COPY $r2d
%1:addr64bit = COPY %0
%2:vr128bit = VGBM 0
%3:gr128bit = COPY %2
$r0q = COPY %3
Return implicit $r0q
...

---
name: fold_vgbm_0_copyvr128_to_gr128_virtreg_multi_use
tracksRegLiveness: true
body: |
bb.0:
liveins: $r2d
; CHECK-LABEL: name: fold_vgbm_0_copyvr128_to_gr128_virtreg_multi_use
; CHECK: liveins: $r2d
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64bit = COPY $r2d
; CHECK-NEXT: [[COPY1:%[0-9]+]]:addr64bit = COPY [[COPY]]
; CHECK-NEXT: [[VGBM:%[0-9]+]]:vr128bit = VGBM 0
; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr128bit = COPY [[VGBM]]
; CHECK-NEXT: $r0q = COPY [[COPY2]]
; CHECK-NEXT: $r2q = COPY [[COPY2]]
; CHECK-NEXT: Return implicit $r0q, implicit $r2q
%0:gr64bit = COPY $r2d
%1:addr64bit = COPY %0
%2:vr128bit = VGBM 0
%3:gr128bit = COPY %2
%4:gr128bit = COPY %2
$r0q = COPY %3
$r2q = COPY %4
Return implicit $r0q, implicit $r2q
...

---
name: fold_vgbm_0_copyvr128_to_gr128_physreg
tracksRegLiveness: true
body: |
bb.0:
liveins: $r2d
; CHECK-LABEL: name: fold_vgbm_0_copyvr128_to_gr128_physreg
; CHECK: liveins: $r2d
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64bit = COPY $r2d
; CHECK-NEXT: [[COPY1:%[0-9]+]]:addr64bit = COPY [[COPY]]
; CHECK-NEXT: [[VGBM:%[0-9]+]]:vr128bit = VGBM 0
; CHECK-NEXT: $r0q = COPY [[VGBM]]
; CHECK-NEXT: Return implicit $r0q
%0:gr64bit = COPY $r2d
%1:addr64bit = COPY %0
%2:vr128bit = VGBM 0
$r0q = COPY %2
Return implicit $r0q
...

---
name: no_fold_vgbm_0_copyvr128_to_vr128_virtreg
tracksRegLiveness: true
body: |
bb.0:
liveins: $r2d
; CHECK-LABEL: name: no_fold_vgbm_0_copyvr128_to_vr128_virtreg
; CHECK: liveins: $r2d
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64bit = COPY $r2d
; CHECK-NEXT: [[COPY1:%[0-9]+]]:addr64bit = COPY [[COPY]]
; CHECK-NEXT: [[VGBM:%[0-9]+]]:vr128bit = VGBM 0
; CHECK-NEXT: [[COPY2:%[0-9]+]]:vr128bit = COPY [[VGBM]]
; CHECK-NEXT: $v0 = COPY [[COPY2]]
; CHECK-NEXT: Return implicit $v0
%0:gr64bit = COPY $r2d
%1:addr64bit = COPY %0
%2:vr128bit = VGBM 0
%3:vr128bit = COPY %2
$v0 = COPY %3
Return implicit $v0
...

---
name: no_fold_vgbm_0_copyvr128_to_vr128_physreg
tracksRegLiveness: true
body: |
bb.0:
liveins: $r2d
; CHECK-LABEL: name: no_fold_vgbm_0_copyvr128_to_vr128_physreg
; CHECK: liveins: $r2d
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64bit = COPY $r2d
; CHECK-NEXT: [[COPY1:%[0-9]+]]:addr64bit = COPY [[COPY]]
; CHECK-NEXT: [[VGBM:%[0-9]+]]:vr128bit = VGBM 0
; CHECK-NEXT: $v0 = COPY [[VGBM]]
; CHECK-NEXT: Return implicit $v0
%0:gr64bit = COPY $r2d
%1:addr64bit = COPY %0
%2:vr128bit = VGBM 0
$v0 = COPY %2
Return implicit $v0
...

---
name: fold_vgbm_1_copyvr128_to_gr128_virtreg
tracksRegLiveness: true
body: |
bb.0:
liveins: $r2d
; CHECK-LABEL: name: fold_vgbm_1_copyvr128_to_gr128_virtreg
; CHECK: liveins: $r2d
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64bit = COPY $r2d
; CHECK-NEXT: [[COPY1:%[0-9]+]]:addr64bit = COPY [[COPY]]
; CHECK-NEXT: [[VGBM:%[0-9]+]]:vr128bit = VGBM 1
; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr128bit = COPY [[VGBM]]
; CHECK-NEXT: $r0q = COPY [[COPY2]]
; CHECK-NEXT: Return implicit $r0q
%0:gr64bit = COPY $r2d
%1:addr64bit = COPY %0
%2:vr128bit = VGBM 1
%3:gr128bit = COPY %2
$r0q = COPY %3
Return implicit $r0q
...

---
name: no_fold_vgbm_0_noncopy_use
tracksRegLiveness: true
body: |
bb.0:
liveins: $r2d
; CHECK-LABEL: name: no_fold_vgbm_0_noncopy_use
; CHECK: liveins: $r2d
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64bit = COPY $r2d
; CHECK-NEXT: [[COPY1:%[0-9]+]]:addr64bit = COPY [[COPY]]
; CHECK-NEXT: [[VGBM:%[0-9]+]]:vr128bit = VGBM 0
; CHECK-NEXT: Return implicit [[VGBM]]
%0:gr64bit = COPY $r2d
%1:addr64bit = COPY %0
%2:vr128bit = VGBM 0
Return implicit %2
...

---
name: fold_vgbm_0_copyvr128_to_gr64_subreg_h64
tracksRegLiveness: true
body: |
bb.0:
liveins: $r2d
; CHECK-LABEL: name: fold_vgbm_0_copyvr128_to_gr64_subreg_h64
; CHECK: liveins: $r2d
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64bit = COPY $r2d
; CHECK-NEXT: [[COPY1:%[0-9]+]]:addr64bit = COPY [[COPY]]
; CHECK-NEXT: [[VGBM:%[0-9]+]]:vr128bit = VGBM 0
; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr64bit = COPY [[VGBM]].subreg_h64
; CHECK-NEXT: $r0d = COPY [[COPY2]]
; CHECK-NEXT: Return implicit $r0d
%0:gr64bit = COPY $r2d
%1:addr64bit = COPY %0
%2:vr128bit = VGBM 0
%3:gr64bit = COPY %2.subreg_h64
$r0d = COPY %3
Return implicit $r0d
...