@@ -2229,7 +2229,8 @@ bool RISCVDAGToDAGISel::SelectFrameAddrRegImm(SDValue Addr, SDValue &Base,
2229
2229
// Fold constant addresses.
2230
2230
static bool selectConstantAddr (SelectionDAG *CurDAG, const SDLoc &DL,
2231
2231
const MVT VT, const RISCVSubtarget *Subtarget,
2232
- SDValue Addr, SDValue &Base, SDValue &Offset) {
2232
+ SDValue Addr, SDValue &Base, SDValue &Offset,
2233
+ bool IsPrefetch = false ) {
2233
2234
if (!isa<ConstantSDNode>(Addr))
2234
2235
return false ;
2235
2236
@@ -2241,6 +2242,9 @@ static bool selectConstantAddr(SelectionDAG *CurDAG, const SDLoc &DL,
2241
2242
int64_t Lo12 = SignExtend64<12 >(CVal);
2242
2243
int64_t Hi = (uint64_t )CVal - (uint64_t )Lo12;
2243
2244
if (!Subtarget->is64Bit () || isInt<32 >(Hi)) {
2245
+ if (IsPrefetch && (Lo12 & 0b11111 ) != 0 )
2246
+ return false ;
2247
+
2244
2248
if (Hi) {
2245
2249
int64_t Hi20 = (Hi >> 12 ) & 0xfffff ;
2246
2250
Base = SDValue (
@@ -2263,6 +2267,8 @@ static bool selectConstantAddr(SelectionDAG *CurDAG, const SDLoc &DL,
2263
2267
if (Seq.back ().getOpcode () != RISCV::ADDI)
2264
2268
return false ;
2265
2269
Lo12 = Seq.back ().getImm ();
2270
+ if (IsPrefetch && (Lo12 & 0b11111 ) != 0 )
2271
+ return false ;
2266
2272
2267
2273
// Drop the last instruction.
2268
2274
Seq.pop_back ();
@@ -2443,6 +2449,72 @@ bool RISCVDAGToDAGISel::SelectAddrRegImm(SDValue Addr, SDValue &Base,
2443
2449
return true ;
2444
2450
}
2445
2451
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
+
2446
2518
bool RISCVDAGToDAGISel::selectShiftMask (SDValue N, unsigned ShiftWidth,
2447
2519
SDValue &ShAmt) {
2448
2520
ShAmt = N;
0 commit comments