Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
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
5 changes: 1 addition & 4 deletions llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,9 +291,6 @@ bool RISCVExpandPseudo::expandRV32ZdinxStore(MachineBasicBlock &MBB,
.setMemRefs(MMOLo);

if (MBBI->getOperand(2).isGlobal() || MBBI->getOperand(2).isCPI()) {
// FIXME: Zdinx RV32 can not work on unaligned scalar memory.
assert(!STI->enableUnalignedScalarMem());

assert(MBBI->getOperand(2).getOffset() % 8 == 0);
MBBI->getOperand(2).setOffset(MBBI->getOperand(2).getOffset() + 4);
BuildMI(MBB, MBBI, DL, TII->get(RISCV::SW))
Expand Down Expand Up @@ -344,7 +341,7 @@ bool RISCVExpandPseudo::expandRV32ZdinxLoad(MachineBasicBlock &MBB,

if (MBBI->getOperand(2).isGlobal() || MBBI->getOperand(2).isCPI()) {
auto Offset = MBBI->getOperand(2).getOffset();
assert(MBBI->getOperand(2).getOffset() % 8 == 0);
assert(Offset % 8 == 0);
MBBI->getOperand(2).setOffset(Offset + 4);
BuildMI(MBB, MBBI, DL, TII->get(RISCV::LW), Hi)
.addReg(MBBI->getOperand(1).getReg())
Expand Down
56 changes: 44 additions & 12 deletions llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2522,7 +2522,8 @@ bool RISCVDAGToDAGISel::SelectFrameAddrRegImm(SDValue Addr, SDValue &Base,
static bool selectConstantAddr(SelectionDAG *CurDAG, const SDLoc &DL,
const MVT VT, const RISCVSubtarget *Subtarget,
SDValue Addr, SDValue &Base, SDValue &Offset,
bool IsPrefetch = false) {
bool IsPrefetch = false,
bool IsRV32Zdinx = false) {
if (!isa<ConstantSDNode>(Addr))
return false;

Expand All @@ -2536,6 +2537,8 @@ static bool selectConstantAddr(SelectionDAG *CurDAG, const SDLoc &DL,
if (!Subtarget->is64Bit() || isInt<32>(Hi)) {
if (IsPrefetch && (Lo12 & 0b11111) != 0)
return false;
if (IsRV32Zdinx && !isInt<12>(Lo12 + 4))
return false;

if (Hi) {
int64_t Hi20 = (Hi >> 12) & 0xfffff;
Expand All @@ -2560,6 +2563,8 @@ static bool selectConstantAddr(SelectionDAG *CurDAG, const SDLoc &DL,
Lo12 = Seq.back().getImm();
if (IsPrefetch && (Lo12 & 0b11111) != 0)
return false;
if (IsRV32Zdinx && !isInt<12>(Lo12 + 4))
return false;

// Drop the last instruction.
Seq.pop_back();
Expand Down Expand Up @@ -2649,20 +2654,44 @@ bool RISCVDAGToDAGISel::SelectAddrRegRegScale(SDValue Addr,
}

bool RISCVDAGToDAGISel::SelectAddrRegImm(SDValue Addr, SDValue &Base,
SDValue &Offset, bool IsINX) {
SDValue &Offset, bool IsRV32Zdinx) {
if (SelectAddrFrameIndex(Addr, Base, Offset))
return true;

SDLoc DL(Addr);
MVT VT = Addr.getSimpleValueType();

if (Addr.getOpcode() == RISCVISD::ADD_LO) {
Base = Addr.getOperand(0);
Offset = Addr.getOperand(1);
return true;
// If this is non RV32Zdinx we can always fold.
if (!IsRV32Zdinx) {
Base = Addr.getOperand(0);
Offset = Addr.getOperand(1);
return true;
}

// For RV32Zdinx we need to have more than 4 byte alignment so we can add 4
// to the offset when we expandin RISCVExpandPseudoInsts.
if (auto *GA = dyn_cast<GlobalAddressSDNode>(Addr.getOperand(1))) {
const DataLayout &DL = CurDAG->getDataLayout();
Align Alignment = commonAlignment(
GA->getGlobal()->getPointerAlignment(DL), GA->getOffset());
if (Alignment > 4) {
Base = Addr.getOperand(0);
Offset = Addr.getOperand(1);
return true;
}
}
if (auto *CP = dyn_cast<ConstantPoolSDNode>(Addr.getOperand(1))) {
Align Alignment = commonAlignment(CP->getAlign(), CP->getOffset());
if (Alignment > 4) {
Base = Addr.getOperand(0);
Offset = Addr.getOperand(1);
return true;
}
}
}

int64_t RV32ZdinxRange = IsINX ? 4 : 0;
int64_t RV32ZdinxRange = IsRV32Zdinx ? 4 : 0;
if (CurDAG->isBaseWithConstantOffset(Addr)) {
int64_t CVal = cast<ConstantSDNode>(Addr.getOperand(1))->getSExtValue();
if (isInt<12>(CVal) && isInt<12>(CVal + RV32ZdinxRange)) {
Expand All @@ -2678,7 +2707,8 @@ bool RISCVDAGToDAGISel::SelectAddrRegImm(SDValue Addr, SDValue &Base,
const DataLayout &DL = CurDAG->getDataLayout();
Align Alignment = commonAlignment(
GA->getGlobal()->getPointerAlignment(DL), GA->getOffset());
if (CVal == 0 || Alignment > CVal) {
if ((CVal == 0 || Alignment > CVal) &&
(!IsRV32Zdinx || Alignment > (CVal + 4))) {
int64_t CombinedOffset = CVal + GA->getOffset();
Base = Base.getOperand(0);
Offset = CurDAG->getTargetGlobalAddress(
Expand All @@ -2705,7 +2735,7 @@ bool RISCVDAGToDAGISel::SelectAddrRegImm(SDValue Addr, SDValue &Base,
// Handle immediates in the range [-4096,-2049] or [2048, 4094]. We can use
// an ADDI for part of the offset and fold the rest into the load/store.
// This mirrors the AddiPair PatFrag in RISCVInstrInfo.td.
if (isInt<12>(CVal / 2) && isInt<12>(CVal - CVal / 2)) {
if (CVal >= -4096 && CVal <= (4094 - RV32ZdinxRange)) {
int64_t Adj = CVal < 0 ? -2048 : 2047;
Base = SDValue(
CurDAG->getMachineNode(
Expand All @@ -2724,7 +2754,7 @@ bool RISCVDAGToDAGISel::SelectAddrRegImm(SDValue Addr, SDValue &Base,
// instructions.
if (isWorthFoldingAdd(Addr) &&
selectConstantAddr(CurDAG, DL, VT, Subtarget, Addr.getOperand(1), Base,
Offset)) {
Offset, /*IsPrefetch=*/false, RV32ZdinxRange)) {
// Insert an ADD instruction with the materialized Hi52 bits.
Base = SDValue(
CurDAG->getMachineNode(RISCV::ADD, DL, VT, Addr.getOperand(0), Base),
Expand All @@ -2733,7 +2763,8 @@ bool RISCVDAGToDAGISel::SelectAddrRegImm(SDValue Addr, SDValue &Base,
}
}

if (selectConstantAddr(CurDAG, DL, VT, Subtarget, Addr, Base, Offset))
if (selectConstantAddr(CurDAG, DL, VT, Subtarget, Addr, Base, Offset,
/*IsPrefetch=*/false, RV32ZdinxRange))
return true;

Base = Addr;
Expand Down Expand Up @@ -2791,7 +2822,7 @@ bool RISCVDAGToDAGISel::SelectAddrRegImmLsb00000(SDValue Addr, SDValue &Base,
}

if (selectConstantAddr(CurDAG, DL, VT, Subtarget, Addr.getOperand(1), Base,
Offset, true)) {
Offset, /*IsPrefetch=*/true)) {
// Insert an ADD instruction with the materialized Hi52 bits.
Base = SDValue(
CurDAG->getMachineNode(RISCV::ADD, DL, VT, Addr.getOperand(0), Base),
Expand All @@ -2800,7 +2831,8 @@ bool RISCVDAGToDAGISel::SelectAddrRegImmLsb00000(SDValue Addr, SDValue &Base,
}
}

if (selectConstantAddr(CurDAG, DL, VT, Subtarget, Addr, Base, Offset, true))
if (selectConstantAddr(CurDAG, DL, VT, Subtarget, Addr, Base, Offset,
/*IsPrefetch=*/true))
return true;

Base = Addr;
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
bool SelectAddrFrameIndex(SDValue Addr, SDValue &Base, SDValue &Offset);
bool SelectFrameAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset);
bool SelectAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset,
bool IsINX = false);
bool SelectAddrRegImmINX(SDValue Addr, SDValue &Base, SDValue &Offset) {
bool IsRV32Zdinx = false);
bool SelectAddrRegImmRV32Zdinx(SDValue Addr, SDValue &Base, SDValue &Offset) {
return SelectAddrRegImm(Addr, Base, Offset, true);
}
bool SelectAddrRegImmLsb00000(SDValue Addr, SDValue &Base, SDValue &Offset);
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/RISCV/RISCVInstrInfoD.td
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def SDT_RISCVSplitF64 : SDTypeProfile<2, 1, [SDTCisVT<0, i32>,
def RISCVBuildPairF64 : SDNode<"RISCVISD::BuildPairF64", SDT_RISCVBuildPairF64>;
def RISCVSplitF64 : SDNode<"RISCVISD::SplitF64", SDT_RISCVSplitF64>;

def AddrRegImmINX : ComplexPattern<iPTR, 2, "SelectAddrRegImmINX">;
def AddrRegImmINX : ComplexPattern<iPTR, 2, "SelectAddrRegImmRV32Zdinx">;

//===----------------------------------------------------------------------===//
// Operand and SDNode transformation definitions.
Expand Down
Loading