Index: lib/Target/ARM/ARMBaseInstrInfo.cpp =================================================================== --- lib/Target/ARM/ARMBaseInstrInfo.cpp +++ lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -2542,6 +2542,7 @@ return true; case ARM::CMPrr: case ARM::t2CMPrr: + case ARM::tCMPr: SrcReg = MI.getOperand(0).getReg(); SrcReg2 = MI.getOperand(1).getReg(); CmpMask = ~0; @@ -2618,28 +2619,61 @@ /// This function can be extended later on. inline static bool isRedundantFlagInstr(const MachineInstr *CmpI, unsigned SrcReg, unsigned SrcReg2, - int ImmValue, const MachineInstr *OI) { + int ImmValue, const MachineInstr *OI, + bool &IsThumb1) { if ((CmpI->getOpcode() == ARM::CMPrr || CmpI->getOpcode() == ARM::t2CMPrr) && (OI->getOpcode() == ARM::SUBrr || OI->getOpcode() == ARM::t2SUBrr) && ((OI->getOperand(1).getReg() == SrcReg && OI->getOperand(2).getReg() == SrcReg2) || (OI->getOperand(1).getReg() == SrcReg2 && - OI->getOperand(2).getReg() == SrcReg))) + OI->getOperand(2).getReg() == SrcReg))) { + IsThumb1 = false; + return true; + } + + if (CmpI->getOpcode() == ARM::tCMPr && OI->getOpcode() == ARM::tSUBrr && + ((OI->getOperand(2).getReg() == SrcReg && + OI->getOperand(3).getReg() == SrcReg2) || + (OI->getOperand(2).getReg() == SrcReg2 && + OI->getOperand(3).getReg() == SrcReg))) { + IsThumb1 = true; return true; + } if ((CmpI->getOpcode() == ARM::CMPri || CmpI->getOpcode() == ARM::t2CMPri) && (OI->getOpcode() == ARM::SUBri || OI->getOpcode() == ARM::t2SUBri) && OI->getOperand(1).getReg() == SrcReg && - OI->getOperand(2).getImm() == ImmValue) + OI->getOperand(2).getImm() == ImmValue) { + IsThumb1 = false; return true; + } + + if (CmpI->getOpcode() == ARM::tCMPi8 && + (OI->getOpcode() == ARM::tSUBi8 || OI->getOpcode() == ARM::tSUBi3) && + OI->getOperand(2).getReg() == SrcReg && + OI->getOperand(3).getImm() == ImmValue) { + IsThumb1 = true; + return true; + } if ((CmpI->getOpcode() == ARM::CMPrr || CmpI->getOpcode() == ARM::t2CMPrr) && (OI->getOpcode() == ARM::ADDrr || OI->getOpcode() == ARM::t2ADDrr || OI->getOpcode() == ARM::ADDri || OI->getOpcode() == ARM::t2ADDri) && - OI->getOperand(0).isReg() && OI->getOperand(1).isReg() && OI->getOperand(0).getReg() == SrcReg && - OI->getOperand(1).getReg() == SrcReg2) + OI->getOperand(1).getReg() == SrcReg2) { + IsThumb1 = false; + return true; + } + + if (CmpI->getOpcode() == ARM::tCMPr && + (OI->getOpcode() == ARM::tADDi3 || OI->getOpcode() == ARM::tADDi8 || + OI->getOpcode() == ARM::tADDrr) && + OI->getOperand(0).getReg() == SrcReg && + OI->getOperand(2).getReg() == SrcReg2) { + IsThumb1 = true; return true; + } + return false; } @@ -2756,7 +2790,8 @@ // For CMPri w/ CmpValue != 0, a SubAdd may still be a candidate. // Thus we cannot return here. if (CmpInstr.getOpcode() == ARM::CMPri || - CmpInstr.getOpcode() == ARM::t2CMPri) + CmpInstr.getOpcode() == ARM::t2CMPri || + CmpInstr.getOpcode() == ARM::tCMPi8) MI = nullptr; else return false; @@ -2800,11 +2835,13 @@ // Check that CPSR isn't set between the comparison instruction and the one we // want to change. At the same time, search for SubAdd. const TargetRegisterInfo *TRI = &getRegisterInfo(); + bool SubAddIsThumb1 = false; do { const MachineInstr &Instr = *--I; // Check whether CmpInstr can be made redundant by the current instruction. - if (isRedundantFlagInstr(&CmpInstr, SrcReg, SrcReg2, CmpValue, &Instr)) { + if (isRedundantFlagInstr(&CmpInstr, SrcReg, SrcReg2, CmpValue, &Instr, + SubAddIsThumb1)) { SubAdd = &*I; break; } @@ -2828,7 +2865,7 @@ // If we found a SubAdd, use it as it will be "closer" if (SubAdd) { MI = SubAdd; - IsThumb1 = false; + IsThumb1 = SubAddIsThumb1; } // We can't use a predicated instruction - it doesn't always write the flags. @@ -2897,9 +2934,13 @@ // operands will be modified. unsigned Opc = SubAdd->getOpcode(); bool IsSub = Opc == ARM::SUBrr || Opc == ARM::t2SUBrr || - Opc == ARM::SUBri || Opc == ARM::t2SUBri; - if (!IsSub || (SrcReg2 != 0 && SubAdd->getOperand(1).getReg() == SrcReg2 && - SubAdd->getOperand(2).getReg() == SrcReg)) { + Opc == ARM::SUBri || Opc == ARM::t2SUBri || + Opc == ARM::tSUBrr || Opc == ARM::tSUBi3 || + Opc == ARM::tSUBi8; + unsigned OpI = Opc != ARM::tSUBrr ? 1 : 2; + if (!IsSub || + (SrcReg2 != 0 && SubAdd->getOperand(OpI).getReg() == SrcReg2 && + SubAdd->getOperand(OpI + 1).getReg() == SrcReg)) { // VSel doesn't support condition code update. if (IsInstrVSel) return false; @@ -2977,9 +3018,10 @@ ++Next; unsigned SrcReg, SrcReg2; int CmpMask, CmpValue; + bool IsThumb1; if (Next != MI.getParent()->end() && analyzeCompare(*Next, SrcReg, SrcReg2, CmpMask, CmpValue) && - isRedundantFlagInstr(&*Next, SrcReg, SrcReg2, CmpValue, &MI)) + isRedundantFlagInstr(&*Next, SrcReg, SrcReg2, CmpValue, &MI, IsThumb1)) return false; return true; } Index: test/CodeGen/ARM/intrinsics-overflow.ll =================================================================== --- test/CodeGen/ARM/intrinsics-overflow.ll +++ test/CodeGen/ARM/intrinsics-overflow.ll @@ -38,8 +38,7 @@ ; ARM: movvc r[[R0]], #0 ; ARM: mov pc, lr - ; THUMBV6: adds r1, r0, r1 - ; THUMBV6: cmp r1, r0 + ; THUMBV6: adds r0, r0, r1 ; THUMBV6: bvc .LBB1_2 ; THUMBV7: adds r[[R2:[0-9]+]], r[[R0]], r[[R1:[0-9]+]] Index: test/CodeGen/Thumb/peephole-cmp.mir =================================================================== --- test/CodeGen/Thumb/peephole-cmp.mir +++ test/CodeGen/Thumb/peephole-cmp.mir @@ -42,8 +42,7 @@ # CHECK: [[COPY1:%[0-9]+]]:tgpr = COPY $r1 # CHECK-NEXT: [[COPY0:%[0-9]+]]:tgpr = COPY $r0 # CHECK-NEXT: [[ADD:%[0-9]+]]:tgpr, $cpsr = tSUBrr [[COPY1]], [[COPY0]], 14, $noreg -# CHECK-NEXT: tCMPr [[COPY0]], [[COPY1]], 14, $noreg, implicit-def $cpsr -# CHECK-NEXT: tBcc %bb.2, 3, $cpsr +# CHECK-NEXT: tBcc %bb.2, 8, $cpsr ... --- name: test_subrr_c @@ -75,7 +74,6 @@ # CHECK: [[COPY1:%[0-9]+]]:tgpr = COPY $r1 # CHECK-NEXT: [[COPY0:%[0-9]+]]:tgpr = COPY $r0 # CHECK-NEXT: [[ADD:%[0-9]+]]:tgpr, $cpsr = tSUBrr [[COPY0]], [[COPY1]], 14, $noreg -# CHECK-NEXT: tCMPr [[COPY0]], [[COPY1]], 14, $noreg, implicit-def $cpsr # CHECK-NEXT: tBcc %bb.2, 3, $cpsr ... --- @@ -105,7 +103,6 @@ # CHECK-LABEL: name: test_subri3 # CHECK: [[COPY:%[0-9]+]]:tgpr = COPY $r0 # CHECK-NEXT: [[ADD:%[0-9]+]]:tgpr, $cpsr = tSUBi3 [[COPY]], 1, 14, $noreg -# CHECK-NEXT: tCMPi8 [[COPY]], 1, 14, $noreg, implicit-def $cpsr # CHECK-NEXT: tBcc %bb.2, 3, $cpsr ... --- @@ -135,7 +132,6 @@ # CHECK-LABEL: name: test_subri8 # CHECK: [[COPY:%[0-9]+]]:tgpr = COPY $r0 # CHECK-NEXT: [[ADD:%[0-9]+]]:tgpr, $cpsr = tSUBi8 [[COPY]], 1, 14, $noreg -# CHECK-NEXT: tCMPi8 [[COPY]], 1, 14, $noreg, implicit-def $cpsr # CHECK-NEXT: tBcc %bb.2, 3, $cpsr ... --- @@ -168,8 +164,7 @@ # CHECK: [[COPY1:%[0-9]+]]:tgpr = COPY $r1 # CHECK-NEXT: [[COPY0:%[0-9]+]]:tgpr = COPY $r0 # CHECK-NEXT: [[ADD:%[0-9]+]]:tgpr, $cpsr = tADDrr [[COPY1]], [[COPY0]], 14, $noreg -# CHECK-NEXT: tCMPr [[ADD]], [[COPY1]], 14, $noreg, implicit-def $cpsr -# CHECK-NEXT: tBcc %bb.2, 3, $cpsr +# CHECK-NEXT: tBcc %bb.2, 2, $cpsr ... --- name: test_addri3 @@ -198,8 +193,7 @@ # CHECK-LABEL: name: test_addri3 # CHECK: [[COPY:%[0-9]+]]:tgpr = COPY $r0 # CHECK-NEXT: [[ADD:%[0-9]+]]:tgpr, $cpsr = tADDi3 [[COPY]], 1, 14, $noreg -# CHECK-NEXT: tCMPr [[ADD]], [[COPY]], 14, $noreg, implicit-def $cpsr -# CHECK-NEXT: tBcc %bb.2, 3, $cpsr +# CHECK-NEXT: tBcc %bb.2, 2, $cpsr ... --- name: test_addri8 @@ -228,6 +222,5 @@ # CHECK-LABEL: name: test_addri8 # CHECK: [[COPY:%[0-9]+]]:tgpr = COPY $r0 # CHECK-NEXT: [[ADD:%[0-9]+]]:tgpr, $cpsr = tADDi8 [[COPY]], 10, 14, $noreg -# CHECK-NEXT: tCMPr [[ADD]], [[COPY]], 14, $noreg, implicit-def $cpsr -# CHECK-NEXT: tBcc %bb.2, 3, $cpsr +# CHECK-NEXT: tBcc %bb.2, 2, $cpsr ...