@@ -3976,22 +3976,36 @@ void X86DAGToDAGISel::Select(SDNode *Node) {
3976
3976
3977
3977
// For operations of the form (x << C1) op C2, check if we can use a smaller
3978
3978
// encoding for C2 by transforming it into (x op (C2>>C1)) << C1.
3979
- SDValue N0 = Node->getOperand (0 );
3979
+ SDValue Shift = Node->getOperand (0 );
3980
3980
SDValue N1 = Node->getOperand (1 );
3981
3981
3982
- if (N0->getOpcode () != ISD::SHL || !N0->hasOneUse ())
3982
+ ConstantSDNode *Cst = dyn_cast<ConstantSDNode>(N1);
3983
+ if (!Cst)
3984
+ break ;
3985
+
3986
+ // If we have an any_extend feeding the AND, look through it to see if there
3987
+ // is a shift behind it. But only if the AND doesn't use the extended bits.
3988
+ // FIXME: Generalize this to other ANY_EXTEND than i32 to i64?
3989
+ int64_t Val = Cst->getSExtValue ();
3990
+ bool FoundAnyExtend = false ;
3991
+ if (Shift.getOpcode () == ISD::ANY_EXTEND && Shift.hasOneUse () &&
3992
+ Shift.getOperand (0 ).getSimpleValueType () == MVT::i32 &&
3993
+ isUInt<32 >(Val)) {
3994
+ FoundAnyExtend = true ;
3995
+ Shift = Shift.getOperand (0 );
3996
+ }
3997
+
3998
+ if (Shift.getOpcode () != ISD::SHL || !Shift.hasOneUse ())
3983
3999
break ;
3984
4000
3985
4001
// i8 is unshrinkable, i16 should be promoted to i32.
3986
4002
if (NVT != MVT::i32 && NVT != MVT::i64 )
3987
4003
break ;
3988
4004
3989
- ConstantSDNode *Cst = dyn_cast<ConstantSDNode>(N1);
3990
- ConstantSDNode *ShlCst = dyn_cast<ConstantSDNode>(N0->getOperand (1 ));
3991
- if (!Cst || !ShlCst)
4005
+ ConstantSDNode *ShlCst = dyn_cast<ConstantSDNode>(Shift.getOperand (1 ));
4006
+ if (!ShlCst)
3992
4007
break ;
3993
4008
3994
- int64_t Val = Cst->getSExtValue ();
3995
4009
uint64_t ShAmt = ShlCst->getZExtValue ();
3996
4010
3997
4011
// Make sure that we don't change the operation by removing bits.
@@ -4028,13 +4042,19 @@ void X86DAGToDAGISel::Select(SDNode *Node) {
4028
4042
4029
4043
int64_t ShiftedVal;
4030
4044
if (CanShrinkImmediate (ShiftedVal)) {
4045
+ SDValue X = Shift.getOperand (0 );
4046
+ if (FoundAnyExtend) {
4047
+ SDValue NewX = CurDAG->getNode (ISD::ANY_EXTEND, dl, NVT, X);
4048
+ insertDAGNode (*CurDAG, SDValue (Node, 0 ), NewX);
4049
+ X = NewX;
4050
+ }
4051
+
4031
4052
SDValue NewCst = CurDAG->getConstant (ShiftedVal, dl, NVT);
4032
4053
insertDAGNode (*CurDAG, SDValue (Node, 0 ), NewCst);
4033
- SDValue NewBinOp = CurDAG->getNode (Opcode, dl, NVT, N0->getOperand (0 ),
4034
- NewCst);
4054
+ SDValue NewBinOp = CurDAG->getNode (Opcode, dl, NVT, X, NewCst);
4035
4055
insertDAGNode (*CurDAG, SDValue (Node, 0 ), NewBinOp);
4036
4056
SDValue NewSHL = CurDAG->getNode (ISD::SHL, dl, NVT, NewBinOp,
4037
- N0-> getOperand (1 ));
4057
+ Shift. getOperand (1 ));
4038
4058
ReplaceNode (Node, NewSHL.getNode ());
4039
4059
SelectCode (NewSHL.getNode ());
4040
4060
return ;
0 commit comments