mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-15 07:59:57 +00:00
improve heuristics to find the 'and' corresponding to 'tst' to also catch opportunities on thumb2
added some doxygen on the way git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@115033 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
afa4163afa
commit
05642a3eba
@ -1433,16 +1433,29 @@ AnalyzeCompare(const MachineInstr *MI, unsigned &SrcReg, int &CmpMask,
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool isSuitableForMask(const MachineInstr &MI, unsigned SrcReg,
|
||||
/// isSuitableForMask - Identify a suitable 'and' instruction that
|
||||
/// operates on the given source register and applies the same mask
|
||||
/// as a 'tst' instruction. Provide a limited look-through for copies.
|
||||
/// When successful, MI will hold the found instruction.
|
||||
static bool isSuitableForMask(MachineInstr *&MI, unsigned SrcReg,
|
||||
int CmpMask, bool CommonUse) {
|
||||
switch (MI.getOpcode()) {
|
||||
switch (MI->getOpcode()) {
|
||||
case ARM::ANDri:
|
||||
case ARM::t2ANDri:
|
||||
if (CmpMask != MI.getOperand(2).getImm())
|
||||
if (CmpMask != MI->getOperand(2).getImm())
|
||||
return false;
|
||||
if (SrcReg == MI.getOperand(CommonUse ? 1 : 0).getReg())
|
||||
if (SrcReg == MI->getOperand(CommonUse ? 1 : 0).getReg())
|
||||
return true;
|
||||
break;
|
||||
case ARM::COPY: {
|
||||
// Walk down one instruction which is potentially an 'and'.
|
||||
const MachineInstr &Copy = *MI;
|
||||
MachineBasicBlock::iterator AND(next(MachineBasicBlock::iterator(MI)));
|
||||
if (AND == MI->getParent()->end()) return false;
|
||||
MI = AND;
|
||||
return isSuitableForMask(MI, Copy.getOperand(0).getReg(),
|
||||
CmpMask, true);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -1467,16 +1480,15 @@ OptimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, int CmpMask,
|
||||
|
||||
// Masked compares sometimes use the same register as the corresponding 'and'.
|
||||
if (CmpMask != ~0) {
|
||||
if (!isSuitableForMask(*MI, SrcReg, CmpMask, false)) {
|
||||
if (!isSuitableForMask(MI, SrcReg, CmpMask, false)) {
|
||||
MI = 0;
|
||||
for (MachineRegisterInfo::use_iterator UI = MRI.use_begin(SrcReg),
|
||||
UE = MRI.use_end(); UI != UE; ++UI) {
|
||||
if (UI->getParent() != CmpInstr->getParent()) continue;
|
||||
MachineInstr &PotentialAND = *UI;
|
||||
MachineInstr *PotentialAND = &*UI;
|
||||
if (!isSuitableForMask(PotentialAND, SrcReg, CmpMask, true))
|
||||
continue;
|
||||
SrcReg = PotentialAND.getOperand(0).getReg();
|
||||
MI = &PotentialAND;
|
||||
MI = PotentialAND;
|
||||
break;
|
||||
}
|
||||
if (!MI) return false;
|
||||
|
@ -1,5 +1,6 @@
|
||||
; RUN: llc < %s -mtriple=arm-apple-darwin | FileCheck %s
|
||||
; RUN: llc < %s -mtriple=thumbv6-apple-darwin | FileCheck -check-prefix=T2 %s
|
||||
; RUN: llc < %s -march=arm | FileCheck %s
|
||||
; RUN: llc < %s -march=thumb | FileCheck -check-prefix=THUMB %s
|
||||
; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck -check-prefix=T2 %s
|
||||
|
||||
%struct.Foo = type { i8* }
|
||||
|
||||
@ -18,13 +19,16 @@ tailrecurse: ; preds = %sw.bb, %entry
|
||||
%0 = ptrtoint i8* %tmp2 to i32
|
||||
|
||||
; CHECK: ands r12, r12, #3
|
||||
; CHECK-NEXT: beq LBB0_2
|
||||
; CHECK-NEXT: beq .LBB0_2
|
||||
|
||||
; T2: movs r5, #3
|
||||
; T2-NEXT: mov r6, r4
|
||||
; T2-NEXT: ands r6, r5
|
||||
; T2-NEXT: tst r4, r5
|
||||
; T2-NEXT: beq LBB0_3
|
||||
; THUMB: movs r5, #3
|
||||
; THUMB-NEXT: mov r6, r4
|
||||
; THUMB-NEXT: ands r6, r5
|
||||
; THUMB-NEXT: tst r4, r5
|
||||
; THUMB-NEXT: beq .LBB0_3
|
||||
|
||||
; T2: ands r12, r12, #3
|
||||
; T2-NEXT: beq .LBB0_3
|
||||
|
||||
%and = and i32 %0, 3
|
||||
%tst = icmp eq i32 %and, 0
|
||||
|
Loading…
Reference in New Issue
Block a user