Hi,
I’m trying to replace a shift left instruction with multiple add instructions in LLVM’s RISCV backend, since my target RISCV processor might not contain an implementation of the shift left instruction. For example:
slli x5, x5, 3
should be replaced by
add x5, x5, x5
add x5, x5, x5
add x5, x5, x5
However, everything I’ve tried results in llc either crashing, or outputting just a single replacement add instruction. Here’s what I’ve tried so far - in RISCVTargetLowering::RISCVTargetLowering
:
// Using Expand in place of Custom results in a crash
setOperationAction(ISD::SHL, MVT::i32, Custom);
In RISCVTargetLowering::LowerOperation
:
case ISD::SHL:
return replaceShlWithAdd(Op, DAG);
And
SDValue RISCVTargetLowering::replaceShlWithAdd(SDValue Op, SelectionDAG &DAG) const {
SDLoc DL(Op);
SDValue finalReplacement;
SDValue num = Op.getOperand(0);
EVT VT = num.getValueType();
SDValue shamtOp = Op.getOperand(1);
if (DAG.isConstantIntBuildVectorOrConstantInt(shamtOp)) {
uint64_t shamt = Op.getConstantOperandVal(1);
SmallVector<SDValue, 32> additions;
for (int i = 0; i < shamt; i++) {
SDValue addn = DAG.getNode(ISD::ADD, DL, VT, num, num);
additions.push_back(addn);
num = addn;
}
finalReplacement = DAG.getMergeValues(additions, DL);
// The following didn't work either:
// finalReplacement = DAG.getNode(ISD::TokenFactor, DL, VT, additions);
}
else {
// TODO
}
return finalReplacement;
}
Let me know if any further details are required.
Thanks.