diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp index 8176eba74b738..3238b62218dba 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -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; @@ -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; +} diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.h b/llvm/lib/Target/SystemZ/SystemZInstrInfo.h index aa10fb5649623..61338b0816155 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.h +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.h @@ -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 diff --git a/llvm/test/CodeGen/SystemZ/fold-copy-vector-immediate.mir b/llvm/test/CodeGen/SystemZ/fold-copy-vector-immediate.mir new file mode 100644 index 0000000000000..2aee0cb521c4c --- /dev/null +++ b/llvm/test/CodeGen/SystemZ/fold-copy-vector-immediate.mir @@ -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 +...