Thumb2: When optimizing for size, do not if-convert branches involving comparisons with zero.

This allows the constant island pass to lower these branches to cbn?z
instructions, resulting in a shorter instruction sequence.

Differential Revision: http://reviews.llvm.org/D9183

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235638 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Peter Collingbourne 2015-04-23 20:31:30 +00:00
parent f86c29ea2c
commit d9a479e5a0
4 changed files with 79 additions and 5 deletions

View File

@ -1685,6 +1685,33 @@ isProfitableToIfCvt(MachineBasicBlock &MBB,
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();

View File

@ -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:

View File

@ -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
}

View File

@ -24,14 +24,14 @@ entry:
%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: