Index: lib/Target/ARM/ARMISelLowering.cpp =================================================================== --- lib/Target/ARM/ARMISelLowering.cpp +++ lib/Target/ARM/ARMISelLowering.cpp @@ -3821,6 +3821,7 @@ SDValue ARMTargetLowering::getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC, SDValue &ARMcc, SelectionDAG &DAG, const SDLoc &dl) const { + bool SwapOperands = false; if (ConstantSDNode *RHSC = dyn_cast(RHS.getNode())) { unsigned C = RHSC->getZExtValue(); if (!isLegalICmpImmediate(C)) { @@ -3857,9 +3858,17 @@ break; } } - } + } else if ((ARM_AM::getShiftOpcForNode(LHS.getOpcode()) != ARM_AM::no_shift)&& + (ARM_AM::getShiftOpcForNode(RHS.getOpcode()) == ARM_AM::no_shift)) + // In ARM and Thumb-2, the compare instructions can shift their second + // operand. + SwapOperands = true; ARMCC::CondCodes CondCode = IntCCToARMCC(CC); + if (SwapOperands) { + CondCode = ARMCC::getOppositeCondition(CondCode); + std::swap(LHS, RHS); + } ARMISD::NodeType CompareType; switch (CondCode) { default: Index: test/CodeGen/ARM/cmp-shift-swap.ll =================================================================== --- /dev/null +++ test/CodeGen/ARM/cmp-shift-swap.ll @@ -0,0 +1,35 @@ +; RUN: llc -mtriple=thumbv7m %s -o - | FileCheck %s --check-prefix=CHECK-T2 +; RUN: llc -mtriple=armv7 %s -o - | FileCheck %s + +; CHECK-LABEL: swap_cmp_shl +; CHECK: cmp r1, r0, lsl #11 +; CHECK-T2: cmp.w r1, r0, lsl #11 +define arm_aapcscc i32 @swap_cmp_shl(i32 %a, i32 %b) { +entry: + %add = shl i32 %a, 11 + %cmp = icmp sgt i32 %add, %b + %conv = zext i1 %cmp to i32 + ret i32 %conv +} + +; CHECK-LABEL: swap_cmp_lshr +; CHECK: cmp r1, r0, lsr #11 +; CHECK-T2: cmp.w r1, r0, lsr #11 +define arm_aapcscc i32 @swap_cmp_lshr(i32 %a, i32 %b) { +entry: + %add = lshr i32 %a, 11 + %cmp = icmp sgt i32 %add, %b + %conv = zext i1 %cmp to i32 + ret i32 %conv +} + +; CHECK-LABEL: swap_cmp_ashr +; CHECK: cmp r1, r0, asr #11 +; CHECK-T2: cmp.w r1, r0, asr #11 +define arm_aapcscc i32 @swap_cmp_ashr(i32 %a, i32 %b) { +entry: + %add = ashr i32 %a, 11 + %cmp = icmp sgt i32 %add, %b + %conv = zext i1 %cmp to i32 + ret i32 %conv +}