From 44a931919d2cfda9468d04975a980dee12cc529b Mon Sep 17 00:00:00 2001 From: Rose Date: Fri, 21 Jun 2024 15:26:02 -0400 Subject: [PATCH] [AArch64] Use isKnownNonZero to optimize to cmn instead of cmp --- .../Target/AArch64/AArch64ISelLowering.cpp | 49 ++- llvm/test/CodeGen/AArch64/cmp-chains.ll | 3 +- llvm/test/CodeGen/AArch64/cmp-select-sign.ll | 3 +- llvm/test/CodeGen/AArch64/cmp-to-cmn.ll | 313 ++++++++++-------- 4 files changed, 219 insertions(+), 149 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index acce9515e832cb..93486b77fcff99 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -3396,9 +3396,11 @@ static bool isLegalArithImmed(uint64_t C) { // So, finally, the only LLVM-native comparisons that don't mention C and V // are SETEQ and SETNE. They're the only ones we can safely use CMN for in // the absence of information about op2. -static bool isCMN(SDValue Op, ISD::CondCode CC) { +static bool isCMN(SDValue Op, SDValue CheckedVal, ISD::CondCode CC, + SelectionDAG &DAG) { return Op.getOpcode() == ISD::SUB && isNullConstant(Op.getOperand(0)) && - (CC == ISD::SETEQ || CC == ISD::SETNE); + (CC == ISD::SETEQ || CC == ISD::SETNE || + DAG.isKnownNeverZero(CheckedVal)); } static SDValue emitStrictFPComparison(SDValue LHS, SDValue RHS, const SDLoc &dl, @@ -3443,15 +3445,26 @@ static SDValue emitComparison(SDValue LHS, SDValue RHS, ISD::CondCode CC, // register to WZR/XZR if it ends up being unused. unsigned Opcode = AArch64ISD::SUBS; - if (isCMN(RHS, CC)) { + if (isCMN(RHS, RHS.getOperand(1), CC, DAG)) { // Can we combine a (CMP op1, (sub 0, op2) into a CMN instruction ? Opcode = AArch64ISD::ADDS; RHS = RHS.getOperand(1); - } else if (isCMN(LHS, CC)) { + } else if (isCMN(LHS, RHS, CC, DAG) && + (!isUnsignedIntSetCC(CC) && + isCMN(LHS, LHS.getOperand(1), CC, DAG))) { // As we are looking for EQ/NE compares, the operands can be commuted ; can // we combine a (CMP (sub 0, op1), op2) into a CMN instruction ? + // Not swapping operands, but negation requires inversion + CC = ISD::getSetCCSwappedOperands(CC); Opcode = AArch64ISD::ADDS; LHS = LHS.getOperand(1); + } else if (isCMN(LHS, LHS.getOperand(1), CC, DAG)) { + // As we are looking for EQ/NE compares, the operands can be commuted ; can + // we combine a (CMP (sub 0, op1), op2) into a CMN instruction ? + std::swap(LHS, RHS); + CC = ISD::getSetCCSwappedOperands(CC); + Opcode = AArch64ISD::ADDS; + RHS = RHS.getOperand(1); } else if (isNullConstant(RHS) && !isUnsignedIntSetCC(CC)) { if (LHS.getOpcode() == ISD::AND) { // Similarly, (CMP (and X, Y), 0) can be implemented with a TST @@ -3551,8 +3564,19 @@ static SDValue emitConditionalComparison(SDValue LHS, SDValue RHS, } } else if (RHS.getOpcode() == ISD::SUB) { SDValue SubOp0 = RHS.getOperand(0); - if (isNullConstant(SubOp0) && (CC == ISD::SETEQ || CC == ISD::SETNE)) { + if (isNullConstant(SubOp0) && (CC == ISD::SETEQ || CC == ISD::SETNE || + DAG.isKnownNeverZero(RHS.getOperand(1)))) { + // See emitComparison() on why we can only do this for SETEQ and SETNE. + Opcode = AArch64ISD::CCMN; + RHS = RHS.getOperand(1); + } + } else if (LHS.getOpcode() == ISD::SUB) { + SDValue SubOp0 = LHS.getOperand(0); + if (isNullConstant(SubOp0) && (CC == ISD::SETEQ || CC == ISD::SETNE || + DAG.isKnownNeverZero(LHS.getOperand(1)))) { // See emitComparison() on why we can only do this for SETEQ and SETNE. + std::swap(LHS, RHS); + CC = ISD::getSetCCSwappedOperands(CC); Opcode = AArch64ISD::CCMN; RHS = RHS.getOperand(1); } @@ -3871,10 +3895,17 @@ static SDValue getAArch64Cmp(SDValue LHS, SDValue RHS, ISD::CondCode CC, // cmp w13, w12 // can be turned into: // cmp w12, w11, lsl #1 - if (!isa(RHS) || !isLegalArithImmed(RHS->getAsZExtVal())) { - SDValue TheLHS = isCMN(LHS, CC) ? LHS.getOperand(1) : LHS; - - if (getCmpOperandFoldingProfit(TheLHS) > getCmpOperandFoldingProfit(RHS)) { + if (!isa(RHS) || (!isLegalArithImmed(RHS->getAsZExtVal()) && + !isLegalArithImmed(-RHS->getAsZExtVal()))) { + bool IsLHSCMN = + (!isa(RHS) && isCMN(RHS, RHS.getOperand(1), CC, DAG)); + bool IsRHSCMN = isCMN(RHS, RHS.getOperand(1), CC, DAG); + SDValue TheLHS = IsLHSCMN ? LHS.getOperand(1) : LHS; + SDValue TheRHS = IsRHSCMN ? RHS.getOperand(1) : RHS; + // We save a neg when we do cmn instead of cmp, so add 1 if that is what we + // did. + if ((getCmpOperandFoldingProfit(TheLHS) + (IsLHSCMN ? 1 : 0)) > + getCmpOperandFoldingProfit(TheRHS) + (IsRHSCMN ? 1 : 0)) { std::swap(LHS, RHS); CC = ISD::getSetCCSwappedOperands(CC); } diff --git a/llvm/test/CodeGen/AArch64/cmp-chains.ll b/llvm/test/CodeGen/AArch64/cmp-chains.ll index d51c9c946f4677..4ea515911b0c51 100644 --- a/llvm/test/CodeGen/AArch64/cmp-chains.ll +++ b/llvm/test/CodeGen/AArch64/cmp-chains.ll @@ -263,8 +263,7 @@ define i32 @neg_range_int_cmn(i32 %a, i32 %b, i32 %c) { ; SDISEL-LABEL: neg_range_int_cmn: ; SDISEL: // %bb.0: ; SDISEL-NEXT: orr w8, w2, #0x1 -; SDISEL-NEXT: neg w8, w8 -; SDISEL-NEXT: cmp w8, w0 +; SDISEL-NEXT: cmn w0, w8 ; SDISEL-NEXT: ccmn w1, #3, #0, le ; SDISEL-NEXT: csel w0, w1, w0, gt ; SDISEL-NEXT: ret diff --git a/llvm/test/CodeGen/AArch64/cmp-select-sign.ll b/llvm/test/CodeGen/AArch64/cmp-select-sign.ll index ca20a7a435a648..036d8202a22b31 100644 --- a/llvm/test/CodeGen/AArch64/cmp-select-sign.ll +++ b/llvm/test/CodeGen/AArch64/cmp-select-sign.ll @@ -266,8 +266,7 @@ define i32 @or_neg(i32 %x, i32 %y) { ; CHECK-LABEL: or_neg: ; CHECK: // %bb.0: ; CHECK-NEXT: orr w8, w0, #0x1 -; CHECK-NEXT: neg w8, w8 -; CHECK-NEXT: cmp w8, w1 +; CHECK-NEXT: cmn w1, w8 ; CHECK-NEXT: cset w0, gt ; CHECK-NEXT: ret %3 = or i32 %x, 1 diff --git a/llvm/test/CodeGen/AArch64/cmp-to-cmn.ll b/llvm/test/CodeGen/AArch64/cmp-to-cmn.ll index 6da98142573f60..2a28213fa100a9 100644 --- a/llvm/test/CodeGen/AArch64/cmp-to-cmn.ll +++ b/llvm/test/CodeGen/AArch64/cmp-to-cmn.ll @@ -1,12 +1,14 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 ; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" target triple = "arm64" define i1 @test_EQ_IllEbT(i64 %a, i64 %b) { -; CHECK-LABEL: test_EQ_IllEbT -; CHECK: cmn x1, x0 -; CHECK-NEXT: cset w0, eq -; CHECK-NEXT: ret +; CHECK-LABEL: test_EQ_IllEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: cmn x1, x0 +; CHECK-NEXT: cset w0, eq +; CHECK-NEXT: ret entry: %add = sub i64 0, %b %cmp = icmp eq i64 %add, %a @@ -14,10 +16,11 @@ entry: } define i1 @test_EQ_IliEbT(i64 %a, i32 %b) { -; CHECK-LABEL: test_EQ_IliEbT -; CHECK: cmn x0, w1, sxtw -; CHECK-NEXT: cset w0, eq -; CHECK-NEXT: ret +; CHECK-LABEL: test_EQ_IliEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: cmn x0, w1, sxtw +; CHECK-NEXT: cset w0, eq +; CHECK-NEXT: ret entry: %conv = sext i32 %b to i64 %add = sub i64 0, %a @@ -26,10 +29,12 @@ entry: } define i1 @test_EQ_IlsEbT(i64 %a, i16 %b) { -; CHECK-LABEL: test_EQ_IlsEbT -; CHECK: cmn x0, w1, sxth -; CHECK-NEXT: cset w0, eq -; CHECK-NEXT: ret +; CHECK-LABEL: test_EQ_IlsEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: cmn x0, w1, sxth +; CHECK-NEXT: cset w0, eq +; CHECK-NEXT: ret entry: %conv = sext i16 %b to i64 %add = sub i64 0, %a @@ -38,10 +43,12 @@ entry: } define i1 @test_EQ_IlcEbT(i64 %a, i8 %b) { -; CHECK-LABEL: test_EQ_IlcEbT -; CHECK: cmn x0, w1, uxtb -; CHECK-NEXT: cset w0, eq -; CHECK-NEXT: ret +; CHECK-LABEL: test_EQ_IlcEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: cmn x0, w1, uxtb +; CHECK-NEXT: cset w0, eq +; CHECK-NEXT: ret entry: %conv = zext i8 %b to i64 %add = sub i64 0, %a @@ -50,10 +57,11 @@ entry: } define i1 @test_EQ_IilEbT(i32 %a, i64 %b) { -; CHECK-LABEL: test_EQ_IilEbT -; CHECK: cmn x1, w0, sxtw -; CHECK-NEXT: cset w0, eq -; CHECK-NEXT: ret +; CHECK-LABEL: test_EQ_IilEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: cmn x1, w0, sxtw +; CHECK-NEXT: cset w0, eq +; CHECK-NEXT: ret entry: %conv = sext i32 %a to i64 %add = sub i64 0, %b @@ -62,10 +70,11 @@ entry: } define i1 @test_EQ_IiiEbT(i32 %a, i32 %b) { -; CHECK-LABEL: test_EQ_IiiEbT -; CHECK: cmn w1, w0 -; CHECK-NEXT: cset w0, eq -; CHECK-NEXT: ret +; CHECK-LABEL: test_EQ_IiiEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: cmn w1, w0 +; CHECK-NEXT: cset w0, eq +; CHECK-NEXT: ret entry: %add = sub i32 0, %b %cmp = icmp eq i32 %add, %a @@ -73,10 +82,11 @@ entry: } define i1 @test_EQ_IisEbT(i32 %a, i16 %b) { -; CHECK-LABEL: test_EQ_IisEbT -; CHECK: cmn w0, w1, sxth -; CHECK-NEXT: cset w0, eq -; CHECK-NEXT: ret +; CHECK-LABEL: test_EQ_IisEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: cmn w0, w1, sxth +; CHECK-NEXT: cset w0, eq +; CHECK-NEXT: ret entry: %conv = sext i16 %b to i32 %add = sub i32 0, %a @@ -85,10 +95,11 @@ entry: } define i1 @test_EQ_IicEbT(i32 %a, i8 %b) { -; CHECK-LABEL: test_EQ_IicEbT -; CHECK: cmn w0, w1, uxtb -; CHECK-NEXT: cset w0, eq -; CHECK-NEXT: ret +; CHECK-LABEL: test_EQ_IicEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: cmn w0, w1, uxtb +; CHECK-NEXT: cset w0, eq +; CHECK-NEXT: ret entry: %conv = zext i8 %b to i32 %add = sub i32 0, %a @@ -97,10 +108,12 @@ entry: } define i1 @test_EQ_IslEbT(i16 %a, i64 %b) { -; CHECK-LABEL: test_EQ_IslEbT -; CHECK: cmn x1, w0, sxth -; CHECK-NEXT: cset w0, eq -; CHECK-NEXT: ret +; CHECK-LABEL: test_EQ_IslEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0 +; CHECK-NEXT: cmn x1, w0, sxth +; CHECK-NEXT: cset w0, eq +; CHECK-NEXT: ret entry: %conv = sext i16 %a to i64 %add = sub i64 0, %b @@ -109,10 +122,11 @@ entry: } define i1 @test_EQ_IsiEbT(i16 %a, i32 %b) { -; CHECK-LABEL: test_EQ_IsiEbT -; CHECK: cmn w1, w0, sxth -; CHECK-NEXT: cset w0, eq -; CHECK-NEXT: ret +; CHECK-LABEL: test_EQ_IsiEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: cmn w1, w0, sxth +; CHECK-NEXT: cset w0, eq +; CHECK-NEXT: ret entry: %conv = sext i16 %a to i32 %add = sub i32 0, %b @@ -121,11 +135,12 @@ entry: } define i1 @test_EQ_IssEbT(i16 %a, i16 %b) { -; CHECK-LABEL: test_EQ_IssEbT -; CHECK: sxth w8, w1 -; CHECK-NEXT: cmn w8, w0, sxth -; CHECK-NEXT: cset w0, eq -; CHECK-NEXT: ret +; CHECK-LABEL: test_EQ_IssEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: sxth w8, w0 +; CHECK-NEXT: cmn w8, w1, sxth +; CHECK-NEXT: cset w0, eq +; CHECK-NEXT: ret entry: %conv = sext i16 %a to i32 %conv1 = sext i16 %b to i32 @@ -135,11 +150,12 @@ entry: } define i1 @test_EQ_IscEbT(i16 %a, i8 %b) { -; CHECK-LABEL: test_EQ_IscEbT -; CHECK: and w8, w1, #0xff -; CHECK-NEXT: cmn w8, w0, sxth -; CHECK-NEXT: cset w0, eq -; CHECK-NEXT: ret +; CHECK-LABEL: test_EQ_IscEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: sxth w8, w0 +; CHECK-NEXT: cmn w8, w1, uxtb +; CHECK-NEXT: cset w0, eq +; CHECK-NEXT: ret entry: %conv = sext i16 %a to i32 %conv1 = zext i8 %b to i32 @@ -149,10 +165,12 @@ entry: } define i1 @test_EQ_IclEbT(i8 %a, i64 %b) { -; CHECK-LABEL: test_EQ_IclEbT -; CHECK: cmn x1, w0, uxtb -; CHECK-NEXT: cset w0, eq -; CHECK-NEXT: ret +; CHECK-LABEL: test_EQ_IclEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0 +; CHECK-NEXT: cmn x1, w0, uxtb +; CHECK-NEXT: cset w0, eq +; CHECK-NEXT: ret entry: %conv = zext i8 %a to i64 %add = sub i64 0, %b @@ -161,10 +179,11 @@ entry: } define i1 @test_EQ_IciEbT(i8 %a, i32 %b) { -; CHECK-LABEL: test_EQ_IciEbT -; CHECK: cmn w1, w0, uxtb -; CHECK-NEXT: cset w0, eq -; CHECK-NEXT: ret +; CHECK-LABEL: test_EQ_IciEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: cmn w1, w0, uxtb +; CHECK-NEXT: cset w0, eq +; CHECK-NEXT: ret entry: %conv = zext i8 %a to i32 %add = sub i32 0, %b @@ -173,11 +192,12 @@ entry: } define i1 @test_EQ_IcsEbT(i8 %a, i16 %b) { -; CHECK-LABEL: test_EQ_IcsEbT -; CHECK: sxth w8, w1 -; CHECK-NEXT: cmn w8, w0, uxtb -; CHECK-NEXT: cset w0, eq -; CHECK-NEXT: ret +; CHECK-LABEL: test_EQ_IcsEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: and w8, w0, #0xff +; CHECK-NEXT: cmn w8, w1, sxth +; CHECK-NEXT: cset w0, eq +; CHECK-NEXT: ret entry: %conv = zext i8 %a to i32 %conv1 = sext i16 %b to i32 @@ -187,11 +207,12 @@ entry: } define i1 @test_EQ_IccEbT(i8 %a, i8 %b) { -; CHECK-LABEL: test_EQ_IccEbT -; CHECK: and w8, w1, #0xff -; CHECK-NEXT: cmn w8, w0, uxtb -; CHECK-NEXT: cset w0, eq -; CHECK-NEXT: ret +; CHECK-LABEL: test_EQ_IccEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: and w8, w0, #0xff +; CHECK-NEXT: cmn w8, w1, uxtb +; CHECK-NEXT: cset w0, eq +; CHECK-NEXT: ret entry: %conv = zext i8 %a to i32 %conv1 = zext i8 %b to i32 @@ -201,10 +222,11 @@ entry: } define i1 @test_NE_IllEbT(i64 %a, i64 %b) { -; CHECK-LABEL: test_NE_IllEbT -; CHECK: cmn x1, x0 -; CHECK-NEXT: cset w0, ne -; CHECK-NEXT: ret +; CHECK-LABEL: test_NE_IllEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: cmn x1, x0 +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret entry: %add = sub i64 0, %b %cmp = icmp ne i64 %add, %a @@ -212,10 +234,11 @@ entry: } define i1 @test_NE_IliEbT(i64 %a, i32 %b) { -; CHECK-LABEL: test_NE_IliEbT -; CHECK: cmn x0, w1, sxtw -; CHECK-NEXT: cset w0, ne -; CHECK-NEXT: ret +; CHECK-LABEL: test_NE_IliEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: cmn x0, w1, sxtw +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret entry: %conv = sext i32 %b to i64 %add = sub i64 0, %a @@ -224,10 +247,12 @@ entry: } define i1 @test_NE_IlsEbT(i64 %a, i16 %b) { -; CHECK-LABEL: test_NE_IlsEbT -; CHECK: cmn x0, w1, sxth -; CHECK-NEXT: cset w0, ne -; CHECK-NEXT: ret +; CHECK-LABEL: test_NE_IlsEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: cmn x0, w1, sxth +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret entry: %conv = sext i16 %b to i64 %add = sub i64 0, %a @@ -236,10 +261,12 @@ entry: } define i1 @test_NE_IlcEbT(i64 %a, i8 %b) { -; CHECK-LABEL: test_NE_IlcEbT -; CHECK: cmn x0, w1, uxtb -; CHECK-NEXT: cset w0, ne -; CHECK-NEXT: ret +; CHECK-LABEL: test_NE_IlcEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: cmn x0, w1, uxtb +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret entry: %conv = zext i8 %b to i64 %add = sub i64 0, %a @@ -248,10 +275,11 @@ entry: } define i1 @test_NE_IilEbT(i32 %a, i64 %b) { -; CHECK-LABEL: test_NE_IilEbT -; CHECK: cmn x1, w0, sxtw -; CHECK-NEXT: cset w0, ne -; CHECK-NEXT: ret +; CHECK-LABEL: test_NE_IilEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: cmn x1, w0, sxtw +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret entry: %conv = sext i32 %a to i64 %add = sub i64 0, %b @@ -260,10 +288,11 @@ entry: } define i1 @test_NE_IiiEbT(i32 %a, i32 %b) { -; CHECK-LABEL: test_NE_IiiEbT -; CHECK: cmn w1, w0 -; CHECK-NEXT: cset w0, ne -; CHECK-NEXT: ret +; CHECK-LABEL: test_NE_IiiEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: cmn w1, w0 +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret entry: %add = sub i32 0, %b %cmp = icmp ne i32 %add, %a @@ -271,10 +300,11 @@ entry: } define i1 @test_NE_IisEbT(i32 %a, i16 %b) { -; CHECK-LABEL: test_NE_IisEbT -; CHECK: cmn w0, w1, sxth -; CHECK-NEXT: cset w0, ne -; CHECK-NEXT: ret +; CHECK-LABEL: test_NE_IisEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: cmn w0, w1, sxth +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret entry: %conv = sext i16 %b to i32 %add = sub i32 0, %a @@ -283,10 +313,11 @@ entry: } define i1 @test_NE_IicEbT(i32 %a, i8 %b) { -; CHECK-LABEL: test_NE_IicEbT -; CHECK: cmn w0, w1, uxtb -; CHECK-NEXT: cset w0, ne -; CHECK-NEXT: ret +; CHECK-LABEL: test_NE_IicEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: cmn w0, w1, uxtb +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret entry: %conv = zext i8 %b to i32 %add = sub i32 0, %a @@ -295,10 +326,12 @@ entry: } define i1 @test_NE_IslEbT(i16 %a, i64 %b) { -; CHECK-LABEL: test_NE_IslEbT -; CHECK: cmn x1, w0, sxth -; CHECK-NEXT: cset w0, ne -; CHECK-NEXT: ret +; CHECK-LABEL: test_NE_IslEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0 +; CHECK-NEXT: cmn x1, w0, sxth +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret entry: %conv = sext i16 %a to i64 %add = sub i64 0, %b @@ -307,10 +340,11 @@ entry: } define i1 @test_NE_IsiEbT(i16 %a, i32 %b) { -; CHECK-LABEL: test_NE_IsiEbT -; CHECK: cmn w1, w0, sxth -; CHECK-NEXT: cset w0, ne -; CHECK-NEXT: ret +; CHECK-LABEL: test_NE_IsiEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: cmn w1, w0, sxth +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret entry: %conv = sext i16 %a to i32 %add = sub i32 0, %b @@ -319,11 +353,12 @@ entry: } define i1 @test_NE_IssEbT(i16 %a, i16 %b) { -; CHECK-LABEL:test_NE_IssEbT -; CHECK: sxth w8, w1 -; CHECK-NEXT: cmn w8, w0, sxth -; CHECK-NEXT: cset w0, ne -; CHECK-NEXT: ret +; CHECK-LABEL: test_NE_IssEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: sxth w8, w0 +; CHECK-NEXT: cmn w8, w1, sxth +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret entry: %conv = sext i16 %a to i32 %conv1 = sext i16 %b to i32 @@ -333,11 +368,12 @@ entry: } define i1 @test_NE_IscEbT(i16 %a, i8 %b) { -; CHECK-LABEL:test_NE_IscEbT -; CHECK: and w8, w1, #0xff -; CHECK-NEXT: cmn w8, w0, sxth -; CHECK-NEXT: cset w0, ne -; CHECK-NEXT: ret +; CHECK-LABEL: test_NE_IscEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: sxth w8, w0 +; CHECK-NEXT: cmn w8, w1, uxtb +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret entry: %conv = sext i16 %a to i32 %conv1 = zext i8 %b to i32 @@ -347,10 +383,12 @@ entry: } define i1 @test_NE_IclEbT(i8 %a, i64 %b) { -; CHECK-LABEL:test_NE_IclEbT -; CHECK: cmn x1, w0, uxtb -; CHECK-NEXT: cset w0, ne -; CHECK-NEXT: ret +; CHECK-LABEL: test_NE_IclEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0 +; CHECK-NEXT: cmn x1, w0, uxtb +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret entry: %conv = zext i8 %a to i64 %add = sub i64 0, %b @@ -359,10 +397,11 @@ entry: } define i1 @test_NE_IciEbT(i8 %a, i32 %b) { -; CHECK-LABEL:test_NE_IciEbT -; CHECK: cmn w1, w0, uxtb -; CHECK-NEXT: cset w0, ne -; CHECK-NEXT: ret +; CHECK-LABEL: test_NE_IciEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: cmn w1, w0, uxtb +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret entry: %conv = zext i8 %a to i32 %add = sub i32 0, %b @@ -371,11 +410,12 @@ entry: } define i1 @test_NE_IcsEbT(i8 %a, i16 %b) { -; CHECK-LABEL:test_NE_IcsEbT -; CHECK: sxth w8, w1 -; CHECK-NEXT: cmn w8, w0, uxtb -; CHECK-NEXT: cset w0, ne -; CHECK-NEXT: ret +; CHECK-LABEL: test_NE_IcsEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: and w8, w0, #0xff +; CHECK-NEXT: cmn w8, w1, sxth +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret entry: %conv = zext i8 %a to i32 %conv1 = sext i16 %b to i32 @@ -385,11 +425,12 @@ entry: } define i1 @test_NE_IccEbT(i8 %a, i8 %b) { -; CHECK-LABEL:test_NE_IccEbT -; CHECK: and w8, w1, #0xff -; CHECK-NEXT: cmn w8, w0, uxtb -; CHECK-NEXT: cset w0, ne -; CHECK-NEXT: ret +; CHECK-LABEL: test_NE_IccEbT: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: and w8, w0, #0xff +; CHECK-NEXT: cmn w8, w1, uxtb +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret entry: %conv = zext i8 %a to i32 %conv1 = zext i8 %b to i32