[ARM64] Fix the information we give to the peephole optimizer for comparison.

ANDS does not use the same encoding scheme as other xxxS instructions (e.g.,
ADDS). Take that into account to avoid wrong peephole optimization.

<rdar://problem/16693089>

llvm-svn: 207020
This commit is contained in:
Quentin Colombet 2014-04-23 20:43:38 +00:00
parent fcd7401bbf
commit ef86b4067c
2 changed files with 42 additions and 2 deletions

View File

@ -567,15 +567,24 @@ bool ARM64InstrInfo::analyzeCompare(const MachineInstr *MI, unsigned &SrcReg,
return true;
case ARM64::SUBSWri:
case ARM64::ADDSWri:
case ARM64::ANDSWri:
case ARM64::SUBSXri:
case ARM64::ADDSXri:
case ARM64::ANDSXri:
SrcReg = MI->getOperand(1).getReg();
SrcReg2 = 0;
CmpMask = ~0;
CmpValue = MI->getOperand(2).getImm();
return true;
case ARM64::ANDSWri:
case ARM64::ANDSXri:
// ANDS does not use the same encoding scheme as the others xxxS
// instructions.
SrcReg = MI->getOperand(1).getReg();
SrcReg2 = 0;
CmpMask = ~0;
CmpValue = ARM64_AM::decodeLogicalImmediate(
MI->getOperand(2).getImm(),
MI->getOpcode() == ARM64::ANDSWri ? 32 : 64);
return true;
}
return false;

View File

@ -0,0 +1,31 @@
; RUN: llc %s -o - | FileCheck %s
; Check that ANDS (tst) is not merged with ADD when the immediate
; is not 0.
; <rdar://problem/16693089>
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
target triple = "arm64-apple-ios"
; CHECK-LABEL: tst1:
; CHECK: add [[REG:w[0-9]+]], w{{[0-9]+}}, #1
; CHECK: tst [[REG]], #0x1
define void @tst1() {
entry:
br i1 undef, label %for.end, label %for.body
for.body: ; preds = %for.body, %entry
%result.09 = phi i32 [ %add2.result.0, %for.body ], [ 1, %entry ]
%i.08 = phi i32 [ %inc, %for.body ], [ 2, %entry ]
%and = and i32 %i.08, 1
%cmp1 = icmp eq i32 %and, 0
%add2.result.0 = select i1 %cmp1, i32 undef, i32 %result.09
%inc = add nsw i32 %i.08, 1
%cmp = icmp slt i32 %i.08, undef
br i1 %cmp, label %for.body, label %for.cond.for.end_crit_edge
for.cond.for.end_crit_edge: ; preds = %for.body
%add2.result.0.lcssa = phi i32 [ %add2.result.0, %for.body ]
br label %for.end
for.end: ; preds = %for.cond.for.end_crit_edge, %entry
ret void
}