Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
39 changes: 39 additions & 0 deletions llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,18 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
return true;
}

// FIXME: We create a IMPLICIT_DEF and a G_CONSTANT in preISelLower when
// we encounter a G_SPLAT_VECTOR. We cannot select the G_CONSTANT until after
// the MI is lowered, since renderVLOp needs to see the G_CONSTANT. It would
// be nice if the InstructionSelector selected these instructions without
// needing to call select on them explicitly.
if (Opc == RISCV::G_VMV_V_X_VL || Opc == RISCV::G_VFMV_V_F_VL) {
MachineInstr *Passthru = MRI->getVRegDef(MI.getOperand(1).getReg());
MachineInstr *VL = MRI->getVRegDef(MI.getOperand(3).getReg());
if (selectImpl(MI, *CoverageInfo))
return select(*Passthru) && select(*VL);
}

if (selectImpl(MI, *CoverageInfo))
return true;

Expand Down Expand Up @@ -800,6 +812,33 @@ void RISCVInstructionSelector::preISelLower(MachineInstr &MI,
replacePtrWithInt(MI.getOperand(1), MIB);
MI.setDesc(TII.get(TargetOpcode::G_AND));
MRI->setType(DstReg, sXLen);
break;
}
case TargetOpcode::G_SPLAT_VECTOR: {
// Convert integer SPLAT_VECTOR to VMV_V_X_VL and floating-point
// SPLAT_VECTOR to VFMV_V_F_VL to reduce isel burden.
Register Scalar = MI.getOperand(1).getReg();
bool IsGPRSplat = isRegInGprb(Scalar);
const LLT sXLen = LLT::scalar(STI.getXLen());
if (IsGPRSplat && TypeSize::isKnownLT(MRI->getType(Scalar).getSizeInBits(),
sXLen.getSizeInBits()))
Scalar = MIB.buildAnyExt(sXLen, Scalar).getReg(0);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why doesn't this G_ANYEXT need special selection like the passthru and vlmax?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fairly confident that we never hit this case. I brought it over from selectiondag, but still looking for a test case, otherwise I will remove it. Maybe we are already doing it in legalization.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed this case to an assert, since we don't seem to be generating this case yet.


// Convert MI in place, since select function is trying to select this
// instruction.
unsigned Opc = IsGPRSplat ? RISCV::G_VMV_V_X_VL : RISCV::G_VFMV_V_F_VL;
MI.setDesc(TII.get(Opc));
MI.removeOperand(1);
LLT VecTy = MRI->getType(MI.getOperand(0).getReg());
auto Passthru = MIB.buildUndef(VecTy);
auto VLMax = MIB.buildConstant(sXLen, -1);
MRI->setRegBank(Passthru.getReg(0), RBI.getRegBank(RISCV::VRBRegBankID));
MRI->setRegBank(VLMax.getReg(0), RBI.getRegBank(RISCV::GPRBRegBankID));
MachineInstrBuilder(*MI.getMF(), &MI)
.addUse(Passthru.getReg(0))
.addUse(Scalar)
.addUse(VLMax.getReg(0));
break;
}
}
}
Expand Down
16 changes: 16 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrGISel.td
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,22 @@ def G_VMSET_VL : RISCVGenericInstruction {
}
def : GINodeEquiv<G_VMSET_VL, riscv_vmset_vl>;

// Pseudo equivalent to a RISCVISD::VMV_V_X_VL
def G_VMV_V_X_VL : RISCVGenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src);
let hasSideEffects = false;
}
def : GINodeEquiv<G_VMV_V_X_VL, riscv_vmv_v_x_vl>;

// Pseudo equivalent to a RISCVISD::VFMV_V_F_VL
def G_VFMV_V_F_VL : RISCVGenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src);
let hasSideEffects = false;
}
def : GINodeEquiv<G_VFMV_V_F_VL, riscv_vfmv_v_f_vl>;

// Pseudo equivalent to a RISCVISD::SPLAT_VECTOR_SPLIT_I64_VL. There is no
// record to mark as equivalent to using GINodeEquiv because it gets lowered
// before instruction selection.
Expand Down
Loading
Loading