@@ -2803,11 +2803,10 @@ static bool tryBitfieldInsertOpFromOrAndImm(SDNode *N, SelectionDAG *CurDAG) {
2803
2803
return true ;
2804
2804
}
2805
2805
2806
- static bool isWorthFoldingIntoOrrWithLeftShift (SDValue Dst,
2807
- SelectionDAG *CurDAG,
2808
- SDValue &LeftShiftedOperand,
2809
- uint64_t &LeftShiftAmount) {
2810
- // Avoid folding Dst into ORR-with-left-shift if Dst has other uses than ORR.
2806
+ static bool isWorthFoldingIntoOrrWithShift (SDValue Dst, SelectionDAG *CurDAG,
2807
+ SDValue &ShiftedOperand,
2808
+ uint64_t &ShiftAmount) {
2809
+ // Avoid folding Dst into ORR-with-shift if Dst has other uses than ORR.
2811
2810
if (!Dst.hasOneUse ())
2812
2811
return false ;
2813
2812
@@ -2852,23 +2851,32 @@ static bool isWorthFoldingIntoOrrWithLeftShift(SDValue Dst,
2852
2851
VT),
2853
2852
CurDAG->getTargetConstant (
2854
2853
SrlImm + NumTrailingZeroInShiftedMask + MaskWidth - 1 , DL, VT));
2855
- LeftShiftedOperand = SDValue (UBFMNode, 0 );
2856
- LeftShiftAmount = NumTrailingZeroInShiftedMask;
2854
+ ShiftedOperand = SDValue (UBFMNode, 0 );
2855
+ ShiftAmount = NumTrailingZeroInShiftedMask;
2857
2856
return true ;
2858
2857
}
2859
2858
}
2860
- } else if (isOpcWithIntImmediate (Dst.getNode (), ISD::SHL, ShlImm)) {
2861
- LeftShiftedOperand = Dst.getOperand (0 );
2862
- LeftShiftAmount = ShlImm;
2859
+ return false ;
2860
+ }
2861
+
2862
+ if (isOpcWithIntImmediate (Dst.getNode (), ISD::SHL, ShlImm)) {
2863
+ ShiftedOperand = Dst.getOperand (0 );
2864
+ ShiftAmount = ShlImm;
2865
+ return true ;
2866
+ }
2867
+
2868
+ uint64_t SrlImm;
2869
+ if (isOpcWithIntImmediate (Dst.getNode (), ISD::SRL, SrlImm)) {
2870
+ ShiftedOperand = Dst.getOperand (0 );
2871
+ ShiftAmount = AArch64_AM::getShifterImm (AArch64_AM::LSR, SrlImm);
2863
2872
return true ;
2864
2873
}
2865
- // FIXME: Extend the implementation to optimize if Dst is an SRL node.
2866
2874
return false ;
2867
2875
}
2868
2876
2869
- static bool tryOrrWithLeftShift (SDNode *N, SDValue OrOpd0, SDValue OrOpd1,
2870
- SDValue Src, SDValue Dst, SelectionDAG *CurDAG,
2871
- const bool BiggerPattern) {
2877
+ static bool tryOrrWithShift (SDNode *N, SDValue OrOpd0, SDValue OrOpd1,
2878
+ SDValue Src, SDValue Dst, SelectionDAG *CurDAG,
2879
+ const bool BiggerPattern) {
2872
2880
EVT VT = N->getValueType (0 );
2873
2881
assert ((VT == MVT::i32 || VT == MVT::i64 ) &&
2874
2882
" Expect result type to be i32 or i64 since N is combinable to BFM" );
@@ -2890,13 +2898,13 @@ static bool tryOrrWithLeftShift(SDNode *N, SDValue OrOpd0, SDValue OrOpd1,
2890
2898
// one node (from Rd), ORR is better since it has higher throughput and
2891
2899
// smaller latency than BFM on many AArch64 processors (and for the rest
2892
2900
// ORR is at least as good as BFM).
2893
- SDValue LeftShiftedOperand ;
2894
- uint64_t LeftShiftAmount ;
2895
- if (isWorthFoldingIntoOrrWithLeftShift (Dst, CurDAG, LeftShiftedOperand ,
2896
- LeftShiftAmount )) {
2901
+ SDValue ShiftedOperand ;
2902
+ uint64_t ShiftAmount ;
2903
+ if (isWorthFoldingIntoOrrWithShift (Dst, CurDAG, ShiftedOperand ,
2904
+ ShiftAmount )) {
2897
2905
unsigned OrrOpc = (VT == MVT::i32 ) ? AArch64::ORRWrs : AArch64::ORRXrs;
2898
- SDValue Ops[] = {OrOpd0, LeftShiftedOperand ,
2899
- CurDAG->getTargetConstant (LeftShiftAmount , DL, VT)};
2906
+ SDValue Ops[] = {OrOpd0, ShiftedOperand ,
2907
+ CurDAG->getTargetConstant (ShiftAmount , DL, VT)};
2900
2908
CurDAG->SelectNodeTo (N, OrrOpc, VT, Ops);
2901
2909
return true ;
2902
2910
}
@@ -2907,7 +2915,6 @@ static bool tryOrrWithLeftShift(SDNode *N, SDValue OrOpd0, SDValue OrOpd1,
2907
2915
assert ((!BiggerPattern) && " BiggerPattern should be handled above" );
2908
2916
2909
2917
uint64_t ShlImm;
2910
- // FIXME: Extend the implementation if OrOpd0 is an SRL node.
2911
2918
if (isOpcWithIntImmediate (OrOpd0.getNode (), ISD::SHL, ShlImm) &&
2912
2919
OrOpd0.getOperand (0 ) == Src && OrOpd0.hasOneUse ()) {
2913
2920
unsigned OrrOpc = (VT == MVT::i32 ) ? AArch64::ORRWrs : AArch64::ORRXrs;
@@ -3022,11 +3029,9 @@ static bool tryBitfieldInsertOpFromOr(SDNode *N, const APInt &UsefulBits,
3022
3029
Dst = OrOpd1Val;
3023
3030
3024
3031
// Before selecting ISD::OR node to AArch64::BFM, see if an AArch64::ORR
3025
- // with left-shifted operand is more efficient.
3026
- // FIXME: Extend this to compare AArch64::BFM and AArch64::ORR with
3027
- // right-shifted operand as well.
3028
- if (tryOrrWithLeftShift (N, OrOpd0Val, OrOpd1Val, Src, Dst, CurDAG,
3029
- BiggerPattern))
3032
+ // with shifted operand is more efficient.
3033
+ if (tryOrrWithShift (N, OrOpd0Val, OrOpd1Val, Src, Dst, CurDAG,
3034
+ BiggerPattern))
3030
3035
return true ;
3031
3036
3032
3037
// both parts match
0 commit comments