[llvm] 0cd8063 - [AArch64] Genereate CCMP from And CSel

David Green via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 2 05:48:21 PST 2022


Author: David Green
Date: 2022-02-02T13:48:16Z
New Revision: 0cd8063960259903b5bbb0accc3259accdb1bd6c

URL: https://github.com/llvm/llvm-project/commit/0cd8063960259903b5bbb0accc3259accdb1bd6c
DIFF: https://github.com/llvm/llvm-project/commit/0cd8063960259903b5bbb0accc3259accdb1bd6c.diff

LOG: [AArch64] Genereate CCMP from And CSel

LLVM has a couple of ways of producing ccmp - either from chains in isel
or from a later ifcvt style pass. This adds a simple DAG combine to
capture more cases, converting and(csel(0, 1, cc0), csel(0, 1, cc1))
into a csel(ccmp(.., cc0)), depending on cc1 (a SUBS in this case).

Differential Revision: https://reviews.llvm.org/D118327

Added: 
    

Modified: 
    llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
    llvm/test/CodeGen/AArch64/andcompare.ll
    llvm/test/CodeGen/AArch64/arm64-ccmp.ll
    llvm/test/CodeGen/AArch64/select-with-and-or.ll
    llvm/test/CodeGen/AArch64/umulo-128-legalisation-lowering.ll
    llvm/test/CodeGen/AArch64/vec_umulo.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 5c43d8a0d4bc6..638bbd74c152d 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -14068,11 +14068,62 @@ static SDValue performSVEAndCombine(SDNode *N,
   return SDValue();
 }
 
+// Given a tree of and(csel(0, 1, cc0), csel(0, 1, cc1)), we may be able to
+// convert to csel(ccmp(.., cc0)), depending on cc1.
+static SDValue PerformANDCSELCombine(SDNode *N, SelectionDAG &DAG) {
+  EVT VT = N->getValueType(0);
+  SDValue CSel0 = N->getOperand(0);
+  SDValue CSel1 = N->getOperand(1);
+
+  if (CSel0.getOpcode() != AArch64ISD::CSEL ||
+      CSel1.getOpcode() != AArch64ISD::CSEL)
+    return SDValue();
+
+  if (!CSel0->hasOneUse() || !CSel1->hasOneUse())
+    return SDValue();
+
+  if (!isNullConstant(CSel0.getOperand(0)) ||
+      !isOneConstant(CSel0.getOperand(1)) ||
+      !isNullConstant(CSel1.getOperand(0)) ||
+      !isOneConstant(CSel1.getOperand(1)))
+    return SDValue();
+
+  SDValue Cmp0 = CSel0.getOperand(3);
+  SDValue Cmp1 = CSel1.getOperand(3);
+  AArch64CC::CondCode CC0 = (AArch64CC::CondCode)CSel0.getConstantOperandVal(2);
+  AArch64CC::CondCode CC1 = (AArch64CC::CondCode)CSel1.getConstantOperandVal(2);
+  if (!Cmp0->hasOneUse() || !Cmp1->hasOneUse())
+    return SDValue();
+  if (Cmp1.getOpcode() != AArch64ISD::SUBS &&
+      Cmp0.getOpcode() == AArch64ISD::SUBS) {
+    std::swap(Cmp0, Cmp1);
+    std::swap(CC0, CC1);
+  }
+
+  if (Cmp1.getOpcode() != AArch64ISD::SUBS)
+    return SDValue();
+
+  SDLoc DL(N);
+  AArch64CC::CondCode InvCC0 = AArch64CC::getInvertedCondCode(CC0);
+  SDValue Condition = DAG.getConstant(InvCC0, DL, MVT_CC);
+  unsigned NZCV = AArch64CC::getNZCVToSatisfyCondCode(CC1);
+  SDValue NZCVOp = DAG.getConstant(NZCV, DL, MVT::i32);
+  SDValue CCmp = DAG.getNode(AArch64ISD::CCMP, DL, MVT_CC, Cmp1.getOperand(0),
+                             Cmp1.getOperand(1), NZCVOp, Condition, Cmp0);
+  return DAG.getNode(AArch64ISD::CSEL, DL, VT, CSel0.getOperand(0),
+                     CSel0.getOperand(1), DAG.getConstant(CC1, DL, MVT::i32),
+                     CCmp);
+}
+
 static SDValue performANDCombine(SDNode *N,
                                  TargetLowering::DAGCombinerInfo &DCI) {
   SelectionDAG &DAG = DCI.DAG;
   SDValue LHS = N->getOperand(0);
   EVT VT = N->getValueType(0);
+
+  if (SDValue R = PerformANDCSELCombine(N, DAG))
+    return R;
+
   if (!VT.isVector() || !DAG.getTargetLoweringInfo().isTypeLegal(VT))
     return SDValue();
 

diff  --git a/llvm/test/CodeGen/AArch64/andcompare.ll b/llvm/test/CodeGen/AArch64/andcompare.ll
index 0820acc597f3e..cd9ae9c438004 100644
--- a/llvm/test/CodeGen/AArch64/andcompare.ll
+++ b/llvm/test/CodeGen/AArch64/andcompare.ll
@@ -5,10 +5,8 @@ define i32 @and_eq_eq(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_eq_eq:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, eq
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, eq
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, eq
+; CHECK-NEXT:    cset w0, eq
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp eq i32 %s0, %s1
@@ -22,10 +20,8 @@ define i32 @and_eq_ne(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_eq_ne:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, eq
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ne
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #4, eq
+; CHECK-NEXT:    cset w0, ne
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp eq i32 %s0, %s1
@@ -39,10 +35,8 @@ define i32 @and_eq_ult(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_eq_ult:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, eq
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, lo
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #2, eq
+; CHECK-NEXT:    cset w0, lo
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp eq i32 %s0, %s1
@@ -56,10 +50,8 @@ define i32 @and_eq_ule(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_eq_ule:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, eq
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ls
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #2, eq
+; CHECK-NEXT:    cset w0, ls
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp eq i32 %s0, %s1
@@ -73,10 +65,8 @@ define i32 @and_eq_ugt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_eq_ugt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, eq
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, hi
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, eq
+; CHECK-NEXT:    cset w0, hi
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp eq i32 %s0, %s1
@@ -90,10 +80,8 @@ define i32 @and_eq_uge(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_eq_uge:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, eq
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, hs
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, eq
+; CHECK-NEXT:    cset w0, hs
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp eq i32 %s0, %s1
@@ -107,10 +95,8 @@ define i32 @and_eq_slt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_eq_slt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, eq
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, lt
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, eq
+; CHECK-NEXT:    cset w0, lt
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp eq i32 %s0, %s1
@@ -124,10 +110,8 @@ define i32 @and_eq_sle(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_eq_sle:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, eq
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, le
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, eq
+; CHECK-NEXT:    cset w0, le
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp eq i32 %s0, %s1
@@ -141,10 +125,8 @@ define i32 @and_eq_sgt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_eq_sgt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, eq
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, gt
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #4, eq
+; CHECK-NEXT:    cset w0, gt
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp eq i32 %s0, %s1
@@ -158,10 +140,8 @@ define i32 @and_eq_sge(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_eq_sge:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, eq
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ge
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #8, eq
+; CHECK-NEXT:    cset w0, ge
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp eq i32 %s0, %s1
@@ -175,10 +155,8 @@ define i32 @and_ne_eq(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ne_eq:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ne
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, eq
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, ne
+; CHECK-NEXT:    cset w0, eq
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ne i32 %s0, %s1
@@ -192,10 +170,8 @@ define i32 @and_ne_ne(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ne_ne:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ne
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ne
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #4, ne
+; CHECK-NEXT:    cset w0, ne
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ne i32 %s0, %s1
@@ -209,10 +185,8 @@ define i32 @and_ne_ult(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ne_ult:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ne
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, lo
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #2, ne
+; CHECK-NEXT:    cset w0, lo
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ne i32 %s0, %s1
@@ -226,10 +200,8 @@ define i32 @and_ne_ule(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ne_ule:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ne
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ls
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #2, ne
+; CHECK-NEXT:    cset w0, ls
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ne i32 %s0, %s1
@@ -243,10 +215,8 @@ define i32 @and_ne_ugt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ne_ugt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ne
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, hi
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, ne
+; CHECK-NEXT:    cset w0, hi
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ne i32 %s0, %s1
@@ -260,10 +230,8 @@ define i32 @and_ne_uge(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ne_uge:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ne
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, hs
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, ne
+; CHECK-NEXT:    cset w0, hs
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ne i32 %s0, %s1
@@ -277,10 +245,8 @@ define i32 @and_ne_slt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ne_slt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ne
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, lt
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, ne
+; CHECK-NEXT:    cset w0, lt
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ne i32 %s0, %s1
@@ -294,10 +260,8 @@ define i32 @and_ne_sle(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ne_sle:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ne
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, le
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, ne
+; CHECK-NEXT:    cset w0, le
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ne i32 %s0, %s1
@@ -311,10 +275,8 @@ define i32 @and_ne_sgt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ne_sgt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ne
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, gt
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #4, ne
+; CHECK-NEXT:    cset w0, gt
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ne i32 %s0, %s1
@@ -328,10 +290,8 @@ define i32 @and_ne_sge(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ne_sge:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ne
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ge
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #8, ne
+; CHECK-NEXT:    cset w0, ge
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ne i32 %s0, %s1
@@ -345,10 +305,8 @@ define i32 @and_ult_eq(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ult_eq:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, lo
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, eq
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, lo
+; CHECK-NEXT:    cset w0, eq
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ult i32 %s0, %s1
@@ -362,10 +320,8 @@ define i32 @and_ult_ne(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ult_ne:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, lo
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ne
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #4, lo
+; CHECK-NEXT:    cset w0, ne
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ult i32 %s0, %s1
@@ -379,10 +335,8 @@ define i32 @and_ult_ult(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ult_ult:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, lo
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, lo
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #2, lo
+; CHECK-NEXT:    cset w0, lo
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ult i32 %s0, %s1
@@ -396,10 +350,8 @@ define i32 @and_ult_ule(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ult_ule:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, lo
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ls
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #2, lo
+; CHECK-NEXT:    cset w0, ls
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ult i32 %s0, %s1
@@ -413,10 +365,8 @@ define i32 @and_ult_ugt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ult_ugt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, lo
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, hi
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, lo
+; CHECK-NEXT:    cset w0, hi
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ult i32 %s0, %s1
@@ -430,10 +380,8 @@ define i32 @and_ult_uge(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ult_uge:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, lo
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, hs
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, lo
+; CHECK-NEXT:    cset w0, hs
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ult i32 %s0, %s1
@@ -447,10 +395,8 @@ define i32 @and_ult_slt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ult_slt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, lo
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, lt
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, lo
+; CHECK-NEXT:    cset w0, lt
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ult i32 %s0, %s1
@@ -464,10 +410,8 @@ define i32 @and_ult_sle(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ult_sle:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, lo
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, le
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, lo
+; CHECK-NEXT:    cset w0, le
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ult i32 %s0, %s1
@@ -481,10 +425,8 @@ define i32 @and_ult_sgt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ult_sgt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, lo
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, gt
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #4, lo
+; CHECK-NEXT:    cset w0, gt
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ult i32 %s0, %s1
@@ -498,10 +440,8 @@ define i32 @and_ult_sge(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ult_sge:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, lo
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ge
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #8, lo
+; CHECK-NEXT:    cset w0, ge
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ult i32 %s0, %s1
@@ -515,10 +455,8 @@ define i32 @and_ule_eq(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ule_eq:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ls
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, eq
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, ls
+; CHECK-NEXT:    cset w0, eq
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ule i32 %s0, %s1
@@ -532,10 +470,8 @@ define i32 @and_ule_ne(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ule_ne:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ls
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ne
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #4, ls
+; CHECK-NEXT:    cset w0, ne
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ule i32 %s0, %s1
@@ -549,10 +485,8 @@ define i32 @and_ule_ult(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ule_ult:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ls
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, lo
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #2, ls
+; CHECK-NEXT:    cset w0, lo
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ule i32 %s0, %s1
@@ -566,10 +500,8 @@ define i32 @and_ule_ule(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ule_ule:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ls
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ls
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #2, ls
+; CHECK-NEXT:    cset w0, ls
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ule i32 %s0, %s1
@@ -583,10 +515,8 @@ define i32 @and_ule_ugt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ule_ugt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ls
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, hi
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, ls
+; CHECK-NEXT:    cset w0, hi
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ule i32 %s0, %s1
@@ -600,10 +530,8 @@ define i32 @and_ule_uge(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ule_uge:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ls
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, hs
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, ls
+; CHECK-NEXT:    cset w0, hs
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ule i32 %s0, %s1
@@ -617,10 +545,8 @@ define i32 @and_ule_slt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ule_slt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ls
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, lt
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, ls
+; CHECK-NEXT:    cset w0, lt
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ule i32 %s0, %s1
@@ -634,10 +560,8 @@ define i32 @and_ule_sle(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ule_sle:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ls
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, le
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, ls
+; CHECK-NEXT:    cset w0, le
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ule i32 %s0, %s1
@@ -651,10 +575,8 @@ define i32 @and_ule_sgt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ule_sgt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ls
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, gt
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #4, ls
+; CHECK-NEXT:    cset w0, gt
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ule i32 %s0, %s1
@@ -668,10 +590,8 @@ define i32 @and_ule_sge(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ule_sge:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ls
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ge
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #8, ls
+; CHECK-NEXT:    cset w0, ge
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ule i32 %s0, %s1
@@ -685,10 +605,8 @@ define i32 @and_ugt_eq(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ugt_eq:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, hi
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, eq
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, hi
+; CHECK-NEXT:    cset w0, eq
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ugt i32 %s0, %s1
@@ -702,10 +620,8 @@ define i32 @and_ugt_ne(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ugt_ne:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, hi
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ne
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #4, hi
+; CHECK-NEXT:    cset w0, ne
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ugt i32 %s0, %s1
@@ -719,10 +635,8 @@ define i32 @and_ugt_ult(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ugt_ult:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, hi
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, lo
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #2, hi
+; CHECK-NEXT:    cset w0, lo
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ugt i32 %s0, %s1
@@ -736,10 +650,8 @@ define i32 @and_ugt_ule(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ugt_ule:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, hi
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ls
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #2, hi
+; CHECK-NEXT:    cset w0, ls
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ugt i32 %s0, %s1
@@ -753,10 +665,8 @@ define i32 @and_ugt_ugt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ugt_ugt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, hi
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, hi
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, hi
+; CHECK-NEXT:    cset w0, hi
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ugt i32 %s0, %s1
@@ -770,10 +680,8 @@ define i32 @and_ugt_uge(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ugt_uge:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, hi
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, hs
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, hi
+; CHECK-NEXT:    cset w0, hs
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ugt i32 %s0, %s1
@@ -787,10 +695,8 @@ define i32 @and_ugt_slt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ugt_slt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, hi
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, lt
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, hi
+; CHECK-NEXT:    cset w0, lt
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ugt i32 %s0, %s1
@@ -804,10 +710,8 @@ define i32 @and_ugt_sle(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ugt_sle:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, hi
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, le
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, hi
+; CHECK-NEXT:    cset w0, le
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ugt i32 %s0, %s1
@@ -821,10 +725,8 @@ define i32 @and_ugt_sgt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ugt_sgt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, hi
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, gt
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #4, hi
+; CHECK-NEXT:    cset w0, gt
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ugt i32 %s0, %s1
@@ -838,10 +740,8 @@ define i32 @and_ugt_sge(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_ugt_sge:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, hi
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ge
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #8, hi
+; CHECK-NEXT:    cset w0, ge
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp ugt i32 %s0, %s1
@@ -855,10 +755,8 @@ define i32 @and_uge_eq(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_uge_eq:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, hs
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, eq
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, hs
+; CHECK-NEXT:    cset w0, eq
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp uge i32 %s0, %s1
@@ -872,10 +770,8 @@ define i32 @and_uge_ne(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_uge_ne:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, hs
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ne
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #4, hs
+; CHECK-NEXT:    cset w0, ne
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp uge i32 %s0, %s1
@@ -889,10 +785,8 @@ define i32 @and_uge_ult(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_uge_ult:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, hs
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, lo
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #2, hs
+; CHECK-NEXT:    cset w0, lo
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp uge i32 %s0, %s1
@@ -906,10 +800,8 @@ define i32 @and_uge_ule(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_uge_ule:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, hs
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ls
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #2, hs
+; CHECK-NEXT:    cset w0, ls
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp uge i32 %s0, %s1
@@ -923,10 +815,8 @@ define i32 @and_uge_ugt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_uge_ugt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, hs
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, hi
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, hs
+; CHECK-NEXT:    cset w0, hi
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp uge i32 %s0, %s1
@@ -940,10 +830,8 @@ define i32 @and_uge_uge(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_uge_uge:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, hs
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, hs
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, hs
+; CHECK-NEXT:    cset w0, hs
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp uge i32 %s0, %s1
@@ -957,10 +845,8 @@ define i32 @and_uge_slt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_uge_slt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, hs
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, lt
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, hs
+; CHECK-NEXT:    cset w0, lt
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp uge i32 %s0, %s1
@@ -974,10 +860,8 @@ define i32 @and_uge_sle(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_uge_sle:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, hs
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, le
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, hs
+; CHECK-NEXT:    cset w0, le
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp uge i32 %s0, %s1
@@ -991,10 +875,8 @@ define i32 @and_uge_sgt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_uge_sgt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, hs
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, gt
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #4, hs
+; CHECK-NEXT:    cset w0, gt
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp uge i32 %s0, %s1
@@ -1008,10 +890,8 @@ define i32 @and_uge_sge(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_uge_sge:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, hs
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ge
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #8, hs
+; CHECK-NEXT:    cset w0, ge
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp uge i32 %s0, %s1
@@ -1025,10 +905,8 @@ define i32 @and_slt_eq(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_slt_eq:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, lt
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, eq
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, lt
+; CHECK-NEXT:    cset w0, eq
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp slt i32 %s0, %s1
@@ -1042,10 +920,8 @@ define i32 @and_slt_ne(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_slt_ne:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, lt
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ne
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #4, lt
+; CHECK-NEXT:    cset w0, ne
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp slt i32 %s0, %s1
@@ -1059,10 +935,8 @@ define i32 @and_slt_ult(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_slt_ult:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, lt
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, lo
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #2, lt
+; CHECK-NEXT:    cset w0, lo
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp slt i32 %s0, %s1
@@ -1076,10 +950,8 @@ define i32 @and_slt_ule(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_slt_ule:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, lt
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ls
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #2, lt
+; CHECK-NEXT:    cset w0, ls
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp slt i32 %s0, %s1
@@ -1093,10 +965,8 @@ define i32 @and_slt_ugt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_slt_ugt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, lt
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, hi
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, lt
+; CHECK-NEXT:    cset w0, hi
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp slt i32 %s0, %s1
@@ -1110,10 +980,8 @@ define i32 @and_slt_uge(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_slt_uge:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, lt
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, hs
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, lt
+; CHECK-NEXT:    cset w0, hs
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp slt i32 %s0, %s1
@@ -1127,10 +995,8 @@ define i32 @and_slt_slt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_slt_slt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, lt
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, lt
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, lt
+; CHECK-NEXT:    cset w0, lt
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp slt i32 %s0, %s1
@@ -1144,10 +1010,8 @@ define i32 @and_slt_sle(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_slt_sle:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, lt
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, le
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, lt
+; CHECK-NEXT:    cset w0, le
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp slt i32 %s0, %s1
@@ -1161,10 +1025,8 @@ define i32 @and_slt_sgt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_slt_sgt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, lt
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, gt
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #4, lt
+; CHECK-NEXT:    cset w0, gt
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp slt i32 %s0, %s1
@@ -1178,10 +1040,8 @@ define i32 @and_slt_sge(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_slt_sge:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, lt
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ge
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #8, lt
+; CHECK-NEXT:    cset w0, ge
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp slt i32 %s0, %s1
@@ -1195,10 +1055,8 @@ define i32 @and_sle_eq(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sle_eq:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, le
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, eq
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, le
+; CHECK-NEXT:    cset w0, eq
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sle i32 %s0, %s1
@@ -1212,10 +1070,8 @@ define i32 @and_sle_ne(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sle_ne:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, le
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ne
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #4, le
+; CHECK-NEXT:    cset w0, ne
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sle i32 %s0, %s1
@@ -1229,10 +1085,8 @@ define i32 @and_sle_ult(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sle_ult:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, le
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, lo
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #2, le
+; CHECK-NEXT:    cset w0, lo
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sle i32 %s0, %s1
@@ -1246,10 +1100,8 @@ define i32 @and_sle_ule(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sle_ule:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, le
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ls
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #2, le
+; CHECK-NEXT:    cset w0, ls
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sle i32 %s0, %s1
@@ -1263,10 +1115,8 @@ define i32 @and_sle_ugt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sle_ugt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, le
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, hi
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, le
+; CHECK-NEXT:    cset w0, hi
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sle i32 %s0, %s1
@@ -1280,10 +1130,8 @@ define i32 @and_sle_uge(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sle_uge:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, le
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, hs
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, le
+; CHECK-NEXT:    cset w0, hs
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sle i32 %s0, %s1
@@ -1297,10 +1145,8 @@ define i32 @and_sle_slt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sle_slt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, le
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, lt
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, le
+; CHECK-NEXT:    cset w0, lt
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sle i32 %s0, %s1
@@ -1314,10 +1160,8 @@ define i32 @and_sle_sle(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sle_sle:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, le
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, le
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, le
+; CHECK-NEXT:    cset w0, le
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sle i32 %s0, %s1
@@ -1331,10 +1175,8 @@ define i32 @and_sle_sgt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sle_sgt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, le
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, gt
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #4, le
+; CHECK-NEXT:    cset w0, gt
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sle i32 %s0, %s1
@@ -1348,10 +1190,8 @@ define i32 @and_sle_sge(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sle_sge:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, le
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ge
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #8, le
+; CHECK-NEXT:    cset w0, ge
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sle i32 %s0, %s1
@@ -1365,10 +1205,8 @@ define i32 @and_sgt_eq(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sgt_eq:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, gt
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, eq
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, gt
+; CHECK-NEXT:    cset w0, eq
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sgt i32 %s0, %s1
@@ -1382,10 +1220,8 @@ define i32 @and_sgt_ne(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sgt_ne:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, gt
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ne
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #4, gt
+; CHECK-NEXT:    cset w0, ne
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sgt i32 %s0, %s1
@@ -1399,10 +1235,8 @@ define i32 @and_sgt_ult(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sgt_ult:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, gt
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, lo
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #2, gt
+; CHECK-NEXT:    cset w0, lo
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sgt i32 %s0, %s1
@@ -1416,10 +1250,8 @@ define i32 @and_sgt_ule(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sgt_ule:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, gt
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ls
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #2, gt
+; CHECK-NEXT:    cset w0, ls
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sgt i32 %s0, %s1
@@ -1433,10 +1265,8 @@ define i32 @and_sgt_ugt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sgt_ugt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, gt
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, hi
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, gt
+; CHECK-NEXT:    cset w0, hi
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sgt i32 %s0, %s1
@@ -1450,10 +1280,8 @@ define i32 @and_sgt_uge(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sgt_uge:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, gt
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, hs
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, gt
+; CHECK-NEXT:    cset w0, hs
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sgt i32 %s0, %s1
@@ -1467,10 +1295,8 @@ define i32 @and_sgt_slt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sgt_slt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, gt
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, lt
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, gt
+; CHECK-NEXT:    cset w0, lt
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sgt i32 %s0, %s1
@@ -1484,10 +1310,8 @@ define i32 @and_sgt_sle(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sgt_sle:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, gt
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, le
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, gt
+; CHECK-NEXT:    cset w0, le
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sgt i32 %s0, %s1
@@ -1501,10 +1325,8 @@ define i32 @and_sgt_sgt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sgt_sgt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, gt
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, gt
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #4, gt
+; CHECK-NEXT:    cset w0, gt
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sgt i32 %s0, %s1
@@ -1518,10 +1340,8 @@ define i32 @and_sgt_sge(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sgt_sge:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, gt
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ge
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #8, gt
+; CHECK-NEXT:    cset w0, ge
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sgt i32 %s0, %s1
@@ -1535,10 +1355,8 @@ define i32 @and_sge_eq(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sge_eq:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ge
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, eq
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, ge
+; CHECK-NEXT:    cset w0, eq
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sge i32 %s0, %s1
@@ -1552,10 +1370,8 @@ define i32 @and_sge_ne(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sge_ne:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ge
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ne
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #4, ge
+; CHECK-NEXT:    cset w0, ne
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sge i32 %s0, %s1
@@ -1569,10 +1385,8 @@ define i32 @and_sge_ult(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sge_ult:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ge
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, lo
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #2, ge
+; CHECK-NEXT:    cset w0, lo
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sge i32 %s0, %s1
@@ -1586,10 +1400,8 @@ define i32 @and_sge_ule(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sge_ule:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ge
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ls
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #2, ge
+; CHECK-NEXT:    cset w0, ls
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sge i32 %s0, %s1
@@ -1603,10 +1415,8 @@ define i32 @and_sge_ugt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sge_ugt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ge
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, hi
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, ge
+; CHECK-NEXT:    cset w0, hi
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sge i32 %s0, %s1
@@ -1620,10 +1430,8 @@ define i32 @and_sge_uge(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sge_uge:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ge
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, hs
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, ge
+; CHECK-NEXT:    cset w0, hs
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sge i32 %s0, %s1
@@ -1637,10 +1445,8 @@ define i32 @and_sge_slt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sge_slt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ge
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, lt
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, ge
+; CHECK-NEXT:    cset w0, lt
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sge i32 %s0, %s1
@@ -1654,10 +1460,8 @@ define i32 @and_sge_sle(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sge_sle:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ge
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, le
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #0, ge
+; CHECK-NEXT:    cset w0, le
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sge i32 %s0, %s1
@@ -1671,10 +1475,8 @@ define i32 @and_sge_sgt(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sge_sgt:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ge
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, gt
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #4, ge
+; CHECK-NEXT:    cset w0, gt
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sge i32 %s0, %s1
@@ -1688,10 +1490,8 @@ define i32 @and_sge_sge(i32 %s0, i32 %s1, i32 %s2, i32 %s3) {
 ; CHECK-LABEL: and_sge_sge:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ge
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, ge
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #8, ge
+; CHECK-NEXT:    cset w0, ge
 ; CHECK-NEXT:    ret
 entry:
   %c0 = icmp sge i32 %s0, %s1

diff  --git a/llvm/test/CodeGen/AArch64/arm64-ccmp.ll b/llvm/test/CodeGen/AArch64/arm64-ccmp.ll
index 280e87b98901b..f81ed69b137f6 100644
--- a/llvm/test/CodeGen/AArch64/arm64-ccmp.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-ccmp.ll
@@ -718,15 +718,11 @@ define i64 @select_noccmp1(i64 %v1, i64 %v2, i64 %v3, i64 %r) {
 ; CHECK-LABEL: select_noccmp1:
 ; CHECK:       ; %bb.0:
 ; CHECK-NEXT:    cmp x0, #0
-; CHECK-NEXT:    cset w8, lt
-; CHECK-NEXT:    cmp x0, #13
-; CHECK-NEXT:    cset w9, gt
+; CHECK-NEXT:    ccmp x0, #13, #4, lt
+; CHECK-NEXT:    cset w8, gt
 ; CHECK-NEXT:    cmp x2, #2
-; CHECK-NEXT:    cset w10, lt
-; CHECK-NEXT:    cmp x2, #4
-; CHECK-NEXT:    cset w11, gt
-; CHECK-NEXT:    and w8, w8, w9
-; CHECK-NEXT:    and w9, w10, w11
+; CHECK-NEXT:    ccmp x2, #4, #4, lt
+; CHECK-NEXT:    cset w9, gt
 ; CHECK-NEXT:    orr w8, w8, w9
 ; CHECK-NEXT:    cmp w8, #0
 ; CHECK-NEXT:    csel x0, xzr, x3, ne

diff  --git a/llvm/test/CodeGen/AArch64/select-with-and-or.ll b/llvm/test/CodeGen/AArch64/select-with-and-or.ll
index 56fdd6a7dd7a9..20620c5f70863 100644
--- a/llvm/test/CodeGen/AArch64/select-with-and-or.ll
+++ b/llvm/test/CodeGen/AArch64/select-with-and-or.ll
@@ -5,10 +5,8 @@ define i1 @and(i32 %x, i32 %y, i32 %z, i32 %w) {
 ; CHECK-LABEL: and:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, eq
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, gt
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #4, eq
+; CHECK-NEXT:    cset w0, gt
 ; CHECK-NEXT:    ret
   %a = icmp eq i32 %x, %y
   %b = icmp sgt i32 %z, %w
@@ -35,10 +33,8 @@ define i1 @and_not(i32 %x, i32 %y, i32 %z, i32 %w) {
 ; CHECK-LABEL: and_not:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    cset w8, ne
-; CHECK-NEXT:    cmp w2, w3
-; CHECK-NEXT:    cset w9, gt
-; CHECK-NEXT:    and w0, w8, w9
+; CHECK-NEXT:    ccmp w2, w3, #4, ne
+; CHECK-NEXT:    cset w0, gt
 ; CHECK-NEXT:    ret
   %a = icmp eq i32 %x, %y
   %b = icmp sgt i32 %z, %w

diff  --git a/llvm/test/CodeGen/AArch64/umulo-128-legalisation-lowering.ll b/llvm/test/CodeGen/AArch64/umulo-128-legalisation-lowering.ll
index 6d5472ea05f69..f49897b9f8c87 100644
--- a/llvm/test/CodeGen/AArch64/umulo-128-legalisation-lowering.ll
+++ b/llvm/test/CodeGen/AArch64/umulo-128-legalisation-lowering.ll
@@ -4,20 +4,18 @@
 define { i128, i8 } @muloti_test(i128 %l, i128 %r) unnamed_addr #0 {
 ; AARCH-LABEL: muloti_test:
 ; AARCH:       // %bb.0: // %start
-; AARCH-NEXT:    cmp x3, #0
-; AARCH-NEXT:    umulh x10, x1, x2
-; AARCH-NEXT:    cset w8, ne
-; AARCH-NEXT:    cmp x1, #0
-; AARCH-NEXT:    cset w9, ne
-; AARCH-NEXT:    cmp xzr, x10
-; AARCH-NEXT:    and w8, w9, w8
+; AARCH-NEXT:    umulh x8, x1, x2
 ; AARCH-NEXT:    mul x9, x3, x0
+; AARCH-NEXT:    cmp xzr, x8
 ; AARCH-NEXT:    umulh x10, x3, x0
-; AARCH-NEXT:    cset w11, ne
+; AARCH-NEXT:    cset w8, ne
+; AARCH-NEXT:    cmp x1, #0
+; AARCH-NEXT:    ccmp x3, #0, #4, ne
 ; AARCH-NEXT:    madd x9, x1, x2, x9
-; AARCH-NEXT:    orr w8, w8, w11
+; AARCH-NEXT:    cset w11, ne
 ; AARCH-NEXT:    cmp xzr, x10
 ; AARCH-NEXT:    umulh x10, x0, x2
+; AARCH-NEXT:    orr w8, w11, w8
 ; AARCH-NEXT:    cset w11, ne
 ; AARCH-NEXT:    mul x0, x0, x2
 ; AARCH-NEXT:    adds x1, x10, x9

diff  --git a/llvm/test/CodeGen/AArch64/vec_umulo.ll b/llvm/test/CodeGen/AArch64/vec_umulo.ll
index 8dca9d0818e0a..d305b688f3af2 100644
--- a/llvm/test/CodeGen/AArch64/vec_umulo.ll
+++ b/llvm/test/CodeGen/AArch64/vec_umulo.ll
@@ -324,52 +324,48 @@ define <4 x i32> @umulo_v4i1(<4 x i1> %a0, <4 x i1> %a1, <4 x i1>* %p2) nounwind
 define <2 x i32> @umulo_v2i128(<2 x i128> %a0, <2 x i128> %a1, <2 x i128>* %p2) nounwind {
 ; CHECK-LABEL: umulo_v2i128:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    cmp x7, #0
 ; CHECK-NEXT:    umulh x8, x3, x6
 ; CHECK-NEXT:    mul x10, x7, x2
+; CHECK-NEXT:    cmp xzr, x8
+; CHECK-NEXT:    umulh x8, x7, x2
 ; CHECK-NEXT:    cset w9, ne
 ; CHECK-NEXT:    cmp x3, #0
-; CHECK-NEXT:    umulh x11, x7, x2
-; CHECK-NEXT:    cset w12, ne
+; CHECK-NEXT:    ccmp x7, #0, #4, ne
+; CHECK-NEXT:    umulh x11, x2, x6
 ; CHECK-NEXT:    madd x10, x3, x6, x10
-; CHECK-NEXT:    cmp xzr, x8
-; CHECK-NEXT:    umulh x8, x2, x6
+; CHECK-NEXT:    umulh x12, x1, x4
 ; CHECK-NEXT:    cset w13, ne
-; CHECK-NEXT:    cmp xzr, x11
-; CHECK-NEXT:    cset w11, ne
-; CHECK-NEXT:    adds x8, x8, x10
-; CHECK-NEXT:    cset w10, hs
-; CHECK-NEXT:    cmp x5, #0
-; CHECK-NEXT:    cset w14, ne
+; CHECK-NEXT:    cmp xzr, x8
+; CHECK-NEXT:    cset w8, ne
+; CHECK-NEXT:    adds x10, x11, x10
+; CHECK-NEXT:    cset w11, hs
+; CHECK-NEXT:    cmp xzr, x12
+; CHECK-NEXT:    cset w12, ne
 ; CHECK-NEXT:    cmp x1, #0
-; CHECK-NEXT:    umulh x15, x1, x4
-; CHECK-NEXT:    cset w16, ne
-; CHECK-NEXT:    mul x17, x5, x0
-; CHECK-NEXT:    and w14, w16, w14
-; CHECK-NEXT:    umulh x16, x5, x0
-; CHECK-NEXT:    cmp xzr, x15
-; CHECK-NEXT:    madd x15, x1, x4, x17
+; CHECK-NEXT:    ccmp x5, #0, #4, ne
+; CHECK-NEXT:    mul x15, x5, x0
+; CHECK-NEXT:    umulh x14, x5, x0
+; CHECK-NEXT:    orr w9, w13, w9
+; CHECK-NEXT:    umulh x16, x0, x4
+; CHECK-NEXT:    orr w8, w9, w8
+; CHECK-NEXT:    madd x15, x1, x4, x15
 ; CHECK-NEXT:    cset w17, ne
-; CHECK-NEXT:    umulh x18, x0, x4
-; CHECK-NEXT:    cmp xzr, x16
-; CHECK-NEXT:    orr w14, w14, w17
-; CHECK-NEXT:    cset w16, ne
-; CHECK-NEXT:    adds x15, x18, x15
-; CHECK-NEXT:    orr w14, w14, w16
-; CHECK-NEXT:    cset w16, hs
-; CHECK-NEXT:    and w9, w12, w9
-; CHECK-NEXT:    orr w12, w14, w16
-; CHECK-NEXT:    orr w9, w9, w13
-; CHECK-NEXT:    orr w9, w9, w11
+; CHECK-NEXT:    cmp xzr, x14
+; CHECK-NEXT:    orr w12, w17, w12
+; CHECK-NEXT:    cset w14, ne
+; CHECK-NEXT:    adds x15, x16, x15
+; CHECK-NEXT:    orr w12, w12, w14
+; CHECK-NEXT:    cset w14, hs
+; CHECK-NEXT:    orr w12, w12, w14
+; CHECK-NEXT:    orr w8, w8, w11
 ; CHECK-NEXT:    mul x11, x0, x4
-; CHECK-NEXT:    orr w9, w9, w10
-; CHECK-NEXT:    ldr x10, [sp]
+; CHECK-NEXT:    ldr x9, [sp]
 ; CHECK-NEXT:    fmov s0, w12
-; CHECK-NEXT:    stp x11, x15, [x10]
-; CHECK-NEXT:    mov v0.s[1], w9
-; CHECK-NEXT:    mul x9, x2, x6
+; CHECK-NEXT:    stp x11, x15, [x9]
+; CHECK-NEXT:    mov v0.s[1], w8
+; CHECK-NEXT:    mul x8, x2, x6
 ; CHECK-NEXT:    shl v0.2s, v0.2s, #31
-; CHECK-NEXT:    stp x9, x8, [x10, #16]
+; CHECK-NEXT:    stp x8, x10, [x9, #16]
 ; CHECK-NEXT:    cmlt v0.2s, v0.2s, #0
 ; CHECK-NEXT:    ret
   %t = call {<2 x i128>, <2 x i1>} @llvm.umul.with.overflow.v2i128(<2 x i128> %a0, <2 x i128> %a1)


        


More information about the llvm-commits mailing list