Skip to content

[RISCV] Match prefetch address with offset #66072

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 20, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
74 changes: 73 additions & 1 deletion llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2229,7 +2229,8 @@ bool RISCVDAGToDAGISel::SelectFrameAddrRegImm(SDValue Addr, SDValue &Base,
// Fold constant addresses.
static bool selectConstantAddr(SelectionDAG *CurDAG, const SDLoc &DL,
const MVT VT, const RISCVSubtarget *Subtarget,
SDValue Addr, SDValue &Base, SDValue &Offset) {
SDValue Addr, SDValue &Base, SDValue &Offset,
bool IsPrefetch = false) {
if (!isa<ConstantSDNode>(Addr))
return false;

Expand All @@ -2241,6 +2242,9 @@ static bool selectConstantAddr(SelectionDAG *CurDAG, const SDLoc &DL,
int64_t Lo12 = SignExtend64<12>(CVal);
int64_t Hi = (uint64_t)CVal - (uint64_t)Lo12;
if (!Subtarget->is64Bit() || isInt<32>(Hi)) {
if (IsPrefetch && (Lo12 & 0b11111) != 0)
return false;

if (Hi) {
int64_t Hi20 = (Hi >> 12) & 0xfffff;
Base = SDValue(
Expand All @@ -2263,6 +2267,8 @@ static bool selectConstantAddr(SelectionDAG *CurDAG, const SDLoc &DL,
if (Seq.back().getOpcode() != RISCV::ADDI)
return false;
Lo12 = Seq.back().getImm();
if (IsPrefetch && (Lo12 & 0b11111) != 0)
return false;

// Drop the last instruction.
Seq.pop_back();
Expand Down Expand Up @@ -2443,6 +2449,72 @@ bool RISCVDAGToDAGISel::SelectAddrRegImm(SDValue Addr, SDValue &Base,
return true;
}

/// Similar to SelectAddrRegImm, except that the least significant 5 bits of
/// Offset shoule be all zeros.
bool RISCVDAGToDAGISel::SelectAddrRegImmLsb00000(SDValue Addr, SDValue &Base,
SDValue &Offset) {
if (SelectAddrFrameIndex(Addr, Base, Offset))
return true;

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

if (CurDAG->isBaseWithConstantOffset(Addr)) {
int64_t CVal = cast<ConstantSDNode>(Addr.getOperand(1))->getSExtValue();
if (isInt<12>(CVal)) {
Base = Addr.getOperand(0);

// Early-out if not a valid offset.
if ((CVal & 0b11111) != 0) {
Base = Addr;
Offset = CurDAG->getTargetConstant(0, DL, VT);
return true;
}

if (auto *FIN = dyn_cast<FrameIndexSDNode>(Base))
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think we can fold a FrameIndex. When the FrameIndex is eliminated won't it modify the constant and potentially create a constant that isn't aligned?

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 think I have handled the case in RISCVRegisterInfo::eliminateFrameIndex?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sorry I missed that change.

Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), VT);
Offset = CurDAG->getTargetConstant(CVal, DL, VT);
return true;
}
}

// Handle ADD with large immediates.
if (Addr.getOpcode() == ISD::ADD && isa<ConstantSDNode>(Addr.getOperand(1))) {
int64_t CVal = cast<ConstantSDNode>(Addr.getOperand(1))->getSExtValue();
assert(!(isInt<12>(CVal) && isInt<12>(CVal)) &&
"simm12 not already handled?");

// Handle immediates in the range [-4096,-2049] or [2017, 4065]. We can save
// one instruction by folding adjustment (-2048 or 2016) into the address.
if ((-2049 >= CVal && CVal >= -4096) || (4065 >= CVal && CVal >= 2017)) {
int64_t Adj = CVal < 0 ? -2048 : 2016;
int64_t AdjustedOffset = CVal - Adj;
Base = SDValue(CurDAG->getMachineNode(
RISCV::ADDI, DL, VT, Addr.getOperand(0),
CurDAG->getTargetConstant(AdjustedOffset, DL, VT)),
0);
Offset = CurDAG->getTargetConstant(Adj, DL, VT);
return true;
}

if (selectConstantAddr(CurDAG, DL, VT, Subtarget, Addr.getOperand(1), Base,
Offset, true)) {
// Insert an ADD instruction with the materialized Hi52 bits.
Base = SDValue(
CurDAG->getMachineNode(RISCV::ADD, DL, VT, Addr.getOperand(0), Base),
0);
return true;
}
}

if (selectConstantAddr(CurDAG, DL, VT, Subtarget, Addr, Base, Offset, true))
return true;

Base = Addr;
Offset = CurDAG->getTargetConstant(0, DL, VT);
return true;
}

bool RISCVDAGToDAGISel::selectShiftMask(SDValue N, unsigned ShiftWidth,
SDValue &ShAmt) {
ShAmt = N;
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
bool SelectAddrRegImmINX(SDValue Addr, SDValue &Base, SDValue &Offset) {
return SelectAddrRegImm(Addr, Base, Offset, true);
}
bool SelectAddrRegImmLsb00000(SDValue Addr, SDValue &Base, SDValue &Offset);

bool SelectAddrRegRegScale(SDValue Addr, unsigned MaxShiftAmount,
SDValue &Base, SDValue &Index, SDValue &Scale);
Expand Down
18 changes: 11 additions & 7 deletions llvm/lib/Target/RISCV/RISCVInstrInfoZicbo.td
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,16 @@ def PREFETCH_W : Prefetch_ri<0b00011, "prefetch.w">, Sched<[]>;
// Patterns
//===----------------------------------------------------------------------===//

def AddrRegImmLsb00000 : ComplexPattern<iPTR, 2, "SelectAddrRegImmLsb00000">;

let Predicates = [HasStdExtZicbop] in {
// FIXME: Match address with offset
def : Pat<(prefetch GPR:$rs1, timm, timm, (i32 0)),
(PREFETCH_I GPR:$rs1, 0)>;
def : Pat<(prefetch GPR:$rs1, (i32 0), timm, (i32 1)),
(PREFETCH_R GPR:$rs1, 0)>;
def : Pat<(prefetch GPR:$rs1, (i32 1), timm, (i32 1)),
(PREFETCH_W GPR:$rs1, 0)>;
def : Pat<(prefetch (AddrRegImmLsb00000 (XLenVT GPR:$rs1), simm12_lsb00000:$imm12),
timm, timm, (i32 0)),
(PREFETCH_I GPR:$rs1, simm12_lsb00000:$imm12)>;
def : Pat<(prefetch (AddrRegImmLsb00000 (XLenVT GPR:$rs1), simm12_lsb00000:$imm12),
(i32 0), timm, (i32 1)),
(PREFETCH_R GPR:$rs1, simm12_lsb00000:$imm12)>;
def : Pat<(prefetch (AddrRegImmLsb00000 (XLenVT GPR:$rs1), simm12_lsb00000:$imm12),
(i32 1), timm, (i32 1)),
(PREFETCH_W GPR:$rs1, simm12_lsb00000:$imm12)>;
}
13 changes: 10 additions & 3 deletions llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -436,9 +436,16 @@ bool RISCVRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
// offset can by construction, at worst, a LUI and a ADD.
int64_t Val = Offset.getFixed();
int64_t Lo12 = SignExtend64<12>(Val);
MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Lo12);
Offset = StackOffset::get((uint64_t)Val - (uint64_t)Lo12,
Offset.getScalable());
if ((MI.getOpcode() == RISCV::PREFETCH_I ||
MI.getOpcode() == RISCV::PREFETCH_R ||
MI.getOpcode() == RISCV::PREFETCH_W) &&
(Lo12 & 0b11111) != 0)
MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0);
else {
MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Lo12);
Offset = StackOffset::get((uint64_t)Val - (uint64_t)Lo12,
Offset.getScalable());
}
}
}

Expand Down
Loading