Skip to content

Commit

Permalink
SystemZ: Fold copy of vector immediate to gr128 (#90706)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
arsenm committed May 3, 2024
1 parent ac46eea commit 49c5f4d
Show file tree
Hide file tree
Showing 3 changed files with 243 additions and 0 deletions.
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
...

0 comments on commit 49c5f4d

Please sign in to comment.