summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQuentin Colombet <qcolombet@apple.com>2014-04-23 20:43:38 +0000
committerQuentin Colombet <qcolombet@apple.com>2014-04-23 20:43:38 +0000
commit28a24ca47165d035df5c5533071970f96c3b4808 (patch)
tree92ebee1f0c68c8a52ea436e64d93f7d1f1dc336f
parent0f31056e7a29374ce549dbac23996cfd844c8cc9 (diff)
downloadllvm-28a24ca47165d035df5c5533071970f96c3b4808.tar.gz
llvm-28a24ca47165d035df5c5533071970f96c3b4808.tar.bz2
llvm-28a24ca47165d035df5c5533071970f96c3b4808.tar.xz
[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> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207020 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM64/ARM64InstrInfo.cpp13
-rw-r--r--test/CodeGen/ARM64/ands-bad-peephole.ll31
2 files changed, 42 insertions, 2 deletions
diff --git a/lib/Target/ARM64/ARM64InstrInfo.cpp b/lib/Target/ARM64/ARM64InstrInfo.cpp
index 2c2b3ec19c..6a86723e04 100644
--- a/lib/Target/ARM64/ARM64InstrInfo.cpp
+++ b/lib/Target/ARM64/ARM64InstrInfo.cpp
@@ -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;
diff --git a/test/CodeGen/ARM64/ands-bad-peephole.ll b/test/CodeGen/ARM64/ands-bad-peephole.ll
new file mode 100644
index 0000000000..34d6287b8b
--- /dev/null
+++ b/test/CodeGen/ARM64/ands-bad-peephole.ll
@@ -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
+}