Index: lib/Target/ARM/ARMBaseInstrInfo.cpp =================================================================== --- lib/Target/ARM/ARMBaseInstrInfo.cpp +++ lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -1685,6 +1685,33 @@ if (!NumCycles) return false; + // If we are optimizing for size, see if the branch in the predecessor can be + // lowered to cbn?z by the constant island lowering pass, and return false if + // so. This results in a shorter instruction sequence. + const Function *F = MBB.getParent()->getFunction(); + if (F->hasFnAttribute(Attribute::OptimizeForSize) || + F->hasFnAttribute(Attribute::MinSize)) { + MachineBasicBlock *Pred = *MBB.pred_begin(); + if (!Pred->empty()) { + MachineInstr *LastMI = &*Pred->rbegin(); + if (LastMI->getOpcode() == ARM::t2Bcc) { + MachineBasicBlock::iterator CmpMI = LastMI; + if (CmpMI != Pred->begin()) { + --CmpMI; + if (CmpMI->getOpcode() == ARM::tCMPi8 || + CmpMI->getOpcode() == ARM::t2CMPri) { + unsigned Reg = CmpMI->getOperand(0).getReg(); + unsigned PredReg = 0; + ARMCC::CondCodes P = getInstrPredicate(CmpMI, PredReg); + if (P == ARMCC::AL && CmpMI->getOperand(1).getImm() == 0 && + isARMLowRegister(Reg)) + return false; + } + } + } + } + } + // Attempt to estimate the relative costs of predication versus branching. unsigned UnpredCost = Probability.getNumerator() * NumCycles; UnpredCost /= Probability.getDenominator(); Index: test/CodeGen/Thumb2/2011-06-07-TwoAddrEarlyClobber.ll =================================================================== --- test/CodeGen/Thumb2/2011-06-07-TwoAddrEarlyClobber.ll +++ test/CodeGen/Thumb2/2011-06-07-TwoAddrEarlyClobber.ll @@ -3,9 +3,9 @@ %struct.op = type { %struct.op*, %struct.op*, %struct.op* ()*, i32, i16, i16, i8, i8 } ; CHECK: Perl_ck_sort -; CHECK: ldreq -; CHECK: moveq [[REGISTER:(r[0-9]+)|(lr)]] -; CHECK: streq {{(r[0-9])|(lr)}}, {{\[}}[[REGISTER]]{{\]}}, #24 +; CHECK: ldr +; CHECK: mov [[REGISTER:(r[0-9]+)|(lr)]] +; CHECK: str {{(r[0-9])|(lr)}}, {{\[}}[[REGISTER]]{{\]}}, #24 define void @Perl_ck_sort() nounwind optsize { entry: Index: test/CodeGen/Thumb2/ifcvt-compare.ll =================================================================== --- /dev/null +++ test/CodeGen/Thumb2/ifcvt-compare.ll @@ -0,0 +1,47 @@ +; RUN: llc -mtriple=thumbv7-unknown-linux %s -o - | FileCheck %s + +declare void @x() + +define void @f0(i32 %x) optsize { + ; CHECK-LABEL: f0: + ; CHECK: cbnz + %p = icmp eq i32 %x, 0 + br i1 %p, label %t, label %f + +t: + call void @x() + br label %f + +f: + ret void +} + +define void @f1(i32 %x) optsize { + ; CHECK-LABEL: f1: + ; CHECK: cmp r0, #1 + ; CHECK: it eq + %p = icmp eq i32 %x, 1 + br i1 %p, label %t, label %f + +t: + call void @x() + br label %f + +f: + ret void +} + +define void @f2(i32 %x) { + ; CHECK-LABEL: f2: + ; CHECK: cmp r0, #0 + ; CHECK: it eq + %p = icmp eq i32 %x, 0 + br i1 %p, label %t, label %f + +t: + call void @x() + br label %f + +f: + ret void +} Index: test/CodeGen/Thumb2/v8_IT_3.ll =================================================================== --- test/CodeGen/Thumb2/v8_IT_3.ll +++ test/CodeGen/Thumb2/v8_IT_3.ll @@ -24,14 +24,14 @@ %tmp = load i32, i32* @G, align 4 %tmp1 = call i32 @bar(i32 0, i32 0, i32 %tmp) nounwind switch i32 %tmp1, label %bb8 [ - i32 0, label %bb + i32 1, label %bb i32 536870913, label %bb4 i32 536870914, label %bb6 ] bb: %tmp2 = load i32, i32* @G, align 4 - %tmp4 = icmp eq i32 %tmp2, 0 + %tmp4 = icmp eq i32 %tmp2, 1 br i1 %tmp4, label %bb1, label %bb8 bb1: