2222#include " llvm/ADT/Statistic.h"
2323#include " llvm/ADT/StringExtras.h"
2424#include " llvm/CodeGen/ISDOpcodes.h"
25+ #include " llvm/CodeGen/MachineInstrBuilder.h"
2526#include " llvm/CodeGen/RuntimeLibcallUtil.h"
2627#include " llvm/CodeGen/SelectionDAGNodes.h"
2728#include " llvm/IR/IRBuilder.h"
@@ -6039,17 +6040,20 @@ static MachineBasicBlock *
60396040emitPseudoXVINSGR2VR (MachineInstr &MI, MachineBasicBlock *BB,
60406041 const LoongArchSubtarget &Subtarget) {
60416042 unsigned InsOp;
6043+ unsigned BroadcastOp;
60426044 unsigned HalfSize;
60436045 switch (MI.getOpcode ()) {
60446046 default :
60456047 llvm_unreachable (" Unexpected opcode" );
60466048 case LoongArch::PseudoXVINSGR2VR_B:
60476049 HalfSize = 16 ;
6048- InsOp = LoongArch::VINSGR2VR_B;
6050+ BroadcastOp = LoongArch::XVREPLGR2VR_B;
6051+ InsOp = LoongArch::XVEXTRINS_B;
60496052 break ;
60506053 case LoongArch::PseudoXVINSGR2VR_H:
60516054 HalfSize = 8 ;
6052- InsOp = LoongArch::VINSGR2VR_H;
6055+ BroadcastOp = LoongArch::XVREPLGR2VR_H;
6056+ InsOp = LoongArch::XVEXTRINS_H;
60536057 break ;
60546058 }
60556059 const TargetInstrInfo *TII = Subtarget.getInstrInfo ();
@@ -6063,37 +6067,41 @@ emitPseudoXVINSGR2VR(MachineInstr &MI, MachineBasicBlock *BB,
60636067 Register Elt = MI.getOperand (2 ).getReg ();
60646068 unsigned Idx = MI.getOperand (3 ).getImm ();
60656069
6066- Register ScratchReg1 = XSrc;
6067- if (Idx >= HalfSize) {
6068- ScratchReg1 = MRI.createVirtualRegister (RC);
6069- BuildMI (*BB, MI, DL, TII->get (LoongArch::XVPERMI_D), ScratchReg1)
6070- .addReg (XSrc)
6071- .addImm (14 );
6072- }
6070+ if (XSrc.isVirtual () && MRI.getVRegDef (XSrc)->isImplicitDef () &&
6071+ Idx < HalfSize) {
6072+ Register ScratchSubReg1 = MRI.createVirtualRegister (SubRC);
6073+ Register ScratchSubReg2 = MRI.createVirtualRegister (SubRC);
60736074
6074- Register ScratchSubReg1 = MRI.createVirtualRegister (SubRC);
6075- Register ScratchSubReg2 = MRI.createVirtualRegister (SubRC);
6076- BuildMI (*BB, MI, DL, TII->get (LoongArch::COPY), ScratchSubReg1)
6077- .addReg (ScratchReg1, 0 , LoongArch::sub_128);
6078- BuildMI (*BB, MI, DL, TII->get (InsOp), ScratchSubReg2)
6079- .addReg (ScratchSubReg1)
6080- .addReg (Elt)
6081- .addImm (Idx >= HalfSize ? Idx - HalfSize : Idx);
6075+ BuildMI (*BB, MI, DL, TII->get (LoongArch::COPY), ScratchSubReg1)
6076+ .addReg (XSrc, 0 , LoongArch::sub_128);
6077+ BuildMI (*BB, MI, DL,
6078+ TII->get (HalfSize == 8 ? LoongArch::VINSGR2VR_H
6079+ : LoongArch::VINSGR2VR_B),
6080+ ScratchSubReg2)
6081+ .addReg (ScratchSubReg1)
6082+ .addReg (Elt)
6083+ .addImm (Idx);
6084+
6085+ BuildMI (*BB, MI, DL, TII->get (LoongArch::SUBREG_TO_REG), XDst)
6086+ .addImm (0 )
6087+ .addReg (ScratchSubReg2)
6088+ .addImm (LoongArch::sub_128);
6089+ } else {
6090+ Register ScratchReg1 = MRI.createVirtualRegister (RC);
6091+ Register ScratchReg2 = MRI.createVirtualRegister (RC);
60826092
6083- Register ScratchReg2 = XDst;
6084- if (Idx >= HalfSize)
6085- ScratchReg2 = MRI.createVirtualRegister (RC);
6093+ BuildMI (*BB, MI, DL, TII->get (BroadcastOp), ScratchReg1).addReg (Elt);
60866094
6087- BuildMI (*BB, MI, DL, TII->get (LoongArch::SUBREG_TO_REG ), ScratchReg2)
6088- . addImm ( 0 )
6089- .addReg (ScratchSubReg2 )
6090- .addImm (LoongArch::sub_128 );
6095+ BuildMI (*BB, MI, DL, TII->get (LoongArch::XVPERMI_Q ), ScratchReg2)
6096+ . addReg (ScratchReg1 )
6097+ .addReg (XSrc )
6098+ .addImm (Idx >= HalfSize ? 48 : 18 );
60916099
6092- if (Idx >= HalfSize)
6093- BuildMI (*BB, MI, DL, TII->get (LoongArch::XVPERMI_Q), XDst)
6100+ BuildMI (*BB, MI, DL, TII->get (InsOp), XDst)
60946101 .addReg (XSrc)
60956102 .addReg (ScratchReg2)
6096- .addImm (2 );
6103+ .addImm ((Idx >= HalfSize ? Idx - HalfSize : Idx) * 17 );
6104+ }
60976105
60986106 MI.eraseFromParent ();
60996107 return BB;
0 commit comments