[llvm] [AArch64][ISel] Recover ADDHN from OR comparison masks (PR #210943)

Harry Ramsey via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 4 02:48:21 PDT 2026


https://github.com/Harry-Ramsey updated https://github.com/llvm/llvm-project/pull/210943

>From e3a4ed91abaca62593a6bab3c01ea8efbc1bc3d8 Mon Sep 17 00:00:00 2001
From: Harry Ramsey <harry.ramsey at arm.com>
Date: Tue, 21 Jul 2026 10:07:30 +0000
Subject: [PATCH 1/2] [AArch64][ISel] Recover ADDHN from ORed comparison masks

Introduce AArch64 specific SelectionDAG/GlobalISel node ADDHN which is
used to lower llvm.aarch64.neon.addhn.

Utilise ADDHN to recover the SelectionDAG pattern TRUNCATE(OR(SETCC,
SETCC)).
---
 llvm/test/CodeGen/AArch64/neon-addhn.ll | 52 +++++++++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 llvm/test/CodeGen/AArch64/neon-addhn.ll

diff --git a/llvm/test/CodeGen/AArch64/neon-addhn.ll b/llvm/test/CodeGen/AArch64/neon-addhn.ll
new file mode 100644
index 0000000000000..3f3277dc36329
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/neon-addhn.ll
@@ -0,0 +1,52 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -mtriple=aarch64 | FileCheck %s --check-prefixes=CHECK,CHECK-SD
+; RUN: llc < %s -mtriple=aarch64 -global-isel | FileCheck %s --check-prefixes=CHECK,CHECK-GI
+
+define <8 x i8> @addhn_setcc_v8i16( <8 x i16> %a, <8 x i16> %b, <8 x i16> %comparand) {
+; CHECK-LABEL: addhn_setcc_v8i16:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    cmeq v0.8h, v0.8h, v2.8h
+; CHECK-NEXT:    cmeq v1.8h, v1.8h, v2.8h
+; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
+; CHECK-NEXT:    xtn v0.8b, v0.8h
+; CHECK-NEXT:    ret
+  %cmp.a = icmp eq <8 x i16> %a, %comparand
+  %cmp.b = icmp eq <8 x i16> %b, %comparand
+  %either = or <8 x i1> %cmp.a, %cmp.b
+  %extended = sext <8 x i1> %either to <8 x i8>
+  ret <8 x i8> %extended
+}
+
+define <4 x i16> @addhn_setcc_v4i32( <4 x i32> %a, <4 x i32> %b, <4 x i32> %comparand) {
+; CHECK-LABEL: addhn_setcc_v4i32:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    cmeq v0.4s, v0.4s, v2.4s
+; CHECK-NEXT:    cmeq v1.4s, v1.4s, v2.4s
+; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
+; CHECK-NEXT:    xtn v0.4h, v0.4s
+; CHECK-NEXT:    ret
+  %cmp.a = icmp eq <4 x i32> %a, %comparand
+  %cmp.b = icmp eq <4 x i32> %b, %comparand
+  %either = or <4 x i1> %cmp.a, %cmp.b
+  %extended = sext <4 x i1> %either to <4 x i16>
+  ret <4 x i16> %extended
+}
+
+define <2 x i32> @addhn_setcc_v2i64( <2 x i64> %a, <2 x i64> %b, <2 x i64> %comparand) {
+; CHECK-LABEL: addhn_setcc_v2i64:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    cmeq v0.2d, v0.2d, v2.2d
+; CHECK-NEXT:    cmeq v1.2d, v1.2d, v2.2d
+; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
+; CHECK-NEXT:    xtn v0.2s, v0.2d
+; CHECK-NEXT:    ret
+  %cmp.a = icmp eq <2 x i64> %a, %comparand
+  %cmp.b = icmp eq <2 x i64> %b, %comparand
+  %either = or <2 x i1> %cmp.a, %cmp.b
+  %extended = sext <2 x i1> %either to <2 x i32>
+  ret <2 x i32> %extended
+}
+
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; CHECK-GI: {{.*}}
+; CHECK-SD: {{.*}}

>From db75838459de15afd6a24c1e02911068548095c2 Mon Sep 17 00:00:00 2001
From: Harry Ramsey <harry.ramsey at arm.com>
Date: Tue, 21 Jul 2026 10:07:53 +0000
Subject: [PATCH 2/2] fixup! [AArch64][ISel] Recover ADDHN from OR comparison
 masks

---
 .../Target/AArch64/AArch64ISelLowering.cpp    |  19 +++
 .../lib/Target/AArch64/AArch64InstrFormats.td |   2 +-
 llvm/lib/Target/AArch64/AArch64InstrGISel.td  |   7 +
 llvm/lib/Target/AArch64/AArch64InstrInfo.td   |   7 +-
 .../AArch64/GISel/AArch64LegalizerInfo.cpp    |   2 +
 .../CodeGen/AArch64/bf16-v4-instructions.ll   |  12 +-
 .../CodeGen/AArch64/bf16-v8-instructions.ll   | 132 ++++++++----------
 llvm/test/CodeGen/AArch64/cgp-usubo.ll        |   3 +-
 .../CodeGen/AArch64/fp16-v4-instructions.ll   |   6 +-
 .../CodeGen/AArch64/fp16-v8-instructions.ll   |  86 +++++++-----
 .../half-precision-signof-no-assert.ll        |   3 +-
 .../AArch64/intrinsic-vector-match-sve2.ll    |  12 +-
 llvm/test/CodeGen/AArch64/is_fpclass.ll       |   6 +-
 llvm/test/CodeGen/AArch64/neon-addhn.ll       |  66 ++++++---
 .../CodeGen/AArch64/select-with-and-or.ll     |  18 ++-
 15 files changed, 209 insertions(+), 172 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 51be0e66b19b0..0ae24ee15a1b7 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -6703,6 +6703,10 @@ SDValue AArch64TargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
       report_fatal_error("Unexpected type for AArch64 NEON intrinsic");
     }
   }
+  case Intrinsic::aarch64_neon_addhn: {
+    return DAG.getNode(AArch64ISD::ADDHN, DL, Op.getValueType(),
+                       Op.getOperand(1), Op.getOperand(2));
+  }
   case Intrinsic::aarch64_neon_pmull64: {
     SDValue LHS = Op.getOperand(1);
     SDValue RHS = Op.getOperand(2);
@@ -23647,6 +23651,21 @@ static SDValue performTruncateCombine(SDNode *N, SelectionDAG &DAG,
   SDLoc DL(N);
   EVT VT = N->getValueType(0);
   SDValue N0 = N->getOperand(0);
+
+  if (DCI.isAfterLegalizeDAG() && N0.getOpcode() == ISD::OR && N0.hasOneUse()) {
+    EVT SrcVT = N0.getValueType();
+    const unsigned EltSize = SrcVT.getScalarSizeInBits();
+
+    if (((VT == MVT::v8i8 && SrcVT == MVT::v8i16) ||
+         (VT == MVT::v4i16 && SrcVT == MVT::v4i32) ||
+         (VT == MVT::v2i32 && SrcVT == MVT::v2i64)) &&
+        DAG.ComputeNumSignBits(N0.getOperand(0)) == EltSize &&
+        DAG.ComputeNumSignBits(N0.getOperand(1)) == EltSize) {
+      return DAG.getNode(AArch64ISD::ADDHN, DL, VT, N0.getOperand(0),
+                         N0.getOperand(1));
+    }
+  }
+
   if (VT.isFixedLengthVector() && VT.is64BitVector() && N0.hasOneUse() &&
       N0.getOpcode() == AArch64ISD::DUP) {
     SDValue Op = N0.getOperand(0);
diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
index 30d7c291ca4d4..58fc5ec063c15 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -7451,7 +7451,7 @@ class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode,
 //        the high elements of the result register rather than the low
 //        elements). Until that's fixed, we can't code-gen those.
 multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm,
-                                    Intrinsic IntOp> {
+                                    SDPatternOperator IntOp> {
   def v8i16_v8i8   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
                                                   V64, V128, V128,
                                                   asm, ".8b", ".8h", ".8h",
diff --git a/llvm/lib/Target/AArch64/AArch64InstrGISel.td b/llvm/lib/Target/AArch64/AArch64InstrGISel.td
index ec95448f61043..4be183641cb3e 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrGISel.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrGISel.td
@@ -25,6 +25,12 @@ def G_ADD_LOW : AArch64GenericInstruction {
   let hasSideEffects = 0;
 }
 
+def G_ADDHN : AArch64GenericInstruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type1:$src1, type1:$src2);
+  let hasSideEffects = 0;
+}
+
 // Pseudo for a rev32 instruction. Produced post-legalization from
 // G_SHUFFLE_VECTORs with appropriate masks.
 def G_REV32 : AArch64GenericInstruction {
@@ -303,6 +309,7 @@ def G_BSP : AArch64GenericInstruction {
   let GISelMatchGenericTypes = 1;
 }
 
+def : GINodeEquiv<G_ADDHN, AArch64addhn>;
 def : GINodeEquiv<G_REV32, AArch64rev32>;
 def : GINodeEquiv<G_REV64, AArch64rev64>;
 def : GINodeEquiv<G_UZP1, AArch64uzp1>;
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 2f36cf2ad5494..53c7af890b6e5 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -509,6 +509,9 @@ def SDT_AArch64Insr  : SDTypeProfile<1, 2, [SDTCisVec<0>]>;
 def SDT_AArch64Zip   : SDTypeProfile<1, 2, [SDTCisVec<0>,
                                           SDTCisSameAs<0, 1>,
                                           SDTCisSameAs<0, 2>]>;
+def SDT_AArch64Addhn : SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisVec<1>,
+                                            SDTCisSameAs<1, 2>,
+                                            SDTCisOpSmallerThanOp<0, 1>]>;
 def SDT_AArch64MOVIedit : SDTypeProfile<1, 1, [SDTCisInt<1>]>;
 def SDT_AArch64MOVIshift : SDTypeProfile<1, 2, [SDTCisInt<1>, SDTCisInt<2>]>;
 def SDT_AArch64vecimm : SDTypeProfile<1, 3, [SDTCisVec<0>, SDTCisSameAs<0,1>,
@@ -1108,6 +1111,8 @@ def AArch64usdot    : SDNode<"AArch64ISD::USDOT", SDT_AArch64Dot>;
 def AArch64saddv    : SDNode<"AArch64ISD::SADDV", SDT_AArch64UnaryVec>;
 def AArch64uaddv    : SDNode<"AArch64ISD::UADDV", SDT_AArch64UnaryVec>;
 
+def AArch64addhn     : SDNode<"AArch64ISD::ADDHN", SDT_AArch64Addhn>;
+
 // Vector across-lanes min/max
 // Only the lower result lane is defined.
 def AArch64sminv    : SDNode<"AArch64ISD::SMINV", SDT_AArch64UnaryVec>;
@@ -7406,7 +7411,7 @@ def : Pat <(f64 (uint_to_fp (i32
 // Advanced SIMD three different-sized vector instructions.
 //===----------------------------------------------------------------------===//
 
-defm ADDHN   : SIMDNarrowThreeVectorBHS<0,0b0100,"addhn", int_aarch64_neon_addhn>;
+defm ADDHN   : SIMDNarrowThreeVectorBHS<0,0b0100,"addhn", AArch64addhn>;
 defm SUBHN   : SIMDNarrowThreeVectorBHS<0,0b0110,"subhn", int_aarch64_neon_subhn>;
 defm RADDHN  : SIMDNarrowThreeVectorBHS<1,0b0100,"raddhn",int_aarch64_neon_raddhn>;
 defm RSUBHN  : SIMDNarrowThreeVectorBHS<1,0b0110,"rsubhn",int_aarch64_neon_rsubhn>;
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index 94ca171c0b207..5def62f4707e6 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -2091,6 +2091,8 @@ bool AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
     MI.eraseFromParent();
     return true;
   }
+  case Intrinsic::aarch64_neon_addhn:
+    return LowerBinOp(AArch64::G_ADDHN);
   case Intrinsic::aarch64_neon_sqadd: {
     if (MRI.getType(MI.getOperand(0).getReg()).isVector())
       return LowerBinOp(TargetOpcode::G_SADDSAT);
diff --git a/llvm/test/CodeGen/AArch64/bf16-v4-instructions.ll b/llvm/test/CodeGen/AArch64/bf16-v4-instructions.ll
index ea262467e66fe..90982b93c90bc 100644
--- a/llvm/test/CodeGen/AArch64/bf16-v4-instructions.ll
+++ b/llvm/test/CodeGen/AArch64/bf16-v4-instructions.ll
@@ -921,8 +921,7 @@ define <4 x i1> @test_fcmp_one(<4 x bfloat> %a, <4 x bfloat> %b) #0 {
 ; CHECK-CVT-SD-NEXT:    shll v0.4s, v0.4h, #16
 ; CHECK-CVT-SD-NEXT:    fcmgt v2.4s, v0.4s, v1.4s
 ; CHECK-CVT-SD-NEXT:    fcmgt v0.4s, v1.4s, v0.4s
-; CHECK-CVT-SD-NEXT:    orr v0.16b, v0.16b, v2.16b
-; CHECK-CVT-SD-NEXT:    xtn v0.4h, v0.4s
+; CHECK-CVT-SD-NEXT:    addhn v0.4h, v0.4s, v2.4s
 ; CHECK-CVT-SD-NEXT:    ret
 ;
 ; CHECK-BF16-SD-LABEL: test_fcmp_one:
@@ -931,8 +930,7 @@ define <4 x i1> @test_fcmp_one(<4 x bfloat> %a, <4 x bfloat> %b) #0 {
 ; CHECK-BF16-SD-NEXT:    shll v0.4s, v0.4h, #16
 ; CHECK-BF16-SD-NEXT:    fcmgt v2.4s, v0.4s, v1.4s
 ; CHECK-BF16-SD-NEXT:    fcmgt v0.4s, v1.4s, v0.4s
-; CHECK-BF16-SD-NEXT:    orr v0.16b, v0.16b, v2.16b
-; CHECK-BF16-SD-NEXT:    xtn v0.4h, v0.4s
+; CHECK-BF16-SD-NEXT:    addhn v0.4h, v0.4s, v2.4s
 ; CHECK-BF16-SD-NEXT:    ret
 ;
 ; CHECK-CVT-GI-LABEL: test_fcmp_one:
@@ -1097,8 +1095,7 @@ define <4 x i1> @test_fcmp_ord(<4 x bfloat> %a, <4 x bfloat> %b) #0 {
 ; CHECK-CVT-SD-NEXT:    shll v0.4s, v0.4h, #16
 ; CHECK-CVT-SD-NEXT:    fcmge v2.4s, v0.4s, v1.4s
 ; CHECK-CVT-SD-NEXT:    fcmgt v0.4s, v1.4s, v0.4s
-; CHECK-CVT-SD-NEXT:    orr v0.16b, v0.16b, v2.16b
-; CHECK-CVT-SD-NEXT:    xtn v0.4h, v0.4s
+; CHECK-CVT-SD-NEXT:    addhn v0.4h, v0.4s, v2.4s
 ; CHECK-CVT-SD-NEXT:    ret
 ;
 ; CHECK-BF16-SD-LABEL: test_fcmp_ord:
@@ -1107,8 +1104,7 @@ define <4 x i1> @test_fcmp_ord(<4 x bfloat> %a, <4 x bfloat> %b) #0 {
 ; CHECK-BF16-SD-NEXT:    shll v0.4s, v0.4h, #16
 ; CHECK-BF16-SD-NEXT:    fcmge v2.4s, v0.4s, v1.4s
 ; CHECK-BF16-SD-NEXT:    fcmgt v0.4s, v1.4s, v0.4s
-; CHECK-BF16-SD-NEXT:    orr v0.16b, v0.16b, v2.16b
-; CHECK-BF16-SD-NEXT:    xtn v0.4h, v0.4s
+; CHECK-BF16-SD-NEXT:    addhn v0.4h, v0.4s, v2.4s
 ; CHECK-BF16-SD-NEXT:    ret
 ;
 ; CHECK-CVT-GI-LABEL: test_fcmp_ord:
diff --git a/llvm/test/CodeGen/AArch64/bf16-v8-instructions.ll b/llvm/test/CodeGen/AArch64/bf16-v8-instructions.ll
index c60cf6d11310c..2cd34e9983775 100644
--- a/llvm/test/CodeGen/AArch64/bf16-v8-instructions.ll
+++ b/llvm/test/CodeGen/AArch64/bf16-v8-instructions.ll
@@ -1361,52 +1361,49 @@ define <8 x i1> @test_fcmp_une(<8 x bfloat> %a, <8 x bfloat> %b) #0 {
 define <8 x i1> @test_fcmp_ueq(<8 x bfloat> %a, <8 x bfloat> %b) #0 {
 ; CHECK-CVT-SD-LABEL: test_fcmp_ueq:
 ; CHECK-CVT-SD:       // %bb.0:
-; CHECK-CVT-SD-NEXT:    shll2 v2.4s, v1.8h, #16
-; CHECK-CVT-SD-NEXT:    shll2 v3.4s, v0.8h, #16
-; CHECK-CVT-SD-NEXT:    shll v1.4s, v1.4h, #16
-; CHECK-CVT-SD-NEXT:    shll v0.4s, v0.4h, #16
+; CHECK-CVT-SD-NEXT:    shll v2.4s, v1.4h, #16
+; CHECK-CVT-SD-NEXT:    shll v3.4s, v0.4h, #16
+; CHECK-CVT-SD-NEXT:    shll2 v1.4s, v1.8h, #16
+; CHECK-CVT-SD-NEXT:    shll2 v0.4s, v0.8h, #16
 ; CHECK-CVT-SD-NEXT:    fcmgt v4.4s, v3.4s, v2.4s
 ; CHECK-CVT-SD-NEXT:    fcmgt v2.4s, v2.4s, v3.4s
 ; CHECK-CVT-SD-NEXT:    fcmgt v3.4s, v0.4s, v1.4s
 ; CHECK-CVT-SD-NEXT:    fcmgt v0.4s, v1.4s, v0.4s
-; CHECK-CVT-SD-NEXT:    orr v1.16b, v2.16b, v4.16b
-; CHECK-CVT-SD-NEXT:    orr v0.16b, v0.16b, v3.16b
-; CHECK-CVT-SD-NEXT:    uzp1 v0.8h, v0.8h, v1.8h
-; CHECK-CVT-SD-NEXT:    mvn v0.16b, v0.16b
+; CHECK-CVT-SD-NEXT:    addhn v2.4h, v2.4s, v4.4s
+; CHECK-CVT-SD-NEXT:    addhn2 v2.8h, v0.4s, v3.4s
+; CHECK-CVT-SD-NEXT:    mvn v0.16b, v2.16b
 ; CHECK-CVT-SD-NEXT:    xtn v0.8b, v0.8h
 ; CHECK-CVT-SD-NEXT:    ret
 ;
 ; CHECK-BF16-SD-LABEL: test_fcmp_ueq:
 ; CHECK-BF16-SD:       // %bb.0:
-; CHECK-BF16-SD-NEXT:    shll2 v2.4s, v1.8h, #16
-; CHECK-BF16-SD-NEXT:    shll2 v3.4s, v0.8h, #16
-; CHECK-BF16-SD-NEXT:    shll v1.4s, v1.4h, #16
-; CHECK-BF16-SD-NEXT:    shll v0.4s, v0.4h, #16
+; CHECK-BF16-SD-NEXT:    shll v2.4s, v1.4h, #16
+; CHECK-BF16-SD-NEXT:    shll v3.4s, v0.4h, #16
+; CHECK-BF16-SD-NEXT:    shll2 v1.4s, v1.8h, #16
+; CHECK-BF16-SD-NEXT:    shll2 v0.4s, v0.8h, #16
 ; CHECK-BF16-SD-NEXT:    fcmgt v4.4s, v3.4s, v2.4s
 ; CHECK-BF16-SD-NEXT:    fcmgt v2.4s, v2.4s, v3.4s
 ; CHECK-BF16-SD-NEXT:    fcmgt v3.4s, v0.4s, v1.4s
 ; CHECK-BF16-SD-NEXT:    fcmgt v0.4s, v1.4s, v0.4s
-; CHECK-BF16-SD-NEXT:    orr v1.16b, v2.16b, v4.16b
-; CHECK-BF16-SD-NEXT:    orr v0.16b, v0.16b, v3.16b
-; CHECK-BF16-SD-NEXT:    uzp1 v0.8h, v0.8h, v1.8h
-; CHECK-BF16-SD-NEXT:    mvn v0.16b, v0.16b
+; CHECK-BF16-SD-NEXT:    addhn v2.4h, v2.4s, v4.4s
+; CHECK-BF16-SD-NEXT:    addhn2 v2.8h, v0.4s, v3.4s
+; CHECK-BF16-SD-NEXT:    mvn v0.16b, v2.16b
 ; CHECK-BF16-SD-NEXT:    xtn v0.8b, v0.8h
 ; CHECK-BF16-SD-NEXT:    ret
 ;
 ; CHECK-BF16SVE-SD-LABEL: test_fcmp_ueq:
 ; CHECK-BF16SVE-SD:       // %bb.0:
-; CHECK-BF16SVE-SD-NEXT:    shll2 v2.4s, v1.8h, #16
-; CHECK-BF16SVE-SD-NEXT:    shll2 v3.4s, v0.8h, #16
-; CHECK-BF16SVE-SD-NEXT:    shll v1.4s, v1.4h, #16
-; CHECK-BF16SVE-SD-NEXT:    shll v0.4s, v0.4h, #16
+; CHECK-BF16SVE-SD-NEXT:    shll v2.4s, v1.4h, #16
+; CHECK-BF16SVE-SD-NEXT:    shll v3.4s, v0.4h, #16
+; CHECK-BF16SVE-SD-NEXT:    shll2 v1.4s, v1.8h, #16
+; CHECK-BF16SVE-SD-NEXT:    shll2 v0.4s, v0.8h, #16
 ; CHECK-BF16SVE-SD-NEXT:    fcmgt v4.4s, v3.4s, v2.4s
 ; CHECK-BF16SVE-SD-NEXT:    fcmgt v2.4s, v2.4s, v3.4s
 ; CHECK-BF16SVE-SD-NEXT:    fcmgt v3.4s, v0.4s, v1.4s
 ; CHECK-BF16SVE-SD-NEXT:    fcmgt v0.4s, v1.4s, v0.4s
-; CHECK-BF16SVE-SD-NEXT:    orr v1.16b, v2.16b, v4.16b
-; CHECK-BF16SVE-SD-NEXT:    orr v0.16b, v0.16b, v3.16b
-; CHECK-BF16SVE-SD-NEXT:    uzp1 v0.8h, v0.8h, v1.8h
-; CHECK-BF16SVE-SD-NEXT:    mvn v0.16b, v0.16b
+; CHECK-BF16SVE-SD-NEXT:    addhn v2.4h, v2.4s, v4.4s
+; CHECK-BF16SVE-SD-NEXT:    addhn2 v2.8h, v0.4s, v3.4s
+; CHECK-BF16SVE-SD-NEXT:    mvn v0.16b, v2.16b
 ; CHECK-BF16SVE-SD-NEXT:    xtn v0.8b, v0.8h
 ; CHECK-BF16SVE-SD-NEXT:    ret
 ;
@@ -1736,52 +1733,49 @@ define <8 x i1> @test_fcmp_ule(<8 x bfloat> %a, <8 x bfloat> %b) #0 {
 define <8 x i1> @test_fcmp_uno(<8 x bfloat> %a, <8 x bfloat> %b) #0 {
 ; CHECK-CVT-SD-LABEL: test_fcmp_uno:
 ; CHECK-CVT-SD:       // %bb.0:
-; CHECK-CVT-SD-NEXT:    shll2 v2.4s, v1.8h, #16
-; CHECK-CVT-SD-NEXT:    shll2 v3.4s, v0.8h, #16
-; CHECK-CVT-SD-NEXT:    shll v1.4s, v1.4h, #16
-; CHECK-CVT-SD-NEXT:    shll v0.4s, v0.4h, #16
+; CHECK-CVT-SD-NEXT:    shll v2.4s, v1.4h, #16
+; CHECK-CVT-SD-NEXT:    shll v3.4s, v0.4h, #16
+; CHECK-CVT-SD-NEXT:    shll2 v1.4s, v1.8h, #16
+; CHECK-CVT-SD-NEXT:    shll2 v0.4s, v0.8h, #16
 ; CHECK-CVT-SD-NEXT:    fcmge v4.4s, v3.4s, v2.4s
 ; CHECK-CVT-SD-NEXT:    fcmgt v2.4s, v2.4s, v3.4s
 ; CHECK-CVT-SD-NEXT:    fcmge v3.4s, v0.4s, v1.4s
 ; CHECK-CVT-SD-NEXT:    fcmgt v0.4s, v1.4s, v0.4s
-; CHECK-CVT-SD-NEXT:    orr v1.16b, v2.16b, v4.16b
-; CHECK-CVT-SD-NEXT:    orr v0.16b, v0.16b, v3.16b
-; CHECK-CVT-SD-NEXT:    uzp1 v0.8h, v0.8h, v1.8h
-; CHECK-CVT-SD-NEXT:    mvn v0.16b, v0.16b
+; CHECK-CVT-SD-NEXT:    addhn v2.4h, v2.4s, v4.4s
+; CHECK-CVT-SD-NEXT:    addhn2 v2.8h, v0.4s, v3.4s
+; CHECK-CVT-SD-NEXT:    mvn v0.16b, v2.16b
 ; CHECK-CVT-SD-NEXT:    xtn v0.8b, v0.8h
 ; CHECK-CVT-SD-NEXT:    ret
 ;
 ; CHECK-BF16-SD-LABEL: test_fcmp_uno:
 ; CHECK-BF16-SD:       // %bb.0:
-; CHECK-BF16-SD-NEXT:    shll2 v2.4s, v1.8h, #16
-; CHECK-BF16-SD-NEXT:    shll2 v3.4s, v0.8h, #16
-; CHECK-BF16-SD-NEXT:    shll v1.4s, v1.4h, #16
-; CHECK-BF16-SD-NEXT:    shll v0.4s, v0.4h, #16
+; CHECK-BF16-SD-NEXT:    shll v2.4s, v1.4h, #16
+; CHECK-BF16-SD-NEXT:    shll v3.4s, v0.4h, #16
+; CHECK-BF16-SD-NEXT:    shll2 v1.4s, v1.8h, #16
+; CHECK-BF16-SD-NEXT:    shll2 v0.4s, v0.8h, #16
 ; CHECK-BF16-SD-NEXT:    fcmge v4.4s, v3.4s, v2.4s
 ; CHECK-BF16-SD-NEXT:    fcmgt v2.4s, v2.4s, v3.4s
 ; CHECK-BF16-SD-NEXT:    fcmge v3.4s, v0.4s, v1.4s
 ; CHECK-BF16-SD-NEXT:    fcmgt v0.4s, v1.4s, v0.4s
-; CHECK-BF16-SD-NEXT:    orr v1.16b, v2.16b, v4.16b
-; CHECK-BF16-SD-NEXT:    orr v0.16b, v0.16b, v3.16b
-; CHECK-BF16-SD-NEXT:    uzp1 v0.8h, v0.8h, v1.8h
-; CHECK-BF16-SD-NEXT:    mvn v0.16b, v0.16b
+; CHECK-BF16-SD-NEXT:    addhn v2.4h, v2.4s, v4.4s
+; CHECK-BF16-SD-NEXT:    addhn2 v2.8h, v0.4s, v3.4s
+; CHECK-BF16-SD-NEXT:    mvn v0.16b, v2.16b
 ; CHECK-BF16-SD-NEXT:    xtn v0.8b, v0.8h
 ; CHECK-BF16-SD-NEXT:    ret
 ;
 ; CHECK-BF16SVE-SD-LABEL: test_fcmp_uno:
 ; CHECK-BF16SVE-SD:       // %bb.0:
-; CHECK-BF16SVE-SD-NEXT:    shll2 v2.4s, v1.8h, #16
-; CHECK-BF16SVE-SD-NEXT:    shll2 v3.4s, v0.8h, #16
-; CHECK-BF16SVE-SD-NEXT:    shll v1.4s, v1.4h, #16
-; CHECK-BF16SVE-SD-NEXT:    shll v0.4s, v0.4h, #16
+; CHECK-BF16SVE-SD-NEXT:    shll v2.4s, v1.4h, #16
+; CHECK-BF16SVE-SD-NEXT:    shll v3.4s, v0.4h, #16
+; CHECK-BF16SVE-SD-NEXT:    shll2 v1.4s, v1.8h, #16
+; CHECK-BF16SVE-SD-NEXT:    shll2 v0.4s, v0.8h, #16
 ; CHECK-BF16SVE-SD-NEXT:    fcmge v4.4s, v3.4s, v2.4s
 ; CHECK-BF16SVE-SD-NEXT:    fcmgt v2.4s, v2.4s, v3.4s
 ; CHECK-BF16SVE-SD-NEXT:    fcmge v3.4s, v0.4s, v1.4s
 ; CHECK-BF16SVE-SD-NEXT:    fcmgt v0.4s, v1.4s, v0.4s
-; CHECK-BF16SVE-SD-NEXT:    orr v1.16b, v2.16b, v4.16b
-; CHECK-BF16SVE-SD-NEXT:    orr v0.16b, v0.16b, v3.16b
-; CHECK-BF16SVE-SD-NEXT:    uzp1 v0.8h, v0.8h, v1.8h
-; CHECK-BF16SVE-SD-NEXT:    mvn v0.16b, v0.16b
+; CHECK-BF16SVE-SD-NEXT:    addhn v2.4h, v2.4s, v4.4s
+; CHECK-BF16SVE-SD-NEXT:    addhn2 v2.8h, v0.4s, v3.4s
+; CHECK-BF16SVE-SD-NEXT:    mvn v0.16b, v2.16b
 ; CHECK-BF16SVE-SD-NEXT:    xtn v0.8b, v0.8h
 ; CHECK-BF16SVE-SD-NEXT:    ret
 ;
@@ -1835,10 +1829,9 @@ define <8 x i1> @test_fcmp_one(<8 x bfloat> %a, <8 x bfloat> %b) #0 {
 ; CHECK-CVT-SD-NEXT:    fcmgt v2.4s, v2.4s, v3.4s
 ; CHECK-CVT-SD-NEXT:    fcmgt v3.4s, v0.4s, v1.4s
 ; CHECK-CVT-SD-NEXT:    fcmgt v0.4s, v1.4s, v0.4s
-; CHECK-CVT-SD-NEXT:    orr v1.16b, v2.16b, v4.16b
-; CHECK-CVT-SD-NEXT:    orr v0.16b, v0.16b, v3.16b
-; CHECK-CVT-SD-NEXT:    uzp1 v0.8h, v0.8h, v1.8h
-; CHECK-CVT-SD-NEXT:    xtn v0.8b, v0.8h
+; CHECK-CVT-SD-NEXT:    addhn v1.4h, v2.4s, v4.4s
+; CHECK-CVT-SD-NEXT:    addhn v0.4h, v0.4s, v3.4s
+; CHECK-CVT-SD-NEXT:    uzp1 v0.8b, v0.8b, v1.8b
 ; CHECK-CVT-SD-NEXT:    ret
 ;
 ; CHECK-BF16-SD-LABEL: test_fcmp_one:
@@ -1851,10 +1844,9 @@ define <8 x i1> @test_fcmp_one(<8 x bfloat> %a, <8 x bfloat> %b) #0 {
 ; CHECK-BF16-SD-NEXT:    fcmgt v2.4s, v2.4s, v3.4s
 ; CHECK-BF16-SD-NEXT:    fcmgt v3.4s, v0.4s, v1.4s
 ; CHECK-BF16-SD-NEXT:    fcmgt v0.4s, v1.4s, v0.4s
-; CHECK-BF16-SD-NEXT:    orr v1.16b, v2.16b, v4.16b
-; CHECK-BF16-SD-NEXT:    orr v0.16b, v0.16b, v3.16b
-; CHECK-BF16-SD-NEXT:    uzp1 v0.8h, v0.8h, v1.8h
-; CHECK-BF16-SD-NEXT:    xtn v0.8b, v0.8h
+; CHECK-BF16-SD-NEXT:    addhn v1.4h, v2.4s, v4.4s
+; CHECK-BF16-SD-NEXT:    addhn v0.4h, v0.4s, v3.4s
+; CHECK-BF16-SD-NEXT:    uzp1 v0.8b, v0.8b, v1.8b
 ; CHECK-BF16-SD-NEXT:    ret
 ;
 ; CHECK-BF16SVE-SD-LABEL: test_fcmp_one:
@@ -1867,10 +1859,9 @@ define <8 x i1> @test_fcmp_one(<8 x bfloat> %a, <8 x bfloat> %b) #0 {
 ; CHECK-BF16SVE-SD-NEXT:    fcmgt v2.4s, v2.4s, v3.4s
 ; CHECK-BF16SVE-SD-NEXT:    fcmgt v3.4s, v0.4s, v1.4s
 ; CHECK-BF16SVE-SD-NEXT:    fcmgt v0.4s, v1.4s, v0.4s
-; CHECK-BF16SVE-SD-NEXT:    orr v1.16b, v2.16b, v4.16b
-; CHECK-BF16SVE-SD-NEXT:    orr v0.16b, v0.16b, v3.16b
-; CHECK-BF16SVE-SD-NEXT:    uzp1 v0.8h, v0.8h, v1.8h
-; CHECK-BF16SVE-SD-NEXT:    xtn v0.8b, v0.8h
+; CHECK-BF16SVE-SD-NEXT:    addhn v1.4h, v2.4s, v4.4s
+; CHECK-BF16SVE-SD-NEXT:    addhn v0.4h, v0.4s, v3.4s
+; CHECK-BF16SVE-SD-NEXT:    uzp1 v0.8b, v0.8b, v1.8b
 ; CHECK-BF16SVE-SD-NEXT:    ret
 ;
 ; CHECK-CVT-GI-LABEL: test_fcmp_one:
@@ -2239,10 +2230,9 @@ define <8 x i1> @test_fcmp_ord(<8 x bfloat> %a, <8 x bfloat> %b) #0 {
 ; CHECK-CVT-SD-NEXT:    fcmgt v2.4s, v2.4s, v3.4s
 ; CHECK-CVT-SD-NEXT:    fcmge v3.4s, v0.4s, v1.4s
 ; CHECK-CVT-SD-NEXT:    fcmgt v0.4s, v1.4s, v0.4s
-; CHECK-CVT-SD-NEXT:    orr v1.16b, v2.16b, v4.16b
-; CHECK-CVT-SD-NEXT:    orr v0.16b, v0.16b, v3.16b
-; CHECK-CVT-SD-NEXT:    uzp1 v0.8h, v0.8h, v1.8h
-; CHECK-CVT-SD-NEXT:    xtn v0.8b, v0.8h
+; CHECK-CVT-SD-NEXT:    addhn v1.4h, v2.4s, v4.4s
+; CHECK-CVT-SD-NEXT:    addhn v0.4h, v0.4s, v3.4s
+; CHECK-CVT-SD-NEXT:    uzp1 v0.8b, v0.8b, v1.8b
 ; CHECK-CVT-SD-NEXT:    ret
 ;
 ; CHECK-BF16-SD-LABEL: test_fcmp_ord:
@@ -2255,10 +2245,9 @@ define <8 x i1> @test_fcmp_ord(<8 x bfloat> %a, <8 x bfloat> %b) #0 {
 ; CHECK-BF16-SD-NEXT:    fcmgt v2.4s, v2.4s, v3.4s
 ; CHECK-BF16-SD-NEXT:    fcmge v3.4s, v0.4s, v1.4s
 ; CHECK-BF16-SD-NEXT:    fcmgt v0.4s, v1.4s, v0.4s
-; CHECK-BF16-SD-NEXT:    orr v1.16b, v2.16b, v4.16b
-; CHECK-BF16-SD-NEXT:    orr v0.16b, v0.16b, v3.16b
-; CHECK-BF16-SD-NEXT:    uzp1 v0.8h, v0.8h, v1.8h
-; CHECK-BF16-SD-NEXT:    xtn v0.8b, v0.8h
+; CHECK-BF16-SD-NEXT:    addhn v1.4h, v2.4s, v4.4s
+; CHECK-BF16-SD-NEXT:    addhn v0.4h, v0.4s, v3.4s
+; CHECK-BF16-SD-NEXT:    uzp1 v0.8b, v0.8b, v1.8b
 ; CHECK-BF16-SD-NEXT:    ret
 ;
 ; CHECK-BF16SVE-SD-LABEL: test_fcmp_ord:
@@ -2271,10 +2260,9 @@ define <8 x i1> @test_fcmp_ord(<8 x bfloat> %a, <8 x bfloat> %b) #0 {
 ; CHECK-BF16SVE-SD-NEXT:    fcmgt v2.4s, v2.4s, v3.4s
 ; CHECK-BF16SVE-SD-NEXT:    fcmge v3.4s, v0.4s, v1.4s
 ; CHECK-BF16SVE-SD-NEXT:    fcmgt v0.4s, v1.4s, v0.4s
-; CHECK-BF16SVE-SD-NEXT:    orr v1.16b, v2.16b, v4.16b
-; CHECK-BF16SVE-SD-NEXT:    orr v0.16b, v0.16b, v3.16b
-; CHECK-BF16SVE-SD-NEXT:    uzp1 v0.8h, v0.8h, v1.8h
-; CHECK-BF16SVE-SD-NEXT:    xtn v0.8b, v0.8h
+; CHECK-BF16SVE-SD-NEXT:    addhn v1.4h, v2.4s, v4.4s
+; CHECK-BF16SVE-SD-NEXT:    addhn v0.4h, v0.4s, v3.4s
+; CHECK-BF16SVE-SD-NEXT:    uzp1 v0.8b, v0.8b, v1.8b
 ; CHECK-BF16SVE-SD-NEXT:    ret
 ;
 ; CHECK-CVT-GI-LABEL: test_fcmp_ord:
diff --git a/llvm/test/CodeGen/AArch64/cgp-usubo.ll b/llvm/test/CodeGen/AArch64/cgp-usubo.ll
index f990920e2793a..71a873014a61f 100644
--- a/llvm/test/CodeGen/AArch64/cgp-usubo.ll
+++ b/llvm/test/CodeGen/AArch64/cgp-usubo.ll
@@ -235,8 +235,7 @@ define <4 x i1> @no_subcarry_vector(<4 x i32> %x0, <4 x i32> %x1, <4 x i32> %y0,
 ; CHECK-NEXT:    cmhi v0.4s, v2.4s, v0.4s
 ; CHECK-NEXT:    cmhi v1.4s, v3.4s, v1.4s
 ; CHECK-NEXT:    and v0.16b, v0.16b, v4.16b
-; CHECK-NEXT:    orr v0.16b, v1.16b, v0.16b
-; CHECK-NEXT:    xtn v0.4h, v0.4s
+; CHECK-NEXT:    addhn v0.4h, v1.4s, v0.4s
 ; CHECK-NEXT:    ret
   %b0 = icmp ult <4 x i32> %x0, %y0
   %b1 = icmp ult <4 x i32> %x1, %y1
diff --git a/llvm/test/CodeGen/AArch64/fp16-v4-instructions.ll b/llvm/test/CodeGen/AArch64/fp16-v4-instructions.ll
index b6de932477cca..c1d0c7e2fbda5 100644
--- a/llvm/test/CodeGen/AArch64/fp16-v4-instructions.ll
+++ b/llvm/test/CodeGen/AArch64/fp16-v4-instructions.ll
@@ -677,8 +677,7 @@ define <4 x i1> @test_fcmp_one(<4 x half> %a, <4 x half> %b) #0 {
 ; CHECK-CVT-SD-NEXT:    fcvtl v0.4s, v0.4h
 ; CHECK-CVT-SD-NEXT:    fcmgt v2.4s, v0.4s, v1.4s
 ; CHECK-CVT-SD-NEXT:    fcmgt v0.4s, v1.4s, v0.4s
-; CHECK-CVT-SD-NEXT:    orr v0.16b, v0.16b, v2.16b
-; CHECK-CVT-SD-NEXT:    xtn v0.4h, v0.4s
+; CHECK-CVT-SD-NEXT:    addhn v0.4h, v0.4s, v2.4s
 ; CHECK-CVT-SD-NEXT:    ret
 ;
 ; CHECK-FP16-LABEL: test_fcmp_one:
@@ -823,8 +822,7 @@ define <4 x i1> @test_fcmp_ord(<4 x half> %a, <4 x half> %b) #0 {
 ; CHECK-CVT-SD-NEXT:    fcvtl v0.4s, v0.4h
 ; CHECK-CVT-SD-NEXT:    fcmge v2.4s, v0.4s, v1.4s
 ; CHECK-CVT-SD-NEXT:    fcmgt v0.4s, v1.4s, v0.4s
-; CHECK-CVT-SD-NEXT:    orr v0.16b, v0.16b, v2.16b
-; CHECK-CVT-SD-NEXT:    xtn v0.4h, v0.4s
+; CHECK-CVT-SD-NEXT:    addhn v0.4h, v0.4s, v2.4s
 ; CHECK-CVT-SD-NEXT:    ret
 ;
 ; CHECK-FP16-LABEL: test_fcmp_ord:
diff --git a/llvm/test/CodeGen/AArch64/fp16-v8-instructions.ll b/llvm/test/CodeGen/AArch64/fp16-v8-instructions.ll
index f94f8b449c59b..bbbd2b65b5c2e 100644
--- a/llvm/test/CodeGen/AArch64/fp16-v8-instructions.ll
+++ b/llvm/test/CodeGen/AArch64/fp16-v8-instructions.ll
@@ -893,18 +893,17 @@ define <8 x i1> @test_fcmp_une(<8 x half> %a, <8 x half> %b) #0 {
 define <8 x i1> @test_fcmp_ueq(<8 x half> %a, <8 x half> %b) #0 {
 ; CHECK-CVT-SD-LABEL: test_fcmp_ueq:
 ; CHECK-CVT-SD:       // %bb.0:
-; CHECK-CVT-SD-NEXT:    fcvtl2 v2.4s, v1.8h
-; CHECK-CVT-SD-NEXT:    fcvtl2 v3.4s, v0.8h
-; CHECK-CVT-SD-NEXT:    fcvtl v1.4s, v1.4h
-; CHECK-CVT-SD-NEXT:    fcvtl v0.4s, v0.4h
+; CHECK-CVT-SD-NEXT:    fcvtl v2.4s, v1.4h
+; CHECK-CVT-SD-NEXT:    fcvtl v3.4s, v0.4h
+; CHECK-CVT-SD-NEXT:    fcvtl2 v1.4s, v1.8h
+; CHECK-CVT-SD-NEXT:    fcvtl2 v0.4s, v0.8h
 ; CHECK-CVT-SD-NEXT:    fcmgt v4.4s, v3.4s, v2.4s
 ; CHECK-CVT-SD-NEXT:    fcmgt v2.4s, v2.4s, v3.4s
 ; CHECK-CVT-SD-NEXT:    fcmgt v3.4s, v0.4s, v1.4s
 ; CHECK-CVT-SD-NEXT:    fcmgt v0.4s, v1.4s, v0.4s
-; CHECK-CVT-SD-NEXT:    orr v1.16b, v2.16b, v4.16b
-; CHECK-CVT-SD-NEXT:    orr v0.16b, v0.16b, v3.16b
-; CHECK-CVT-SD-NEXT:    uzp1 v0.8h, v0.8h, v1.8h
-; CHECK-CVT-SD-NEXT:    mvn v0.16b, v0.16b
+; CHECK-CVT-SD-NEXT:    addhn v2.4h, v2.4s, v4.4s
+; CHECK-CVT-SD-NEXT:    addhn2 v2.8h, v0.4s, v3.4s
+; CHECK-CVT-SD-NEXT:    mvn v0.16b, v2.16b
 ; CHECK-CVT-SD-NEXT:    xtn v0.8b, v0.8h
 ; CHECK-CVT-SD-NEXT:    ret
 ;
@@ -1093,18 +1092,17 @@ define <8 x i1> @test_fcmp_ule(<8 x half> %a, <8 x half> %b) #0 {
 define <8 x i1> @test_fcmp_uno(<8 x half> %a, <8 x half> %b) #0 {
 ; CHECK-CVT-SD-LABEL: test_fcmp_uno:
 ; CHECK-CVT-SD:       // %bb.0:
-; CHECK-CVT-SD-NEXT:    fcvtl2 v2.4s, v1.8h
-; CHECK-CVT-SD-NEXT:    fcvtl2 v3.4s, v0.8h
-; CHECK-CVT-SD-NEXT:    fcvtl v1.4s, v1.4h
-; CHECK-CVT-SD-NEXT:    fcvtl v0.4s, v0.4h
+; CHECK-CVT-SD-NEXT:    fcvtl v2.4s, v1.4h
+; CHECK-CVT-SD-NEXT:    fcvtl v3.4s, v0.4h
+; CHECK-CVT-SD-NEXT:    fcvtl2 v1.4s, v1.8h
+; CHECK-CVT-SD-NEXT:    fcvtl2 v0.4s, v0.8h
 ; CHECK-CVT-SD-NEXT:    fcmge v4.4s, v3.4s, v2.4s
 ; CHECK-CVT-SD-NEXT:    fcmgt v2.4s, v2.4s, v3.4s
 ; CHECK-CVT-SD-NEXT:    fcmge v3.4s, v0.4s, v1.4s
 ; CHECK-CVT-SD-NEXT:    fcmgt v0.4s, v1.4s, v0.4s
-; CHECK-CVT-SD-NEXT:    orr v1.16b, v2.16b, v4.16b
-; CHECK-CVT-SD-NEXT:    orr v0.16b, v0.16b, v3.16b
-; CHECK-CVT-SD-NEXT:    uzp1 v0.8h, v0.8h, v1.8h
-; CHECK-CVT-SD-NEXT:    mvn v0.16b, v0.16b
+; CHECK-CVT-SD-NEXT:    addhn v2.4h, v2.4s, v4.4s
+; CHECK-CVT-SD-NEXT:    addhn2 v2.8h, v0.4s, v3.4s
+; CHECK-CVT-SD-NEXT:    mvn v0.16b, v2.16b
 ; CHECK-CVT-SD-NEXT:    xtn v0.8b, v0.8h
 ; CHECK-CVT-SD-NEXT:    ret
 ;
@@ -1149,19 +1147,17 @@ define <8 x i1> @test_fcmp_one(<8 x half> %a, <8 x half> %b) #0 {
 ; CHECK-CVT-SD-NEXT:    fcmgt v2.4s, v2.4s, v3.4s
 ; CHECK-CVT-SD-NEXT:    fcmgt v3.4s, v0.4s, v1.4s
 ; CHECK-CVT-SD-NEXT:    fcmgt v0.4s, v1.4s, v0.4s
-; CHECK-CVT-SD-NEXT:    orr v1.16b, v2.16b, v4.16b
-; CHECK-CVT-SD-NEXT:    orr v0.16b, v0.16b, v3.16b
-; CHECK-CVT-SD-NEXT:    uzp1 v0.8h, v0.8h, v1.8h
-; CHECK-CVT-SD-NEXT:    xtn v0.8b, v0.8h
+; CHECK-CVT-SD-NEXT:    addhn v1.4h, v2.4s, v4.4s
+; CHECK-CVT-SD-NEXT:    addhn v0.4h, v0.4s, v3.4s
+; CHECK-CVT-SD-NEXT:    uzp1 v0.8b, v0.8b, v1.8b
 ; CHECK-CVT-SD-NEXT:    ret
 ;
-; CHECK-FP16-LABEL: test_fcmp_one:
-; CHECK-FP16:       // %bb.0:
-; CHECK-FP16-NEXT:    fcmgt v2.8h, v0.8h, v1.8h
-; CHECK-FP16-NEXT:    fcmgt v0.8h, v1.8h, v0.8h
-; CHECK-FP16-NEXT:    orr v0.16b, v0.16b, v2.16b
-; CHECK-FP16-NEXT:    xtn v0.8b, v0.8h
-; CHECK-FP16-NEXT:    ret
+; CHECK-FP16-SD-LABEL: test_fcmp_one:
+; CHECK-FP16-SD:       // %bb.0:
+; CHECK-FP16-SD-NEXT:    fcmgt v2.8h, v0.8h, v1.8h
+; CHECK-FP16-SD-NEXT:    fcmgt v0.8h, v1.8h, v0.8h
+; CHECK-FP16-SD-NEXT:    addhn v0.8b, v0.8h, v2.8h
+; CHECK-FP16-SD-NEXT:    ret
 ;
 ; CHECK-CVT-GI-LABEL: test_fcmp_one:
 ; CHECK-CVT-GI:       // %bb.0:
@@ -1178,6 +1174,14 @@ define <8 x i1> @test_fcmp_one(<8 x half> %a, <8 x half> %b) #0 {
 ; CHECK-CVT-GI-NEXT:    uzp1 v0.8h, v1.8h, v0.8h
 ; CHECK-CVT-GI-NEXT:    xtn v0.8b, v0.8h
 ; CHECK-CVT-GI-NEXT:    ret
+;
+; CHECK-FP16-GI-LABEL: test_fcmp_one:
+; CHECK-FP16-GI:       // %bb.0:
+; CHECK-FP16-GI-NEXT:    fcmgt v2.8h, v0.8h, v1.8h
+; CHECK-FP16-GI-NEXT:    fcmgt v0.8h, v1.8h, v0.8h
+; CHECK-FP16-GI-NEXT:    orr v0.16b, v0.16b, v2.16b
+; CHECK-FP16-GI-NEXT:    xtn v0.8b, v0.8h
+; CHECK-FP16-GI-NEXT:    ret
   %1 = fcmp one <8 x half> %a, %b
   ret <8 x i1> %1
 }
@@ -1363,19 +1367,17 @@ define <8 x i1> @test_fcmp_ord(<8 x half> %a, <8 x half> %b) #0 {
 ; CHECK-CVT-SD-NEXT:    fcmgt v2.4s, v2.4s, v3.4s
 ; CHECK-CVT-SD-NEXT:    fcmge v3.4s, v0.4s, v1.4s
 ; CHECK-CVT-SD-NEXT:    fcmgt v0.4s, v1.4s, v0.4s
-; CHECK-CVT-SD-NEXT:    orr v1.16b, v2.16b, v4.16b
-; CHECK-CVT-SD-NEXT:    orr v0.16b, v0.16b, v3.16b
-; CHECK-CVT-SD-NEXT:    uzp1 v0.8h, v0.8h, v1.8h
-; CHECK-CVT-SD-NEXT:    xtn v0.8b, v0.8h
+; CHECK-CVT-SD-NEXT:    addhn v1.4h, v2.4s, v4.4s
+; CHECK-CVT-SD-NEXT:    addhn v0.4h, v0.4s, v3.4s
+; CHECK-CVT-SD-NEXT:    uzp1 v0.8b, v0.8b, v1.8b
 ; CHECK-CVT-SD-NEXT:    ret
 ;
-; CHECK-FP16-LABEL: test_fcmp_ord:
-; CHECK-FP16:       // %bb.0:
-; CHECK-FP16-NEXT:    fcmge v2.8h, v0.8h, v1.8h
-; CHECK-FP16-NEXT:    fcmgt v0.8h, v1.8h, v0.8h
-; CHECK-FP16-NEXT:    orr v0.16b, v0.16b, v2.16b
-; CHECK-FP16-NEXT:    xtn v0.8b, v0.8h
-; CHECK-FP16-NEXT:    ret
+; CHECK-FP16-SD-LABEL: test_fcmp_ord:
+; CHECK-FP16-SD:       // %bb.0:
+; CHECK-FP16-SD-NEXT:    fcmge v2.8h, v0.8h, v1.8h
+; CHECK-FP16-SD-NEXT:    fcmgt v0.8h, v1.8h, v0.8h
+; CHECK-FP16-SD-NEXT:    addhn v0.8b, v0.8h, v2.8h
+; CHECK-FP16-SD-NEXT:    ret
 ;
 ; CHECK-CVT-GI-LABEL: test_fcmp_ord:
 ; CHECK-CVT-GI:       // %bb.0:
@@ -1392,6 +1394,14 @@ define <8 x i1> @test_fcmp_ord(<8 x half> %a, <8 x half> %b) #0 {
 ; CHECK-CVT-GI-NEXT:    uzp1 v0.8h, v1.8h, v0.8h
 ; CHECK-CVT-GI-NEXT:    xtn v0.8b, v0.8h
 ; CHECK-CVT-GI-NEXT:    ret
+;
+; CHECK-FP16-GI-LABEL: test_fcmp_ord:
+; CHECK-FP16-GI:       // %bb.0:
+; CHECK-FP16-GI-NEXT:    fcmge v2.8h, v0.8h, v1.8h
+; CHECK-FP16-GI-NEXT:    fcmgt v0.8h, v1.8h, v0.8h
+; CHECK-FP16-GI-NEXT:    orr v0.16b, v0.16b, v2.16b
+; CHECK-FP16-GI-NEXT:    xtn v0.8b, v0.8h
+; CHECK-FP16-GI-NEXT:    ret
   %1 = fcmp ord <8 x half> %a, %b
   ret <8 x i1> %1
 }
diff --git a/llvm/test/CodeGen/AArch64/half-precision-signof-no-assert.ll b/llvm/test/CodeGen/AArch64/half-precision-signof-no-assert.ll
index 4bf2b8c7e6a57..b5831e3236622 100644
--- a/llvm/test/CodeGen/AArch64/half-precision-signof-no-assert.ll
+++ b/llvm/test/CodeGen/AArch64/half-precision-signof-no-assert.ll
@@ -14,9 +14,8 @@ define ptr @fn(ptr %in, ptr %out) {
 ; CHECK-SD-NEXT:    fcvtl v1.4s, v1.4h
 ; CHECK-SD-NEXT:    fcmgt v2.4s, v1.4s, #0.0
 ; CHECK-SD-NEXT:    fcmlt v1.4s, v1.4s, #0.0
-; CHECK-SD-NEXT:    orr v1.16b, v1.16b, v2.16b
+; CHECK-SD-NEXT:    addhn v1.4h, v1.4s, v2.4s
 ; CHECK-SD-NEXT:    ldr h2, [x8, :lo12:.LCPI0_0]
-; CHECK-SD-NEXT:    xtn v1.4h, v1.4s
 ; CHECK-SD-NEXT:    and v0.8b, v1.8b, v0.8b
 ; CHECK-SD-NEXT:    movi d1, #0000000000000000
 ; CHECK-SD-NEXT:    str d0, [x1]
diff --git a/llvm/test/CodeGen/AArch64/intrinsic-vector-match-sve2.ll b/llvm/test/CodeGen/AArch64/intrinsic-vector-match-sve2.ll
index de88e10141fbf..8ef3314ba2681 100644
--- a/llvm/test/CodeGen/AArch64/intrinsic-vector-match-sve2.ll
+++ b/llvm/test/CodeGen/AArch64/intrinsic-vector-match-sve2.ll
@@ -502,12 +502,11 @@ define <4 x i1> @match_v4xi32_v4i32(<4 x i32> %op1, <4 x i32> %op2, <4 x i1> %ma
 ; CHECK-NEXT:    dup v1.4s, v1.s[3]
 ; CHECK-NEXT:    cmeq v3.4s, v0.4s, v3.4s
 ; CHECK-NEXT:    cmeq v4.4s, v0.4s, v4.4s
-; CHECK-NEXT:    cmeq v5.4s, v0.4s, v5.4s
+; CHECK-NEXT:    orr v3.16b, v4.16b, v3.16b
+; CHECK-NEXT:    cmeq v4.4s, v0.4s, v5.4s
 ; CHECK-NEXT:    cmeq v0.4s, v0.4s, v1.4s
-; CHECK-NEXT:    orr v1.16b, v4.16b, v3.16b
-; CHECK-NEXT:    orr v0.16b, v5.16b, v0.16b
-; CHECK-NEXT:    orr v0.16b, v1.16b, v0.16b
-; CHECK-NEXT:    xtn v0.4h, v0.4s
+; CHECK-NEXT:    orr v3.16b, v3.16b, v4.16b
+; CHECK-NEXT:    addhn v0.4h, v3.4s, v0.4s
 ; CHECK-NEXT:    and v0.8b, v0.8b, v2.8b
 ; CHECK-NEXT:    ret
   %r = tail call <4 x i1> @llvm.experimental.vector.match(<4 x i32> %op1, <4 x i32> %op2, <4 x i1> %mask)
@@ -521,8 +520,7 @@ define <2 x i1> @match_v2xi64_v2i64(<2 x i64> %op1, <2 x i64> %op2, <2 x i1> %ma
 ; CHECK-NEXT:    dup v1.2d, v1.d[0]
 ; CHECK-NEXT:    cmeq v3.2d, v0.2d, v3.2d
 ; CHECK-NEXT:    cmeq v0.2d, v0.2d, v1.2d
-; CHECK-NEXT:    orr v0.16b, v0.16b, v3.16b
-; CHECK-NEXT:    xtn v0.2s, v0.2d
+; CHECK-NEXT:    addhn v0.2s, v0.2d, v3.2d
 ; CHECK-NEXT:    and v0.8b, v0.8b, v2.8b
 ; CHECK-NEXT:    ret
   %r = tail call <2 x i1> @llvm.experimental.vector.match(<2 x i64> %op1, <2 x i64> %op2, <2 x i1> %mask)
diff --git a/llvm/test/CodeGen/AArch64/is_fpclass.ll b/llvm/test/CodeGen/AArch64/is_fpclass.ll
index 19ce95641fe98..e2ed2d96a85de 100644
--- a/llvm/test/CodeGen/AArch64/is_fpclass.ll
+++ b/llvm/test/CodeGen/AArch64/is_fpclass.ll
@@ -477,8 +477,7 @@ define <4 x i1> @isfinite_v4f(<4 x float> %x) {
 ; CHECK-SD-NEXT:    fneg v1.4s, v1.4s
 ; CHECK-SD-NEXT:    fcmgt v2.4s, v0.4s, v1.4s
 ; CHECK-SD-NEXT:    fcmgt v0.4s, v1.4s, v0.4s
-; CHECK-SD-NEXT:    orr v0.16b, v0.16b, v2.16b
-; CHECK-SD-NEXT:    xtn v0.4h, v0.4s
+; CHECK-SD-NEXT:    addhn v0.4h, v0.4s, v2.4s
 ; CHECK-SD-NEXT:    ret
 ;
 ; CHECK-GI-LABEL: isfinite_v4f:
@@ -571,8 +570,7 @@ define <2 x i1> @isfinite_v2d(<2 x double> %x) {
 ; CHECK-SD-NEXT:    dup v1.2d, x8
 ; CHECK-SD-NEXT:    fcmgt v2.2d, v0.2d, v1.2d
 ; CHECK-SD-NEXT:    fcmgt v0.2d, v1.2d, v0.2d
-; CHECK-SD-NEXT:    orr v0.16b, v0.16b, v2.16b
-; CHECK-SD-NEXT:    xtn v0.2s, v0.2d
+; CHECK-SD-NEXT:    addhn v0.2s, v0.2d, v2.2d
 ; CHECK-SD-NEXT:    ret
 ;
 ; CHECK-GI-LABEL: isfinite_v2d:
diff --git a/llvm/test/CodeGen/AArch64/neon-addhn.ll b/llvm/test/CodeGen/AArch64/neon-addhn.ll
index 3f3277dc36329..23e290195e192 100644
--- a/llvm/test/CodeGen/AArch64/neon-addhn.ll
+++ b/llvm/test/CodeGen/AArch64/neon-addhn.ll
@@ -3,13 +3,20 @@
 ; RUN: llc < %s -mtriple=aarch64 -global-isel | FileCheck %s --check-prefixes=CHECK,CHECK-GI
 
 define <8 x i8> @addhn_setcc_v8i16( <8 x i16> %a, <8 x i16> %b, <8 x i16> %comparand) {
-; CHECK-LABEL: addhn_setcc_v8i16:
-; CHECK:       // %bb.0:
-; CHECK-NEXT:    cmeq v0.8h, v0.8h, v2.8h
-; CHECK-NEXT:    cmeq v1.8h, v1.8h, v2.8h
-; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
-; CHECK-NEXT:    xtn v0.8b, v0.8h
-; CHECK-NEXT:    ret
+; CHECK-SD-LABEL: addhn_setcc_v8i16:
+; CHECK-SD:       // %bb.0:
+; CHECK-SD-NEXT:    cmeq v0.8h, v0.8h, v2.8h
+; CHECK-SD-NEXT:    cmeq v1.8h, v1.8h, v2.8h
+; CHECK-SD-NEXT:    addhn v0.8b, v0.8h, v1.8h
+; CHECK-SD-NEXT:    ret
+;
+; CHECK-GI-LABEL: addhn_setcc_v8i16:
+; CHECK-GI:       // %bb.0:
+; CHECK-GI-NEXT:    cmeq v0.8h, v0.8h, v2.8h
+; CHECK-GI-NEXT:    cmeq v1.8h, v1.8h, v2.8h
+; CHECK-GI-NEXT:    orr v0.16b, v0.16b, v1.16b
+; CHECK-GI-NEXT:    xtn v0.8b, v0.8h
+; CHECK-GI-NEXT:    ret
   %cmp.a = icmp eq <8 x i16> %a, %comparand
   %cmp.b = icmp eq <8 x i16> %b, %comparand
   %either = or <8 x i1> %cmp.a, %cmp.b
@@ -18,13 +25,20 @@ define <8 x i8> @addhn_setcc_v8i16( <8 x i16> %a, <8 x i16> %b, <8 x i16> %compa
 }
 
 define <4 x i16> @addhn_setcc_v4i32( <4 x i32> %a, <4 x i32> %b, <4 x i32> %comparand) {
-; CHECK-LABEL: addhn_setcc_v4i32:
-; CHECK:       // %bb.0:
-; CHECK-NEXT:    cmeq v0.4s, v0.4s, v2.4s
-; CHECK-NEXT:    cmeq v1.4s, v1.4s, v2.4s
-; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
-; CHECK-NEXT:    xtn v0.4h, v0.4s
-; CHECK-NEXT:    ret
+; CHECK-SD-LABEL: addhn_setcc_v4i32:
+; CHECK-SD:       // %bb.0:
+; CHECK-SD-NEXT:    cmeq v0.4s, v0.4s, v2.4s
+; CHECK-SD-NEXT:    cmeq v1.4s, v1.4s, v2.4s
+; CHECK-SD-NEXT:    addhn v0.4h, v0.4s, v1.4s
+; CHECK-SD-NEXT:    ret
+;
+; CHECK-GI-LABEL: addhn_setcc_v4i32:
+; CHECK-GI:       // %bb.0:
+; CHECK-GI-NEXT:    cmeq v0.4s, v0.4s, v2.4s
+; CHECK-GI-NEXT:    cmeq v1.4s, v1.4s, v2.4s
+; CHECK-GI-NEXT:    orr v0.16b, v0.16b, v1.16b
+; CHECK-GI-NEXT:    xtn v0.4h, v0.4s
+; CHECK-GI-NEXT:    ret
   %cmp.a = icmp eq <4 x i32> %a, %comparand
   %cmp.b = icmp eq <4 x i32> %b, %comparand
   %either = or <4 x i1> %cmp.a, %cmp.b
@@ -33,13 +47,20 @@ define <4 x i16> @addhn_setcc_v4i32( <4 x i32> %a, <4 x i32> %b, <4 x i32> %comp
 }
 
 define <2 x i32> @addhn_setcc_v2i64( <2 x i64> %a, <2 x i64> %b, <2 x i64> %comparand) {
-; CHECK-LABEL: addhn_setcc_v2i64:
-; CHECK:       // %bb.0:
-; CHECK-NEXT:    cmeq v0.2d, v0.2d, v2.2d
-; CHECK-NEXT:    cmeq v1.2d, v1.2d, v2.2d
-; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
-; CHECK-NEXT:    xtn v0.2s, v0.2d
-; CHECK-NEXT:    ret
+; CHECK-SD-LABEL: addhn_setcc_v2i64:
+; CHECK-SD:       // %bb.0:
+; CHECK-SD-NEXT:    cmeq v0.2d, v0.2d, v2.2d
+; CHECK-SD-NEXT:    cmeq v1.2d, v1.2d, v2.2d
+; CHECK-SD-NEXT:    addhn v0.2s, v0.2d, v1.2d
+; CHECK-SD-NEXT:    ret
+;
+; CHECK-GI-LABEL: addhn_setcc_v2i64:
+; CHECK-GI:       // %bb.0:
+; CHECK-GI-NEXT:    cmeq v0.2d, v0.2d, v2.2d
+; CHECK-GI-NEXT:    cmeq v1.2d, v1.2d, v2.2d
+; CHECK-GI-NEXT:    orr v0.16b, v0.16b, v1.16b
+; CHECK-GI-NEXT:    xtn v0.2s, v0.2d
+; CHECK-GI-NEXT:    ret
   %cmp.a = icmp eq <2 x i64> %a, %comparand
   %cmp.b = icmp eq <2 x i64> %b, %comparand
   %either = or <2 x i1> %cmp.a, %cmp.b
@@ -48,5 +69,4 @@ define <2 x i32> @addhn_setcc_v2i64( <2 x i64> %a, <2 x i64> %b, <2 x i64> %comp
 }
 
 ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; CHECK-GI: {{.*}}
-; CHECK-SD: {{.*}}
+; CHECK: {{.*}}
diff --git a/llvm/test/CodeGen/AArch64/select-with-and-or.ll b/llvm/test/CodeGen/AArch64/select-with-and-or.ll
index 60f2add81b45c..4f35f81ca2cdf 100644
--- a/llvm/test/CodeGen/AArch64/select-with-and-or.ll
+++ b/llvm/test/CodeGen/AArch64/select-with-and-or.ll
@@ -119,8 +119,7 @@ define <4 x i1> @or_vec(<4 x i32> %x, <4 x i32> %y, <4 x i32> %z, <4 x i32> %w)
 ; CHECK-SD:       // %bb.0:
 ; CHECK-SD-NEXT:    cmgt v2.4s, v2.4s, v3.4s
 ; CHECK-SD-NEXT:    cmeq v0.4s, v0.4s, v1.4s
-; CHECK-SD-NEXT:    orr v0.16b, v0.16b, v2.16b
-; CHECK-SD-NEXT:    xtn v0.4h, v0.4s
+; CHECK-SD-NEXT:    addhn v0.4h, v0.4s, v2.4s
 ; CHECK-SD-NEXT:    ret
 ;
 ; CHECK-GI-LABEL: or_vec:
@@ -161,10 +160,10 @@ define <4 x i1> @and_not_vec(<4 x i32> %x, <4 x i32> %y, <4 x i32> %z, <4 x i32>
 define <4 x i1> @or_not_vec(<4 x i32> %x, <4 x i32> %y, <4 x i32> %z, <4 x i32> %w) {
 ; CHECK-SD-LABEL: or_not_vec:
 ; CHECK-SD:       // %bb.0:
-; CHECK-SD-NEXT:    cmgt v2.4s, v2.4s, v3.4s
 ; CHECK-SD-NEXT:    cmeq v0.4s, v0.4s, v1.4s
-; CHECK-SD-NEXT:    orn v0.16b, v2.16b, v0.16b
-; CHECK-SD-NEXT:    xtn v0.4h, v0.4s
+; CHECK-SD-NEXT:    cmgt v2.4s, v2.4s, v3.4s
+; CHECK-SD-NEXT:    mvn v0.16b, v0.16b
+; CHECK-SD-NEXT:    addhn v0.4h, v0.4s, v2.4s
 ; CHECK-SD-NEXT:    ret
 ;
 ; CHECK-GI-LABEL: or_not_vec:
@@ -207,8 +206,7 @@ define <4 x i1> @or_vec_undef(<4 x i32> %x, <4 x i32> %y, <4 x i32> %z, <4 x i32
 ; CHECK-SD:       // %bb.0:
 ; CHECK-SD-NEXT:    cmgt v2.4s, v2.4s, v3.4s
 ; CHECK-SD-NEXT:    cmeq v0.4s, v0.4s, v1.4s
-; CHECK-SD-NEXT:    orr v0.16b, v0.16b, v2.16b
-; CHECK-SD-NEXT:    xtn v0.4h, v0.4s
+; CHECK-SD-NEXT:    addhn v0.4h, v0.4s, v2.4s
 ; CHECK-SD-NEXT:    ret
 ;
 ; CHECK-GI-LABEL: or_vec_undef:
@@ -249,10 +247,10 @@ define <4 x i1> @and_not_vec_undef(<4 x i32> %x, <4 x i32> %y, <4 x i32> %z, <4
 define <4 x i1> @or_not_vec_undef(<4 x i32> %x, <4 x i32> %y, <4 x i32> %z, <4 x i32> %w) {
 ; CHECK-SD-LABEL: or_not_vec_undef:
 ; CHECK-SD:       // %bb.0:
-; CHECK-SD-NEXT:    cmgt v2.4s, v2.4s, v3.4s
 ; CHECK-SD-NEXT:    cmeq v0.4s, v0.4s, v1.4s
-; CHECK-SD-NEXT:    orn v0.16b, v2.16b, v0.16b
-; CHECK-SD-NEXT:    xtn v0.4h, v0.4s
+; CHECK-SD-NEXT:    cmgt v2.4s, v2.4s, v3.4s
+; CHECK-SD-NEXT:    mvn v0.16b, v0.16b
+; CHECK-SD-NEXT:    addhn v0.4h, v0.4s, v2.4s
 ; CHECK-SD-NEXT:    ret
 ;
 ; CHECK-GI-LABEL: or_not_vec_undef:



More information about the llvm-commits mailing list