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 +}