From: Gabor Greif Date: Wed, 29 Sep 2010 10:12:08 +0000 (+0000) Subject: improve heuristics to find the 'and' corresponding to 'tst' to also catch opportuniti... X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=05642a3eba3f35aa8fdf6aa16d87561560e60af3;p=oota-llvm.git 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 --- diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index c38b89534bf..26558d900d8 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -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; diff --git a/test/CodeGen/ARM/arm-and-tst-peephole.ll b/test/CodeGen/ARM/arm-and-tst-peephole.ll index 9085b6804c0..8d3c0e013b9 100644 --- a/test/CodeGen/ARM/arm-and-tst-peephole.ll +++ b/test/CodeGen/ARM/arm-and-tst-peephole.ll @@ -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