From ef86b4067cc152356eca7afa2673c438c80b0a40 Mon Sep 17 00:00:00 2001 From: Quentin Colombet Date: Wed, 23 Apr 2014 20:43:38 +0000 Subject: [PATCH] [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. llvm-svn: 207020 --- llvm/lib/Target/ARM64/ARM64InstrInfo.cpp | 13 ++++++-- llvm/test/CodeGen/ARM64/ands-bad-peephole.ll | 31 ++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 llvm/test/CodeGen/ARM64/ands-bad-peephole.ll diff --git a/llvm/lib/Target/ARM64/ARM64InstrInfo.cpp b/llvm/lib/Target/ARM64/ARM64InstrInfo.cpp index 2c2b3ec19c67..6a86723e04da 100644 --- a/llvm/lib/Target/ARM64/ARM64InstrInfo.cpp +++ b/llvm/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/llvm/test/CodeGen/ARM64/ands-bad-peephole.ll b/llvm/test/CodeGen/ARM64/ands-bad-peephole.ll new file mode 100644 index 000000000000..34d6287b8b43 --- /dev/null +++ b/llvm/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. +; +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 +}