@@ -4839,14 +4839,41 @@ static bool isFloatingPointZero(SDValue Op) {
4839
4839
return false;
4840
4840
}
4841
4841
4842
+ // TODO: This is copied from AArch64TargetLowering.cpp, which only has
4843
+ // ands, subs, and adds affecting flags. In ARM, we have more than that, so this
4844
+ // should be expanded to cover all the cases where we can adjust the condition code
4845
+ // to zero.
4846
+ static bool shouldBeAdjustedToZero(SDValue LHS, APInt C, ISD::CondCode &CC) {
4847
+ // TODO: Cover all cases where a comparison with 0 would be profitable..
4848
+ if (LHS.getOpcode() != ISD::AND)
4849
+ return false;
4850
+
4851
+ if (C.isOne() && (CC == ISD::SETLT || CC == ISD::SETGE)) {
4852
+ CC = (CC == ISD::SETLT) ? ISD::SETLE : ISD::SETGT;
4853
+ return true;
4854
+ }
4855
+
4856
+ if (C.isAllOnes() && (CC == ISD::SETLE || CC == ISD::SETGT)) {
4857
+ CC = (CC == ISD::SETLE) ? ISD::SETLT : ISD::SETGE;
4858
+ return true;
4859
+ }
4860
+
4861
+ return false;
4862
+ }
4863
+
4842
4864
/// Returns appropriate ARM CMP (cmp) and corresponding condition code for
4843
4865
/// the given operands.
4844
4866
SDValue ARMTargetLowering::getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
4845
4867
SDValue &ARMcc, SelectionDAG &DAG,
4846
4868
const SDLoc &dl) const {
4847
4869
if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS.getNode())) {
4848
- unsigned C = RHSC->getZExtValue();
4849
- if (!isLegalICmpImmediate((int32_t)C)) {
4870
+ APInt CInt = RHSC->getAPIntValue();
4871
+ unsigned C = CInt.getZExtValue();
4872
+ if (shouldBeAdjustedToZero(LHS, CInt, CC)) {
4873
+ // Adjust the constant to zero.
4874
+ // CC has already been adjusted.
4875
+ RHS = DAG.getConstant(0, DL, VT);
4876
+ } else if (!isLegalICmpImmediate((int32_t)C)) {
4850
4877
// Constant does not fit, try adjusting it by one.
4851
4878
switch (CC) {
4852
4879
default: break;
0 commit comments