@@ -795,7 +795,7 @@ static SDValue performORCombine(SDNode *N, SelectionDAG &DAG,
795
795
796
796
SDValue And0 = N->getOperand (0 ), And1 = N->getOperand (1 );
797
797
uint64_t SMPos0, SMSize0, SMPos1, SMSize1;
798
- ConstantSDNode *CN;
798
+ ConstantSDNode *CN, *CN1 ;
799
799
800
800
// See if Op's first operand matches (and $src1 , mask0).
801
801
if (And0.getOpcode () != ISD::AND)
@@ -806,37 +806,71 @@ static SDValue performORCombine(SDNode *N, SelectionDAG &DAG,
806
806
return SDValue ();
807
807
808
808
// See if Op's second operand matches (and (shl $src, pos), mask1).
809
- if (And1.getOpcode () != ISD::AND)
810
- return SDValue ();
809
+ if (And1.getOpcode () == ISD::AND &&
810
+ And1. getOperand ( 0 ). getOpcode () == ISD::SHL) {
811
811
812
- if (!(CN = dyn_cast<ConstantSDNode>(And1.getOperand (1 ))) ||
813
- !isShiftedMask (CN->getZExtValue (), SMPos1, SMSize1))
814
- return SDValue ();
812
+ if (!(CN = dyn_cast<ConstantSDNode>(And1.getOperand (1 ))) ||
813
+ !isShiftedMask (CN->getZExtValue (), SMPos1, SMSize1))
814
+ return SDValue ();
815
815
816
- // The shift masks must have the same position and size.
817
- if (SMPos0 != SMPos1 || SMSize0 != SMSize1)
818
- return SDValue ();
816
+ // The shift masks must have the same position and size.
817
+ if (SMPos0 != SMPos1 || SMSize0 != SMSize1)
818
+ return SDValue ();
819
819
820
- SDValue Shl = And1.getOperand (0 );
821
- if (Shl.getOpcode () != ISD::SHL)
822
- return SDValue ();
820
+ SDValue Shl = And1.getOperand (0 );
823
821
824
- if (!(CN = dyn_cast<ConstantSDNode>(Shl.getOperand (1 ))))
825
- return SDValue ();
822
+ if (!(CN = dyn_cast<ConstantSDNode>(Shl.getOperand (1 ))))
823
+ return SDValue ();
826
824
827
- unsigned Shamt = CN->getZExtValue ();
825
+ unsigned Shamt = CN->getZExtValue ();
828
826
829
- // Return if the shift amount and the first bit position of mask are not the
830
- // same.
831
- EVT ValTy = N->getValueType (0 );
832
- if ((Shamt != SMPos0) || (SMPos0 + SMSize0 > ValTy.getSizeInBits ()))
833
- return SDValue ();
827
+ // Return if the shift amount and the first bit position of mask are not the
828
+ // same.
829
+ EVT ValTy = N->getValueType (0 );
830
+ if ((Shamt != SMPos0) || (SMPos0 + SMSize0 > ValTy.getSizeInBits ()))
831
+ return SDValue ();
834
832
835
- SDLoc DL (N);
836
- return DAG.getNode (MipsISD::Ins, DL, ValTy, Shl.getOperand (0 ),
837
- DAG.getConstant (SMPos0, DL, MVT::i32),
838
- DAG.getConstant (SMSize0, DL, MVT::i32),
839
- And0.getOperand (0 ));
833
+ SDLoc DL (N);
834
+ return DAG.getNode (MipsISD::Ins, DL, ValTy, Shl.getOperand (0 ),
835
+ DAG.getConstant (SMPos0, DL, MVT::i32),
836
+ DAG.getConstant (SMSize0, DL, MVT::i32),
837
+ And0.getOperand (0 ));
838
+ } else {
839
+ // Pattern match DINS.
840
+ // $dst = or (and $src, mask0), mask1
841
+ // where mask0 = ((1 << SMSize0) -1) << SMPos0
842
+ // => dins $dst, $src, pos, size
843
+ if (~CN->getSExtValue () == ((((int64_t )1 << SMSize0) - 1 ) << SMPos0) &&
844
+ ((SMSize0 + SMPos0 <= 64 && Subtarget.hasMips64r2 ()) ||
845
+ (SMSize0 + SMPos0 <= 32 ))) {
846
+ // Check if AND instruction has constant as argument
847
+ bool isConstCase = And1.getOpcode () != ISD::AND;
848
+ if (And1.getOpcode () == ISD::AND) {
849
+ if (!(CN1 = dyn_cast<ConstantSDNode>(And1->getOperand (1 ))))
850
+ return SDValue ();
851
+ } else {
852
+ if (!(CN1 = dyn_cast<ConstantSDNode>(N->getOperand (1 ))))
853
+ return SDValue ();
854
+ }
855
+ SDLoc DL (N);
856
+ EVT ValTy = N->getOperand (0 )->getValueType (0 );
857
+ SDValue Const1;
858
+ SDValue SrlX;
859
+ if (!isConstCase) {
860
+ Const1 = DAG.getConstant (SMPos0, DL, MVT::i32);
861
+ SrlX = DAG.getNode (ISD::SRL, DL, And1->getValueType (0 ), And1, Const1);
862
+ }
863
+ return DAG.getNode (
864
+ MipsISD::Ins, DL, N->getValueType (0 ),
865
+ isConstCase
866
+ ? DAG.getConstant (CN1->getSExtValue () >> SMPos0, DL, ValTy)
867
+ : SrlX,
868
+ DAG.getConstant (SMPos0, DL, MVT::i32),
869
+ DAG.getConstant (SMSize0, DL, MVT::i32), And0->getOperand (0 ));
870
+
871
+ }
872
+ return SDValue ();
873
+ }
840
874
}
841
875
842
876
static SDValue performADDCombine (SDNode *N, SelectionDAG &DAG,
0 commit comments