@@ -3038,49 +3038,61 @@ bool RISCVDAGToDAGISel::SelectAddrRegRegScale(SDValue Addr,
3038
3038
SDValue &Scale) {
3039
3039
if (Addr.getOpcode () != ISD::ADD)
3040
3040
return false ;
3041
+ SDValue LHS = Addr.getOperand (0 );
3042
+ SDValue RHS = Addr.getOperand (1 );
3041
3043
3042
3044
EVT VT = Addr.getSimpleValueType ();
3043
- auto UnwrapShl = [this , VT, MaxShiftAmount](SDValue N, SDValue &Index,
3045
+ auto SelectShl = [this , VT, MaxShiftAmount](SDValue N, SDValue &Index,
3044
3046
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 ;
3055
3054
3055
+ Index = N.getOperand (0 );
3056
3056
Shift = CurDAG->getTargetConstant (ShiftAmt, SDLoc (N), VT);
3057
- return ShiftAmt != 0 ;
3057
+ return true ;
3058
3058
};
3059
3059
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 )) &&
3065
3064
isInt<12 >(C1->getSExtValue ())) {
3066
3065
// (add (add (shl A C2) B) C1) -> (add (add B C1) (shl A C2))
3067
3066
SDValue C1Val = CurDAG->getTargetConstant (*C1->getConstantIntValue (),
3068
3067
SDLoc (Addr), VT);
3069
3068
Base = SDValue (CurDAG->getMachineNode (RISCV::ADDI, SDLoc (Addr), VT,
3070
- AddrB .getOperand (1 ), C1Val),
3069
+ LHS .getOperand (1 ), C1Val),
3071
3070
0 );
3072
3071
return true ;
3073
3072
}
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;
3076
3083
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;
3080
3089
return true ;
3081
3090
}
3082
3091
3083
- return false ;
3092
+ Base = LHS;
3093
+ Index = RHS;
3094
+ Scale = CurDAG->getTargetConstant (0 , SDLoc (Addr), VT);
3095
+ return true ;
3084
3096
}
3085
3097
3086
3098
bool RISCVDAGToDAGISel::SelectAddrRegReg (SDValue Addr, SDValue &Base,
0 commit comments