aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/RISCV/RISCVISelLowering.cpp')
-rw-r--r--llvm/lib/Target/RISCV/RISCVISelLowering.cpp105
1 files changed, 86 insertions, 19 deletions
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index ff645dea4e7a..658865703079 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -526,6 +526,10 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
{ISD::VP_FPTOSI, ISD::VP_FPTOUI, ISD::VP_TRUNCATE, ISD::VP_SETCC}, VT,
Custom);
setOperationAction(ISD::VECTOR_REVERSE, VT, Custom);
+
+ setOperationPromotedToType(
+ ISD::VECTOR_SPLICE, VT,
+ MVT::getVectorVT(MVT::i8, VT.getVectorElementCount()));
}
for (MVT VT : IntVecVTs) {
@@ -1157,6 +1161,37 @@ bool RISCVTargetLowering::hasBitTest(SDValue X, SDValue Y) const {
return C && C->getAPIntValue().ule(10);
}
+bool RISCVTargetLowering::shouldConvertConstantLoadToIntImm(const APInt &Imm,
+ Type *Ty) const {
+ assert(Ty->isIntegerTy());
+
+ unsigned BitSize = Ty->getIntegerBitWidth();
+ if (BitSize > Subtarget.getXLen())
+ return false;
+
+ // Fast path, assume 32-bit immediates are cheap.
+ int64_t Val = Imm.getSExtValue();
+ if (isInt<32>(Val))
+ return true;
+
+ // A constant pool entry may be more aligned thant he load we're trying to
+ // replace. If we don't support unaligned scalar mem, prefer the constant
+ // pool.
+ // TODO: Can the caller pass down the alignment?
+ if (!Subtarget.enableUnalignedScalarMem())
+ return true;
+
+ // Prefer to keep the load if it would require many instructions.
+ // This uses the same threshold we use for constant pools but doesn't
+ // check useConstantPoolForLargeInts.
+ // TODO: Should we keep the load only when we're definitely going to emit a
+ // constant pool?
+
+ RISCVMatInt::InstSeq Seq =
+ RISCVMatInt::generateInstSeq(Val, Subtarget.getFeatureBits());
+ return Seq.size() <= Subtarget.getMaxBuildIntsCost();
+}
+
bool RISCVTargetLowering::
shouldProduceAndByConstByHoistingConstFromShiftsLHSOfAnd(
SDValue X, ConstantSDNode *XC, ConstantSDNode *CC, SDValue Y,
@@ -1659,7 +1694,7 @@ static SDValue convertFromScalableVector(EVT VT, SDValue V, SelectionDAG &DAG,
/// Return the type of the mask type suitable for masking the provided
/// vector type. This is simply an i1 element type vector of the same
/// (possibly scalable) length.
-static MVT getMaskTypeFor(EVT VecVT) {
+static MVT getMaskTypeFor(MVT VecVT) {
assert(VecVT.isVector());
ElementCount EC = VecVT.getVectorElementCount();
return MVT::getVectorVT(MVT::i1, EC);
@@ -5748,8 +5783,7 @@ SDValue RISCVTargetLowering::lowerVECTOR_SPLICE(SDValue Op,
DAG.getNode(RISCVISD::VSLIDEDOWN_VL, DL, VecVT, DAG.getUNDEF(VecVT), V1,
DownOffset, TrueMask, UpOffset);
return DAG.getNode(RISCVISD::VSLIDEUP_VL, DL, VecVT, SlideDown, V2, UpOffset,
- TrueMask,
- DAG.getTargetConstant(RISCV::VLMaxSentinel, DL, XLenVT));
+ TrueMask, DAG.getRegister(RISCV::X0, XLenVT));
}
SDValue
@@ -8530,12 +8564,6 @@ static unsigned negateFMAOpcode(unsigned Opcode, bool NegMul, bool NegAcc) {
return Opcode;
}
-// Combine (sra (shl X, 32), 32 - C) -> (shl (sext_inreg X, i32), C)
-// FIXME: Should this be a generic combine? There's a similar combine on X86.
-//
-// Also try these folds where an add or sub is in the middle.
-// (sra (add (shl X, 32), C1), 32 - C) -> (shl (sext_inreg (add X, C1), C)
-// (sra (sub C1, (shl X, 32)), 32 - C) -> (shl (sext_inreg (sub C1, X), C)
static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG,
const RISCVSubtarget &Subtarget) {
assert(N->getOpcode() == ISD::SRA && "Unexpected opcode");
@@ -8543,12 +8571,40 @@ static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG,
if (N->getValueType(0) != MVT::i64 || !Subtarget.is64Bit())
return SDValue();
- auto *ShAmtC = dyn_cast<ConstantSDNode>(N->getOperand(1));
- if (!ShAmtC || ShAmtC->getZExtValue() > 32)
+ if (!isa<ConstantSDNode>(N->getOperand(1)))
+ return SDValue();
+ uint64_t ShAmt = N->getConstantOperandVal(1);
+ if (ShAmt > 32)
return SDValue();
SDValue N0 = N->getOperand(0);
+ // Combine (sra (sext_inreg (shl X, C1), i32), C2) ->
+ // (sra (shl X, C1+32), C2+32) so it gets selected as SLLI+SRAI instead of
+ // SLLIW+SRAIW. SLLI+SRAI have compressed forms.
+ if (ShAmt < 32 &&
+ N0.getOpcode() == ISD::SIGN_EXTEND_INREG && N0.hasOneUse() &&
+ cast<VTSDNode>(N0.getOperand(1))->getVT() == MVT::i32 &&
+ N0.getOperand(0).getOpcode() == ISD::SHL && N0.getOperand(0).hasOneUse() &&
+ isa<ConstantSDNode>(N0.getOperand(0).getOperand(1))) {
+ uint64_t LShAmt = N0.getOperand(0).getConstantOperandVal(1);
+ if (LShAmt < 32) {
+ SDLoc ShlDL(N0.getOperand(0));
+ SDValue Shl = DAG.getNode(ISD::SHL, ShlDL, MVT::i64,
+ N0.getOperand(0).getOperand(0),
+ DAG.getConstant(LShAmt + 32, ShlDL, MVT::i64));
+ SDLoc DL(N);
+ return DAG.getNode(ISD::SRA, DL, MVT::i64, Shl,
+ DAG.getConstant(ShAmt + 32, DL, MVT::i64));
+ }
+ }
+
+ // Combine (sra (shl X, 32), 32 - C) -> (shl (sext_inreg X, i32), C)
+ // FIXME: Should this be a generic combine? There's a similar combine on X86.
+ //
+ // Also try these folds where an add or sub is in the middle.
+ // (sra (add (shl X, 32), C1), 32 - C) -> (shl (sext_inreg (add X, C1), C)
+ // (sra (sub C1, (shl X, 32)), 32 - C) -> (shl (sext_inreg (sub C1, X), C)
SDValue Shl;
ConstantSDNode *AddC = nullptr;
@@ -8594,12 +8650,12 @@ static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG,
SDValue SExt = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, MVT::i64, In,
DAG.getValueType(MVT::i32));
- if (ShAmtC->getZExtValue() == 32)
+ if (ShAmt == 32)
return SExt;
return DAG.getNode(
ISD::SHL, DL, MVT::i64, SExt,
- DAG.getConstant(32 - ShAmtC->getZExtValue(), DL, MVT::i64));
+ DAG.getConstant(32 - ShAmt, DL, MVT::i64));
}
SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
@@ -9152,10 +9208,10 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
// FIXME: Support FP.
if (Val.getOpcode() == RISCVISD::VMV_X_S) {
SDValue Src = Val.getOperand(0);
- EVT VecVT = Src.getValueType();
+ MVT VecVT = Src.getSimpleValueType();
EVT MemVT = Store->getMemoryVT();
// The memory VT and the element type must match.
- if (VecVT.getVectorElementType() == MemVT) {
+ if (MemVT == VecVT.getVectorElementType()) {
SDLoc DL(N);
MVT MaskVT = getMaskTypeFor(VecVT);
return DAG.getStoreVP(
@@ -9864,7 +9920,7 @@ EmitLoweredCascadedSelect(MachineInstr &First, MachineInstr &Second,
Register FLHS = First.getOperand(1).getReg();
Register FRHS = First.getOperand(2).getReg();
// Insert appropriate branch.
- BuildMI(ThisMBB, DL, TII.getBrCond(FirstCC))
+ BuildMI(FirstMBB, DL, TII.getBrCond(FirstCC))
.addReg(FLHS)
.addReg(FRHS)
.addMBB(SinkMBB);
@@ -9876,7 +9932,7 @@ EmitLoweredCascadedSelect(MachineInstr &First, MachineInstr &Second,
auto SecondCC = static_cast<RISCVCC::CondCode>(Second.getOperand(3).getImm());
// Insert appropriate branch.
- BuildMI(FirstMBB, DL, TII.getBrCond(SecondCC))
+ BuildMI(ThisMBB, DL, TII.getBrCond(SecondCC))
.addReg(SLHS)
.addReg(SRHS)
.addMBB(SinkMBB);
@@ -9884,9 +9940,9 @@ EmitLoweredCascadedSelect(MachineInstr &First, MachineInstr &Second,
Register DestReg = Second.getOperand(0).getReg();
Register Op2Reg4 = Second.getOperand(4).getReg();
BuildMI(*SinkMBB, SinkMBB->begin(), DL, TII.get(RISCV::PHI), DestReg)
- .addReg(Op1Reg4)
- .addMBB(ThisMBB)
.addReg(Op2Reg4)
+ .addMBB(ThisMBB)
+ .addReg(Op1Reg4)
.addMBB(FirstMBB)
.addReg(Op1Reg5)
.addMBB(SecondMBB);
@@ -12096,6 +12152,17 @@ const MCExpr *RISCVTargetLowering::LowerCustomJumpTableEntry(
return MCSymbolRefExpr::create(MBB->getSymbol(), Ctx);
}
+bool RISCVTargetLowering::isVScaleKnownToBeAPowerOfTwo() const {
+ // We define vscale to be VLEN/RVVBitsPerBlock. VLEN is always a power
+ // of two >= 64, and RVVBitsPerBlock is 64. Thus, vscale must be
+ // a power of two as well.
+ // FIXME: This doesn't work for zve32, but that's already broken
+ // elsewhere for the same reason.
+ assert(Subtarget.getRealMinVLen() >= 64 && "zve32* unsupported");
+ assert(RISCV::RVVBitsPerBlock == 64 && "RVVBitsPerBlock changed, audit needed");
+ return true;
+}
+
bool RISCVTargetLowering::isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
EVT VT) const {
VT = VT.getScalarType();