@@ -2522,7 +2522,8 @@ bool RISCVDAGToDAGISel::SelectFrameAddrRegImm(SDValue Addr, SDValue &Base,
2522
2522
static bool selectConstantAddr (SelectionDAG *CurDAG, const SDLoc &DL,
2523
2523
const MVT VT, const RISCVSubtarget *Subtarget,
2524
2524
SDValue Addr, SDValue &Base, SDValue &Offset,
2525
- bool IsPrefetch = false ) {
2525
+ bool IsPrefetch = false ,
2526
+ bool IsRV32Zdinx = false ) {
2526
2527
if (!isa<ConstantSDNode>(Addr))
2527
2528
return false ;
2528
2529
@@ -2536,6 +2537,8 @@ static bool selectConstantAddr(SelectionDAG *CurDAG, const SDLoc &DL,
2536
2537
if (!Subtarget->is64Bit () || isInt<32 >(Hi)) {
2537
2538
if (IsPrefetch && (Lo12 & 0b11111 ) != 0 )
2538
2539
return false ;
2540
+ if (IsRV32Zdinx && !isInt<12 >(Lo12 + 4 ))
2541
+ return false ;
2539
2542
2540
2543
if (Hi) {
2541
2544
int64_t Hi20 = (Hi >> 12 ) & 0xfffff ;
@@ -2560,6 +2563,8 @@ static bool selectConstantAddr(SelectionDAG *CurDAG, const SDLoc &DL,
2560
2563
Lo12 = Seq.back ().getImm ();
2561
2564
if (IsPrefetch && (Lo12 & 0b11111 ) != 0 )
2562
2565
return false ;
2566
+ if (IsRV32Zdinx && !isInt<12 >(Lo12 + 4 ))
2567
+ return false ;
2563
2568
2564
2569
// Drop the last instruction.
2565
2570
Seq.pop_back ();
@@ -2649,20 +2654,44 @@ bool RISCVDAGToDAGISel::SelectAddrRegRegScale(SDValue Addr,
2649
2654
}
2650
2655
2651
2656
bool RISCVDAGToDAGISel::SelectAddrRegImm (SDValue Addr, SDValue &Base,
2652
- SDValue &Offset, bool IsINX ) {
2657
+ SDValue &Offset, bool IsRV32Zdinx ) {
2653
2658
if (SelectAddrFrameIndex (Addr, Base, Offset))
2654
2659
return true ;
2655
2660
2656
2661
SDLoc DL (Addr);
2657
2662
MVT VT = Addr.getSimpleValueType ();
2658
2663
2659
2664
if (Addr.getOpcode () == RISCVISD::ADD_LO) {
2660
- Base = Addr.getOperand (0 );
2661
- Offset = Addr.getOperand (1 );
2662
- return true ;
2665
+ // If this is non RV32Zdinx we can always fold.
2666
+ if (!IsRV32Zdinx) {
2667
+ Base = Addr.getOperand (0 );
2668
+ Offset = Addr.getOperand (1 );
2669
+ return true ;
2670
+ }
2671
+
2672
+ // For RV32Zdinx we need to have more than 4 byte alignment so we can add 4
2673
+ // to the offset when we expand in RISCVExpandPseudoInsts.
2674
+ if (auto *GA = dyn_cast<GlobalAddressSDNode>(Addr.getOperand (1 ))) {
2675
+ const DataLayout &DL = CurDAG->getDataLayout ();
2676
+ Align Alignment = commonAlignment (
2677
+ GA->getGlobal ()->getPointerAlignment (DL), GA->getOffset ());
2678
+ if (Alignment > 4 ) {
2679
+ Base = Addr.getOperand (0 );
2680
+ Offset = Addr.getOperand (1 );
2681
+ return true ;
2682
+ }
2683
+ }
2684
+ if (auto *CP = dyn_cast<ConstantPoolSDNode>(Addr.getOperand (1 ))) {
2685
+ Align Alignment = commonAlignment (CP->getAlign (), CP->getOffset ());
2686
+ if (Alignment > 4 ) {
2687
+ Base = Addr.getOperand (0 );
2688
+ Offset = Addr.getOperand (1 );
2689
+ return true ;
2690
+ }
2691
+ }
2663
2692
}
2664
2693
2665
- int64_t RV32ZdinxRange = IsINX ? 4 : 0 ;
2694
+ int64_t RV32ZdinxRange = IsRV32Zdinx ? 4 : 0 ;
2666
2695
if (CurDAG->isBaseWithConstantOffset (Addr)) {
2667
2696
int64_t CVal = cast<ConstantSDNode>(Addr.getOperand (1 ))->getSExtValue ();
2668
2697
if (isInt<12 >(CVal) && isInt<12 >(CVal + RV32ZdinxRange)) {
@@ -2678,7 +2707,8 @@ bool RISCVDAGToDAGISel::SelectAddrRegImm(SDValue Addr, SDValue &Base,
2678
2707
const DataLayout &DL = CurDAG->getDataLayout ();
2679
2708
Align Alignment = commonAlignment (
2680
2709
GA->getGlobal ()->getPointerAlignment (DL), GA->getOffset ());
2681
- if (CVal == 0 || Alignment > CVal) {
2710
+ if ((CVal == 0 || Alignment > CVal) &&
2711
+ (!IsRV32Zdinx || Alignment > (CVal + 4 ))) {
2682
2712
int64_t CombinedOffset = CVal + GA->getOffset ();
2683
2713
Base = Base.getOperand (0 );
2684
2714
Offset = CurDAG->getTargetGlobalAddress (
@@ -2705,7 +2735,7 @@ bool RISCVDAGToDAGISel::SelectAddrRegImm(SDValue Addr, SDValue &Base,
2705
2735
// Handle immediates in the range [-4096,-2049] or [2048, 4094]. We can use
2706
2736
// an ADDI for part of the offset and fold the rest into the load/store.
2707
2737
// This mirrors the AddiPair PatFrag in RISCVInstrInfo.td.
2708
- if (isInt< 12 >( CVal / 2 ) && isInt< 12 >(CVal - CVal / 2 )) {
2738
+ if (CVal >= - 4096 && CVal <= ( 4094 - RV32ZdinxRange )) {
2709
2739
int64_t Adj = CVal < 0 ? -2048 : 2047 ;
2710
2740
Base = SDValue (
2711
2741
CurDAG->getMachineNode (
@@ -2724,7 +2754,7 @@ bool RISCVDAGToDAGISel::SelectAddrRegImm(SDValue Addr, SDValue &Base,
2724
2754
// instructions.
2725
2755
if (isWorthFoldingAdd (Addr) &&
2726
2756
selectConstantAddr (CurDAG, DL, VT, Subtarget, Addr.getOperand (1 ), Base,
2727
- Offset)) {
2757
+ Offset, /* IsPrefetch= */ false , RV32ZdinxRange )) {
2728
2758
// Insert an ADD instruction with the materialized Hi52 bits.
2729
2759
Base = SDValue (
2730
2760
CurDAG->getMachineNode (RISCV::ADD, DL, VT, Addr.getOperand (0 ), Base),
@@ -2733,7 +2763,8 @@ bool RISCVDAGToDAGISel::SelectAddrRegImm(SDValue Addr, SDValue &Base,
2733
2763
}
2734
2764
}
2735
2765
2736
- if (selectConstantAddr (CurDAG, DL, VT, Subtarget, Addr, Base, Offset))
2766
+ if (selectConstantAddr (CurDAG, DL, VT, Subtarget, Addr, Base, Offset,
2767
+ /* IsPrefetch=*/ false , RV32ZdinxRange))
2737
2768
return true ;
2738
2769
2739
2770
Base = Addr;
@@ -2791,7 +2822,7 @@ bool RISCVDAGToDAGISel::SelectAddrRegImmLsb00000(SDValue Addr, SDValue &Base,
2791
2822
}
2792
2823
2793
2824
if (selectConstantAddr (CurDAG, DL, VT, Subtarget, Addr.getOperand (1 ), Base,
2794
- Offset, true )) {
2825
+ Offset, /* IsPrefetch= */ true )) {
2795
2826
// Insert an ADD instruction with the materialized Hi52 bits.
2796
2827
Base = SDValue (
2797
2828
CurDAG->getMachineNode (RISCV::ADD, DL, VT, Addr.getOperand (0 ), Base),
@@ -2800,7 +2831,8 @@ bool RISCVDAGToDAGISel::SelectAddrRegImmLsb00000(SDValue Addr, SDValue &Base,
2800
2831
}
2801
2832
}
2802
2833
2803
- if (selectConstantAddr (CurDAG, DL, VT, Subtarget, Addr, Base, Offset, true ))
2834
+ if (selectConstantAddr (CurDAG, DL, VT, Subtarget, Addr, Base, Offset,
2835
+ /* IsPrefetch=*/ true ))
2804
2836
return true ;
2805
2837
2806
2838
Base = Addr;
0 commit comments