@@ -880,38 +880,81 @@ static SDValue performANDCombine(SDNode *N, SelectionDAG &DAG,
880
880
static SDValue performORCombine (SDNode *N, SelectionDAG &DAG,
881
881
TargetLowering::DAGCombinerInfo &DCI,
882
882
const MipsSubtarget &Subtarget) {
883
- // Pattern match INS.
884
- // $dst = or (and $src1 , mask0), (and (shl $src, pos), mask1),
885
- // where mask1 = (2**size - 1) << pos, mask0 = ~mask1
886
- // => ins $dst, $src, size, pos, $src1
887
883
if (DCI.isBeforeLegalizeOps () || !Subtarget.hasExtractInsert ())
888
884
return SDValue ();
889
885
890
- SDValue And0 = N->getOperand (0 ), And1 = N->getOperand (1 );
886
+ SDValue FirstOperand = N->getOperand (0 ), SecondOperand = N->getOperand (1 );
891
887
unsigned SMPos0, SMSize0, SMPos1, SMSize1;
892
888
ConstantSDNode *CN, *CN1;
893
889
890
+ if ((FirstOperand.getOpcode () == ISD::AND &&
891
+ SecondOperand.getOpcode () == ISD::SHL) ||
892
+ (FirstOperand.getOpcode () == ISD::SHL &&
893
+ SecondOperand.getOpcode () == ISD::AND)) {
894
+ // Pattern match INS.
895
+ // $dst = or (and $src1, (2**size0 - 1)), (shl $src2, size0)
896
+ // ==> ins $src1, $src2, pos, size, pos = size0, size = 32 - pos;
897
+ // Or:
898
+ // $dst = or (shl $src2, size0), (and $src1, (2**size0 - 1))
899
+ // ==> ins $src1, $src2, pos, size, pos = size0, size = 32 - pos;
900
+ SDValue AndOperand0 = FirstOperand.getOpcode () == ISD::AND
901
+ ? FirstOperand.getOperand (0 )
902
+ : SecondOperand.getOperand (0 );
903
+ SDValue ShlOperand0 = FirstOperand.getOpcode () == ISD::AND
904
+ ? SecondOperand.getOperand (0 )
905
+ : FirstOperand.getOperand (0 );
906
+ SDValue AndMask = FirstOperand.getOpcode () == ISD::AND
907
+ ? FirstOperand.getOperand (1 )
908
+ : SecondOperand.getOperand (1 );
909
+ if (!(CN = dyn_cast<ConstantSDNode>(AndMask)) ||
910
+ !isShiftedMask_64 (CN->getZExtValue (), SMPos0, SMSize0))
911
+ return SDValue ();
912
+
913
+ SDValue ShlShift = FirstOperand.getOpcode () == ISD::AND
914
+ ? SecondOperand.getOperand (1 )
915
+ : FirstOperand.getOperand (1 );
916
+ if (!(CN = dyn_cast<ConstantSDNode>(ShlShift)))
917
+ return SDValue ();
918
+ uint64_t ShlShiftValue = CN->getZExtValue ();
919
+
920
+ if (SMPos0 != 0 || SMSize0 != ShlShiftValue)
921
+ return SDValue ();
922
+
923
+ SDLoc DL (N);
924
+ EVT ValTy = N->getValueType (0 );
925
+ SMPos1 = ShlShiftValue;
926
+ assert (SMPos1 < ValTy.getSizeInBits ());
927
+ SMSize1 = (ValTy == MVT::i64 ? 64 : 32 ) - SMPos1;
928
+ return DAG.getNode (MipsISD::Ins, DL, ValTy, ShlOperand0,
929
+ DAG.getConstant (SMPos1, DL, MVT::i32 ),
930
+ DAG.getConstant (SMSize1, DL, MVT::i32 ), AndOperand0);
931
+ }
932
+
894
933
// See if Op's first operand matches (and $src1 , mask0).
895
- if (And0 .getOpcode () != ISD::AND)
934
+ if (FirstOperand .getOpcode () != ISD::AND)
896
935
return SDValue ();
897
936
898
- if (!(CN = dyn_cast<ConstantSDNode>(And0.getOperand (1 ))) ||
937
+ // Pattern match INS.
938
+ // $dst = or (and $src1 , mask0), (and (shl $src, pos), mask1),
939
+ // where mask1 = (2**size - 1) << pos, mask0 = ~mask1
940
+ // => ins $dst, $src, size, pos, $src1
941
+ if (!(CN = dyn_cast<ConstantSDNode>(FirstOperand.getOperand (1 ))) ||
899
942
!isShiftedMask_64 (~CN->getSExtValue (), SMPos0, SMSize0))
900
943
return SDValue ();
901
944
902
945
// See if Op's second operand matches (and (shl $src, pos), mask1).
903
- if (And1 .getOpcode () == ISD::AND &&
904
- And1 .getOperand (0 ).getOpcode () == ISD::SHL) {
946
+ if (SecondOperand .getOpcode () == ISD::AND &&
947
+ SecondOperand .getOperand (0 ).getOpcode () == ISD::SHL) {
905
948
906
- if (!(CN = dyn_cast<ConstantSDNode>(And1 .getOperand (1 ))) ||
949
+ if (!(CN = dyn_cast<ConstantSDNode>(SecondOperand .getOperand (1 ))) ||
907
950
!isShiftedMask_64 (CN->getZExtValue (), SMPos1, SMSize1))
908
951
return SDValue ();
909
952
910
953
// The shift masks must have the same position and size.
911
954
if (SMPos0 != SMPos1 || SMSize0 != SMSize1)
912
955
return SDValue ();
913
956
914
- SDValue Shl = And1 .getOperand (0 );
957
+ SDValue Shl = SecondOperand .getOperand (0 );
915
958
916
959
if (!(CN = dyn_cast<ConstantSDNode>(Shl.getOperand (1 ))))
917
960
return SDValue ();
@@ -928,7 +971,7 @@ static SDValue performORCombine(SDNode *N, SelectionDAG &DAG,
928
971
return DAG.getNode (MipsISD::Ins, DL, ValTy, Shl.getOperand (0 ),
929
972
DAG.getConstant (SMPos0, DL, MVT::i32 ),
930
973
DAG.getConstant (SMSize0, DL, MVT::i32 ),
931
- And0 .getOperand (0 ));
974
+ FirstOperand .getOperand (0 ));
932
975
} else {
933
976
// Pattern match DINS.
934
977
// $dst = or (and $src, mask0), mask1
@@ -938,9 +981,9 @@ static SDValue performORCombine(SDNode *N, SelectionDAG &DAG,
938
981
((SMSize0 + SMPos0 <= 64 && Subtarget.hasMips64r2 ()) ||
939
982
(SMSize0 + SMPos0 <= 32 ))) {
940
983
// Check if AND instruction has constant as argument
941
- bool isConstCase = And1 .getOpcode () != ISD::AND;
942
- if (And1 .getOpcode () == ISD::AND) {
943
- if (!(CN1 = dyn_cast<ConstantSDNode>(And1 ->getOperand (1 ))))
984
+ bool isConstCase = SecondOperand .getOpcode () != ISD::AND;
985
+ if (SecondOperand .getOpcode () == ISD::AND) {
986
+ if (!(CN1 = dyn_cast<ConstantSDNode>(SecondOperand ->getOperand (1 ))))
944
987
return SDValue ();
945
988
} else {
946
989
if (!(CN1 = dyn_cast<ConstantSDNode>(N->getOperand (1 ))))
@@ -957,7 +1000,8 @@ static SDValue performORCombine(SDNode *N, SelectionDAG &DAG,
957
1000
SDValue SrlX;
958
1001
if (!isConstCase) {
959
1002
Const1 = DAG.getConstant (SMPos0, DL, MVT::i32 );
960
- SrlX = DAG.getNode (ISD::SRL, DL, And1->getValueType (0 ), And1, Const1);
1003
+ SrlX = DAG.getNode (ISD::SRL, DL, SecondOperand->getValueType (0 ),
1004
+ SecondOperand, Const1);
961
1005
}
962
1006
return DAG.getNode (
963
1007
MipsISD::Ins, DL, N->getValueType (0 ),
@@ -968,8 +1012,7 @@ static SDValue performORCombine(SDNode *N, SelectionDAG &DAG,
968
1012
DAG.getConstant (ValTy.getSizeInBits () / 8 < 8 ? SMSize0 & 31
969
1013
: SMSize0,
970
1014
DL, MVT::i32 ),
971
- And0->getOperand (0 ));
972
-
1015
+ FirstOperand->getOperand (0 ));
973
1016
}
974
1017
return SDValue ();
975
1018
}
0 commit comments