Skip to content

Commit f24d949

Browse files
authored
[RISCV] Match prefetch address with offset (#66072)
A new ComplexPattern `AddrRegImmLsb00000` is added, which is like `AddrRegImm` except that if the least significant 5 bits isn't all zeros, we will fail back to offset 0.
1 parent 7961fa3 commit f24d949

File tree

5 files changed

+191
-155
lines changed

5 files changed

+191
-155
lines changed

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2229,7 +2229,8 @@ bool RISCVDAGToDAGISel::SelectFrameAddrRegImm(SDValue Addr, SDValue &Base,
22292229
// Fold constant addresses.
22302230
static bool selectConstantAddr(SelectionDAG *CurDAG, const SDLoc &DL,
22312231
const MVT VT, const RISCVSubtarget *Subtarget,
2232-
SDValue Addr, SDValue &Base, SDValue &Offset) {
2232+
SDValue Addr, SDValue &Base, SDValue &Offset,
2233+
bool IsPrefetch = false) {
22332234
if (!isa<ConstantSDNode>(Addr))
22342235
return false;
22352236

@@ -2241,6 +2242,9 @@ static bool selectConstantAddr(SelectionDAG *CurDAG, const SDLoc &DL,
22412242
int64_t Lo12 = SignExtend64<12>(CVal);
22422243
int64_t Hi = (uint64_t)CVal - (uint64_t)Lo12;
22432244
if (!Subtarget->is64Bit() || isInt<32>(Hi)) {
2245+
if (IsPrefetch && (Lo12 & 0b11111) != 0)
2246+
return false;
2247+
22442248
if (Hi) {
22452249
int64_t Hi20 = (Hi >> 12) & 0xfffff;
22462250
Base = SDValue(
@@ -2263,6 +2267,8 @@ static bool selectConstantAddr(SelectionDAG *CurDAG, const SDLoc &DL,
22632267
if (Seq.back().getOpcode() != RISCV::ADDI)
22642268
return false;
22652269
Lo12 = Seq.back().getImm();
2270+
if (IsPrefetch && (Lo12 & 0b11111) != 0)
2271+
return false;
22662272

22672273
// Drop the last instruction.
22682274
Seq.pop_back();
@@ -2443,6 +2449,72 @@ bool RISCVDAGToDAGISel::SelectAddrRegImm(SDValue Addr, SDValue &Base,
24432449
return true;
24442450
}
24452451

2452+
/// Similar to SelectAddrRegImm, except that the least significant 5 bits of
2453+
/// Offset shoule be all zeros.
2454+
bool RISCVDAGToDAGISel::SelectAddrRegImmLsb00000(SDValue Addr, SDValue &Base,
2455+
SDValue &Offset) {
2456+
if (SelectAddrFrameIndex(Addr, Base, Offset))
2457+
return true;
2458+
2459+
SDLoc DL(Addr);
2460+
MVT VT = Addr.getSimpleValueType();
2461+
2462+
if (CurDAG->isBaseWithConstantOffset(Addr)) {
2463+
int64_t CVal = cast<ConstantSDNode>(Addr.getOperand(1))->getSExtValue();
2464+
if (isInt<12>(CVal)) {
2465+
Base = Addr.getOperand(0);
2466+
2467+
// Early-out if not a valid offset.
2468+
if ((CVal & 0b11111) != 0) {
2469+
Base = Addr;
2470+
Offset = CurDAG->getTargetConstant(0, DL, VT);
2471+
return true;
2472+
}
2473+
2474+
if (auto *FIN = dyn_cast<FrameIndexSDNode>(Base))
2475+
Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), VT);
2476+
Offset = CurDAG->getTargetConstant(CVal, DL, VT);
2477+
return true;
2478+
}
2479+
}
2480+
2481+
// Handle ADD with large immediates.
2482+
if (Addr.getOpcode() == ISD::ADD && isa<ConstantSDNode>(Addr.getOperand(1))) {
2483+
int64_t CVal = cast<ConstantSDNode>(Addr.getOperand(1))->getSExtValue();
2484+
assert(!(isInt<12>(CVal) && isInt<12>(CVal)) &&
2485+
"simm12 not already handled?");
2486+
2487+
// Handle immediates in the range [-4096,-2049] or [2017, 4065]. We can save
2488+
// one instruction by folding adjustment (-2048 or 2016) into the address.
2489+
if ((-2049 >= CVal && CVal >= -4096) || (4065 >= CVal && CVal >= 2017)) {
2490+
int64_t Adj = CVal < 0 ? -2048 : 2016;
2491+
int64_t AdjustedOffset = CVal - Adj;
2492+
Base = SDValue(CurDAG->getMachineNode(
2493+
RISCV::ADDI, DL, VT, Addr.getOperand(0),
2494+
CurDAG->getTargetConstant(AdjustedOffset, DL, VT)),
2495+
0);
2496+
Offset = CurDAG->getTargetConstant(Adj, DL, VT);
2497+
return true;
2498+
}
2499+
2500+
if (selectConstantAddr(CurDAG, DL, VT, Subtarget, Addr.getOperand(1), Base,
2501+
Offset, true)) {
2502+
// Insert an ADD instruction with the materialized Hi52 bits.
2503+
Base = SDValue(
2504+
CurDAG->getMachineNode(RISCV::ADD, DL, VT, Addr.getOperand(0), Base),
2505+
0);
2506+
return true;
2507+
}
2508+
}
2509+
2510+
if (selectConstantAddr(CurDAG, DL, VT, Subtarget, Addr, Base, Offset, true))
2511+
return true;
2512+
2513+
Base = Addr;
2514+
Offset = CurDAG->getTargetConstant(0, DL, VT);
2515+
return true;
2516+
}
2517+
24462518
bool RISCVDAGToDAGISel::selectShiftMask(SDValue N, unsigned ShiftWidth,
24472519
SDValue &ShAmt) {
24482520
ShAmt = N;

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
5454
bool SelectAddrRegImmINX(SDValue Addr, SDValue &Base, SDValue &Offset) {
5555
return SelectAddrRegImm(Addr, Base, Offset, true);
5656
}
57+
bool SelectAddrRegImmLsb00000(SDValue Addr, SDValue &Base, SDValue &Offset);
5758

5859
bool SelectAddrRegRegScale(SDValue Addr, unsigned MaxShiftAmount,
5960
SDValue &Base, SDValue &Index, SDValue &Scale);

llvm/lib/Target/RISCV/RISCVInstrInfoZicbo.td

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,16 @@ def PREFETCH_W : Prefetch_ri<0b00011, "prefetch.w">, Sched<[]>;
7373
// Patterns
7474
//===----------------------------------------------------------------------===//
7575

76+
def AddrRegImmLsb00000 : ComplexPattern<iPTR, 2, "SelectAddrRegImmLsb00000">;
77+
7678
let Predicates = [HasStdExtZicbop] in {
77-
// FIXME: Match address with offset
78-
def : Pat<(prefetch GPR:$rs1, timm, timm, (i32 0)),
79-
(PREFETCH_I GPR:$rs1, 0)>;
80-
def : Pat<(prefetch GPR:$rs1, (i32 0), timm, (i32 1)),
81-
(PREFETCH_R GPR:$rs1, 0)>;
82-
def : Pat<(prefetch GPR:$rs1, (i32 1), timm, (i32 1)),
83-
(PREFETCH_W GPR:$rs1, 0)>;
79+
def : Pat<(prefetch (AddrRegImmLsb00000 (XLenVT GPR:$rs1), simm12_lsb00000:$imm12),
80+
timm, timm, (i32 0)),
81+
(PREFETCH_I GPR:$rs1, simm12_lsb00000:$imm12)>;
82+
def : Pat<(prefetch (AddrRegImmLsb00000 (XLenVT GPR:$rs1), simm12_lsb00000:$imm12),
83+
(i32 0), timm, (i32 1)),
84+
(PREFETCH_R GPR:$rs1, simm12_lsb00000:$imm12)>;
85+
def : Pat<(prefetch (AddrRegImmLsb00000 (XLenVT GPR:$rs1), simm12_lsb00000:$imm12),
86+
(i32 1), timm, (i32 1)),
87+
(PREFETCH_W GPR:$rs1, simm12_lsb00000:$imm12)>;
8488
}

llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -436,9 +436,16 @@ bool RISCVRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
436436
// offset can by construction, at worst, a LUI and a ADD.
437437
int64_t Val = Offset.getFixed();
438438
int64_t Lo12 = SignExtend64<12>(Val);
439-
MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Lo12);
440-
Offset = StackOffset::get((uint64_t)Val - (uint64_t)Lo12,
441-
Offset.getScalable());
439+
if ((MI.getOpcode() == RISCV::PREFETCH_I ||
440+
MI.getOpcode() == RISCV::PREFETCH_R ||
441+
MI.getOpcode() == RISCV::PREFETCH_W) &&
442+
(Lo12 & 0b11111) != 0)
443+
MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0);
444+
else {
445+
MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Lo12);
446+
Offset = StackOffset::get((uint64_t)Val - (uint64_t)Lo12,
447+
Offset.getScalable());
448+
}
442449
}
443450
}
444451

0 commit comments

Comments
 (0)