@@ -3038,49 +3038,61 @@ bool RISCVDAGToDAGISel::SelectAddrRegRegScale(SDValue Addr,
30383038 SDValue &Scale) {
30393039 if (Addr.getOpcode () != ISD::ADD)
30403040 return false ;
3041+ SDValue LHS = Addr.getOperand (0 );
3042+ SDValue RHS = Addr.getOperand (1 );
30413043
30423044 EVT VT = Addr.getSimpleValueType ();
3043- auto UnwrapShl = [this , VT, MaxShiftAmount](SDValue N, SDValue &Index,
3045+ auto SelectShl = [this , VT, MaxShiftAmount](SDValue N, SDValue &Index,
30443046 SDValue &Shift) {
3045- uint64_t ShiftAmt = 0 ;
3046- Index = N;
3047-
3048- if (N.getOpcode () == ISD::SHL && isa<ConstantSDNode>(N.getOperand (1 ))) {
3049- // Only match shifts by a value in range [0, MaxShiftAmount].
3050- if (N.getConstantOperandVal (1 ) <= MaxShiftAmount) {
3051- Index = N.getOperand (0 );
3052- ShiftAmt = N.getConstantOperandVal (1 );
3053- }
3054- }
3047+ if (N.getOpcode () != ISD::SHL || !isa<ConstantSDNode>(N.getOperand (1 )))
3048+ return false ;
3049+
3050+ // Only match shifts by a value in range [0, MaxShiftAmount].
3051+ unsigned ShiftAmt = N.getConstantOperandVal (1 );
3052+ if (ShiftAmt > MaxShiftAmount)
3053+ return false ;
30553054
3055+ Index = N.getOperand (0 );
30563056 Shift = CurDAG->getTargetConstant (ShiftAmt, SDLoc (N), VT);
3057- return ShiftAmt != 0 ;
3057+ return true ;
30583058 };
30593059
3060- if (auto *C1 = dyn_cast<ConstantSDNode>(Addr.getOperand (1 ))) {
3061- SDValue AddrB = Addr.getOperand (0 );
3062- if (AddrB.getOpcode () == ISD::ADD &&
3063- UnwrapShl (AddrB.getOperand (0 ), Index, Scale) &&
3064- !isa<ConstantSDNode>(AddrB.getOperand (1 )) &&
3060+ if (auto *C1 = dyn_cast<ConstantSDNode>(RHS)) {
3061+ if (LHS.getOpcode () == ISD::ADD &&
3062+ SelectShl (LHS.getOperand (0 ), Index, Scale) &&
3063+ !isa<ConstantSDNode>(LHS.getOperand (1 )) &&
30653064 isInt<12 >(C1->getSExtValue ())) {
30663065 // (add (add (shl A C2) B) C1) -> (add (add B C1) (shl A C2))
30673066 SDValue C1Val = CurDAG->getTargetConstant (*C1->getConstantIntValue (),
30683067 SDLoc (Addr), VT);
30693068 Base = SDValue (CurDAG->getMachineNode (RISCV::ADDI, SDLoc (Addr), VT,
3070- AddrB .getOperand (1 ), C1Val),
3069+ LHS .getOperand (1 ), C1Val),
30713070 0 );
30723071 return true ;
30733072 }
3074- } else if (UnwrapShl (Addr.getOperand (0 ), Index, Scale)) {
3075- Base = Addr.getOperand (1 );
3073+
3074+ // Don't match add with constants.
3075+ // FIXME: Is this profitable for large constants that have 0s in the lower
3076+ // 12 bits that we can materialize with LUI?
3077+ return false ;
3078+ }
3079+
3080+ // Try to match a shift on the RHS.
3081+ if (SelectShl (RHS, Index, Scale)) {
3082+ Base = LHS;
30763083 return true ;
3077- } else {
3078- UnwrapShl (Addr.getOperand (1 ), Index, Scale);
3079- Base = Addr.getOperand (0 );
3084+ }
3085+
3086+ // Try to match a shift on the LHS.
3087+ if (SelectShl (LHS, Index, Scale)) {
3088+ Base = RHS;
30803089 return true ;
30813090 }
30823091
3083- return false ;
3092+ Base = LHS;
3093+ Index = RHS;
3094+ Scale = CurDAG->getTargetConstant (0 , SDLoc (Addr), VT);
3095+ return true ;
30843096}
30853097
30863098bool RISCVDAGToDAGISel::SelectAddrRegReg (SDValue Addr, SDValue &Base,
0 commit comments