@@ -3983,10 +3983,11 @@ void X86DAGToDAGISel::Select(SDNode *Node) {
3983
3983
if (!Cst)
3984
3984
break ;
3985
3985
3986
+ int64_t Val = Cst->getSExtValue ();
3987
+
3986
3988
// If we have an any_extend feeding the AND, look through it to see if there
3987
3989
// is a shift behind it. But only if the AND doesn't use the extended bits.
3988
3990
// FIXME: Generalize this to other ANY_EXTEND than i32 to i64?
3989
- int64_t Val = Cst->getSExtValue ();
3990
3991
bool FoundAnyExtend = false ;
3991
3992
if (Shift.getOpcode () == ISD::ANY_EXTEND && Shift.hasOneUse () &&
3992
3993
Shift.getOperand (0 ).getSimpleValueType () == MVT::i32 &&
@@ -4041,26 +4042,44 @@ void X86DAGToDAGISel::Select(SDNode *Node) {
4041
4042
};
4042
4043
4043
4044
int64_t ShiftedVal;
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
- }
4045
+ if (!CanShrinkImmediate (ShiftedVal))
4046
+ break ;
4051
4047
4052
- SDValue NewCst = CurDAG->getConstant (ShiftedVal, dl, NVT);
4053
- insertDAGNode (*CurDAG, SDValue (Node, 0 ), NewCst);
4054
- SDValue NewBinOp = CurDAG->getNode (Opcode, dl, NVT, X, NewCst);
4055
- insertDAGNode (*CurDAG, SDValue (Node, 0 ), NewBinOp);
4056
- SDValue NewSHL = CurDAG->getNode (ISD::SHL, dl, NVT, NewBinOp,
4057
- Shift.getOperand (1 ));
4058
- ReplaceNode (Node, NewSHL.getNode ());
4059
- SelectCode (NewSHL.getNode ());
4060
- return ;
4048
+ // Ok, we can reorder to get a smaller immediate.
4049
+
4050
+ // But, its possible the original immediate allowed an AND to become MOVZX.
4051
+ // Doing this late due to avoid the MakedValueIsZero call as late as
4052
+ // possible.
4053
+ if (Opcode == ISD::AND) {
4054
+ // Find the smallest zext this could possibly be.
4055
+ unsigned ZExtWidth = Cst->getAPIntValue ().getActiveBits ();
4056
+ ZExtWidth = PowerOf2Ceil (std::max (ZExtWidth, 8U ));
4057
+
4058
+ // Figure out which bits need to be zero to achieve that mask.
4059
+ APInt NeededMask = APInt::getLowBitsSet (NVT.getSizeInBits (),
4060
+ ZExtWidth);
4061
+ NeededMask &= ~Cst->getAPIntValue ();
4062
+
4063
+ if (CurDAG->MaskedValueIsZero (Node->getOperand (0 ), NeededMask))
4064
+ break ;
4061
4065
}
4062
4066
4063
- break ;
4067
+ SDValue X = Shift.getOperand (0 );
4068
+ if (FoundAnyExtend) {
4069
+ SDValue NewX = CurDAG->getNode (ISD::ANY_EXTEND, dl, NVT, X);
4070
+ insertDAGNode (*CurDAG, SDValue (Node, 0 ), NewX);
4071
+ X = NewX;
4072
+ }
4073
+
4074
+ SDValue NewCst = CurDAG->getConstant (ShiftedVal, dl, NVT);
4075
+ insertDAGNode (*CurDAG, SDValue (Node, 0 ), NewCst);
4076
+ SDValue NewBinOp = CurDAG->getNode (Opcode, dl, NVT, X, NewCst);
4077
+ insertDAGNode (*CurDAG, SDValue (Node, 0 ), NewBinOp);
4078
+ SDValue NewSHL = CurDAG->getNode (ISD::SHL, dl, NVT, NewBinOp,
4079
+ Shift.getOperand (1 ));
4080
+ ReplaceNode (Node, NewSHL.getNode ());
4081
+ SelectCode (NewSHL.getNode ());
4082
+ return ;
4064
4083
}
4065
4084
case X86ISD::SMUL:
4066
4085
// i16/i32/i64 are handled with isel patterns.
0 commit comments