added some doxygen on the way
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@115033
91177308-0d34-0410-b5e6-
96231b3b80d8
-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) {
int CmpMask, bool CommonUse) {
- switch (MI.getOpcode()) {
+ switch (MI->getOpcode()) {
case ARM::ANDri:
case ARM::t2ANDri:
case ARM::ANDri:
case ARM::t2ANDri:
- if (CmpMask != MI.getOperand(2).getImm())
+ if (CmpMask != MI->getOperand(2).getImm())
- if (SrcReg == MI.getOperand(CommonUse ? 1 : 0).getReg())
+ if (SrcReg == MI->getOperand(CommonUse ? 1 : 0).getReg())
+ 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);
+ }
// Masked compares sometimes use the same register as the corresponding 'and'.
if (CmpMask != ~0) {
// 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;
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;
if (!isSuitableForMask(PotentialAND, SrcReg, CmpMask, true))
continue;
- SrcReg = PotentialAND.getOperand(0).getReg();
- MI = &PotentialAND;
break;
}
if (!MI) return false;
break;
}
if (!MI) return false;
-; 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* }
%struct.Foo = type { i8* }
%0 = ptrtoint i8* %tmp2 to i32
; CHECK: ands r12, r12, #3
%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
%and = and i32 %0, 3
%tst = icmp eq i32 %and, 0