[llvm] [AArch64][TTI] Tune costs for mulh. (PR #225788)

Ricardo Jesus via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 23 07:09:55 PDT 2026


https://github.com/rj-jesus created https://github.com/llvm/llvm-project/pull/225788

These reuse the mul costs when both instructions lower similarly.

>From 230c2edbe1bcbbfa2b31faa99d77b3132ab59150 Mon Sep 17 00:00:00 2001
From: Ricardo Jesus <rjj at nvidia.com>
Date: Tue, 22 Sep 2026 08:44:57 -0700
Subject: [PATCH 1/2] Update runlines

---
 llvm/test/Analysis/CostModel/AArch64/mulh.ll | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/llvm/test/Analysis/CostModel/AArch64/mulh.ll b/llvm/test/Analysis/CostModel/AArch64/mulh.ll
index 25e5554e1c5a58..097cd1f8a663bf 100644
--- a/llvm/test/Analysis/CostModel/AArch64/mulh.ll
+++ b/llvm/test/Analysis/CostModel/AArch64/mulh.ll
@@ -1,6 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 6
 ; RUN: opt < %s -mtriple=aarch64 -passes="print<cost-model>" -cost-kind=all -disable-output 2>&1 | FileCheck %s --check-prefixes=CHECK,NEON
-; RUN: opt < %s -mtriple=aarch64 -mattr=+sve -passes="print<cost-model>" -cost-kind=all -disable-output 2>&1 | FileCheck %s --check-prefixes=CHECK,SVE
+; RUN: opt < %s -mtriple=aarch64 -mattr=+sve -passes="print<cost-model>" -cost-kind=all -disable-output 2>&1 | FileCheck %s --check-prefixes=CHECK,SVE,SVE-STD
+; RUN: opt < %s -mtriple=aarch64 -mattr=+sve,+has-limited-64bit-vector-mul-bandwidth -passes="print<cost-model>" -cost-kind=all -disable-output 2>&1 | FileCheck %s --check-prefixes=CHECK,SVE,SVE-HIGH
 
 define void @smulh() {
 ; CHECK-LABEL: 'smulh'
@@ -179,3 +180,6 @@ define void @umulh_vec() {
 
   ret void
 }
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; SVE-HIGH: {{.*}}
+; SVE-STD: {{.*}}

>From 865b5caf3d967c087c73af59672219805e27af18 Mon Sep 17 00:00:00 2001
From: Ricardo Jesus <rjj at nvidia.com>
Date: Tue, 22 Sep 2026 08:20:36 -0700
Subject: [PATCH 2/2] [AArch64][TTI] Add specific costs for mulh.

These reuse the mul costs when both instructions lower similarly.
---
 .../AArch64/AArch64TargetTransformInfo.cpp    |  46 ++++
 llvm/test/Analysis/CostModel/AArch64/mulh.ll  | 256 ++++++++++++------
 .../Analysis/CostModel/AArch64/sve-mulh.ll    |  16 +-
 3 files changed, 220 insertions(+), 98 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
index 581f37d4c17bce..0dad2a6c061584 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
@@ -706,6 +706,52 @@ AArch64TTIImpl::getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
     }
     break;
   }
+  case Intrinsic::smulh:
+  case Intrinsic::umulh: {
+    InstructionCost MulCost =
+        getArithmeticInstrCost(Instruction::Mul, RetTy, CostKind);
+
+    // Wide types like i128 need every partial product of a wide multiply
+    // and the carry chain between them. This is a crude cost approximation.
+    if (RetTy->getScalarSizeInBits() > 64)
+      return 2 * MulCost;
+
+    auto LT = getTypeLegalizationCost(RetTy);
+    MVT MTy = LT.second;
+
+    // Per-register cost to extend the operands.
+    InstructionCost ExtraCost =
+        LT.first *
+        (MTy.getScalarSizeInBits() != RetTy->getScalarSizeInBits() ? 2 : 0);
+
+    // MULH and MUL lower similarly for 64-bit products. For vectors, they
+    // also share the reduced vector multiply bandwidth seen on some cores.
+    if (MTy.getScalarSizeInBits() == 64)
+      return MulCost + ExtraCost;
+
+    // Scalable vectors (and fixed-length vectors, when possible) use SVE.
+    if (MTy.isScalableVector() ||
+        (MTy.isFixedLengthVector() && ST->isSVEorStreamingSVEAvailable()))
+      return LT.first + ExtraCost;
+
+    static const CostTblEntry MulHighCostTbl[] = {
+        {ISD::MULHU, MVT::i32, 2}, // [su]mull + lsr
+
+        {ISD::MULHU, MVT::v8i8, 2},  // [su]mull + shrn
+        {ISD::MULHU, MVT::v4i16, 2}, // "
+        {ISD::MULHU, MVT::v2i32, 2}, // "
+
+        {ISD::MULHU, MVT::v16i8, 3}, // [su]mull + [su]mull2 + uzp2
+        {ISD::MULHU, MVT::v8i16, 3}, // "
+        {ISD::MULHU, MVT::v4i32, 3}, // "
+    };
+
+    // Currently we assume SMULH has the same cost as UMULH.
+    if (const auto *Entry = CostTableLookup(MulHighCostTbl, ISD::MULHU, MTy))
+      return LT.first * Entry->Cost + ExtraCost;
+
+    break;
+  }
   case Intrinsic::umin:
   case Intrinsic::umax:
   case Intrinsic::smin:
diff --git a/llvm/test/Analysis/CostModel/AArch64/mulh.ll b/llvm/test/Analysis/CostModel/AArch64/mulh.ll
index 097cd1f8a663bf..b1398f76768a12 100644
--- a/llvm/test/Analysis/CostModel/AArch64/mulh.ll
+++ b/llvm/test/Analysis/CostModel/AArch64/mulh.ll
@@ -4,13 +4,29 @@
 ; RUN: opt < %s -mtriple=aarch64 -mattr=+sve,+has-limited-64bit-vector-mul-bandwidth -passes="print<cost-model>" -cost-kind=all -disable-output 2>&1 | FileCheck %s --check-prefixes=CHECK,SVE,SVE-HIGH
 
 define void @smulh() {
-; CHECK-LABEL: 'smulh'
-; CHECK-NEXT:  Cost Model: Found costs of 4 for: %I8 = call i8 @llvm.smulh.i8(i8 poison, i8 poison)
-; CHECK-NEXT:  Cost Model: Found costs of 4 for: %I16 = call i16 @llvm.smulh.i16(i16 poison, i16 poison)
-; CHECK-NEXT:  Cost Model: Found costs of 4 for: %I32 = call i32 @llvm.smulh.i32(i32 poison, i32 poison)
-; CHECK-NEXT:  Cost Model: Found costs of 1 for: %I64 = call i64 @llvm.smulh.i64(i64 poison, i64 poison)
-; CHECK-NEXT:  Cost Model: Found costs of 4 for: %I128 = call i128 @llvm.smulh.i128(i128 poison, i128 poison)
-; CHECK-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
+; NEON-LABEL: 'smulh'
+; NEON-NEXT:  Cost Model: Found costs of 4 for: %I8 = call i8 @llvm.smulh.i8(i8 poison, i8 poison)
+; NEON-NEXT:  Cost Model: Found costs of 4 for: %I16 = call i16 @llvm.smulh.i16(i16 poison, i16 poison)
+; NEON-NEXT:  Cost Model: Found costs of 2 for: %I32 = call i32 @llvm.smulh.i32(i32 poison, i32 poison)
+; NEON-NEXT:  Cost Model: Found costs of 1 for: %I64 = call i64 @llvm.smulh.i64(i64 poison, i64 poison)
+; NEON-NEXT:  Cost Model: Found costs of 8 for: %I128 = call i128 @llvm.smulh.i128(i128 poison, i128 poison)
+; NEON-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
+;
+; SVE-STD-LABEL: 'smulh'
+; SVE-STD-NEXT:  Cost Model: Found costs of 4 for: %I8 = call i8 @llvm.smulh.i8(i8 poison, i8 poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 4 for: %I16 = call i16 @llvm.smulh.i16(i16 poison, i16 poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 2 for: %I32 = call i32 @llvm.smulh.i32(i32 poison, i32 poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 1 for: %I64 = call i64 @llvm.smulh.i64(i64 poison, i64 poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 8 for: %I128 = call i128 @llvm.smulh.i128(i128 poison, i128 poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
+;
+; SVE-HIGH-LABEL: 'smulh'
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 4 for: %I8 = call i8 @llvm.smulh.i8(i8 poison, i8 poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 4 for: %I16 = call i16 @llvm.smulh.i16(i16 poison, i16 poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 2 for: %I32 = call i32 @llvm.smulh.i32(i32 poison, i32 poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 1 for: %I64 = call i64 @llvm.smulh.i64(i64 poison, i64 poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of RThru:32 CodeSize:8 Lat:8 SizeLat:8 for: %I128 = call i128 @llvm.smulh.i128(i128 poison, i128 poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
 ;
   %I8 = call i8 @llvm.smulh.i8(i8 poison, i8 poison)
   %I16 = call i16 @llvm.smulh.i16(i16 poison, i16 poison)
@@ -21,13 +37,29 @@ define void @smulh() {
 }
 
 define void @umulh() {
-; CHECK-LABEL: 'umulh'
-; CHECK-NEXT:  Cost Model: Found costs of 4 for: %I8 = call i8 @llvm.umulh.i8(i8 poison, i8 poison)
-; CHECK-NEXT:  Cost Model: Found costs of 4 for: %I16 = call i16 @llvm.umulh.i16(i16 poison, i16 poison)
-; CHECK-NEXT:  Cost Model: Found costs of 2 for: %I32 = call i32 @llvm.umulh.i32(i32 poison, i32 poison)
-; CHECK-NEXT:  Cost Model: Found costs of 1 for: %I64 = call i64 @llvm.umulh.i64(i64 poison, i64 poison)
-; CHECK-NEXT:  Cost Model: Found costs of 4 for: %I128 = call i128 @llvm.umulh.i128(i128 poison, i128 poison)
-; CHECK-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
+; NEON-LABEL: 'umulh'
+; NEON-NEXT:  Cost Model: Found costs of 4 for: %I8 = call i8 @llvm.umulh.i8(i8 poison, i8 poison)
+; NEON-NEXT:  Cost Model: Found costs of 4 for: %I16 = call i16 @llvm.umulh.i16(i16 poison, i16 poison)
+; NEON-NEXT:  Cost Model: Found costs of 2 for: %I32 = call i32 @llvm.umulh.i32(i32 poison, i32 poison)
+; NEON-NEXT:  Cost Model: Found costs of 1 for: %I64 = call i64 @llvm.umulh.i64(i64 poison, i64 poison)
+; NEON-NEXT:  Cost Model: Found costs of 8 for: %I128 = call i128 @llvm.umulh.i128(i128 poison, i128 poison)
+; NEON-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
+;
+; SVE-STD-LABEL: 'umulh'
+; SVE-STD-NEXT:  Cost Model: Found costs of 4 for: %I8 = call i8 @llvm.umulh.i8(i8 poison, i8 poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 4 for: %I16 = call i16 @llvm.umulh.i16(i16 poison, i16 poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 2 for: %I32 = call i32 @llvm.umulh.i32(i32 poison, i32 poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 1 for: %I64 = call i64 @llvm.umulh.i64(i64 poison, i64 poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 8 for: %I128 = call i128 @llvm.umulh.i128(i128 poison, i128 poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
+;
+; SVE-HIGH-LABEL: 'umulh'
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 4 for: %I8 = call i8 @llvm.umulh.i8(i8 poison, i8 poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 4 for: %I16 = call i16 @llvm.umulh.i16(i16 poison, i16 poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 2 for: %I32 = call i32 @llvm.umulh.i32(i32 poison, i32 poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 1 for: %I64 = call i64 @llvm.umulh.i64(i64 poison, i64 poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of RThru:32 CodeSize:8 Lat:8 SizeLat:8 for: %I128 = call i128 @llvm.umulh.i128(i128 poison, i128 poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
 ;
   %I8 = call i8 @llvm.umulh.i8(i8 poison, i8 poison)
   %I16 = call i16 @llvm.umulh.i16(i16 poison, i16 poison)
@@ -41,46 +73,68 @@ define void @smulh_vec() {
 ; NEON-LABEL: 'smulh_vec'
 ; NEON-NEXT:  Cost Model: Found costs of 4 for: %V2I8 = call <2 x i8> @llvm.smulh.v2i8(<2 x i8> poison, <2 x i8> poison)
 ; NEON-NEXT:  Cost Model: Found costs of 4 for: %V4I8 = call <4 x i8> @llvm.smulh.v4i8(<4 x i8> poison, <4 x i8> poison)
-; NEON-NEXT:  Cost Model: Found costs of 5 for: %V8I8 = call <8 x i8> @llvm.smulh.v8i8(<8 x i8> poison, <8 x i8> poison)
-; NEON-NEXT:  Cost Model: Found costs of 1 for: %V16I8 = call <16 x i8> @llvm.smulh.v16i8(<16 x i8> poison, <16 x i8> poison)
-; NEON-NEXT:  Cost Model: Found costs of 4 for: %V32I8 = call <32 x i8> @llvm.smulh.v32i8(<32 x i8> poison, <32 x i8> poison)
-; NEON-NEXT:  Cost Model: Found costs of 8 for: %V64I8 = call <64 x i8> @llvm.smulh.v64i8(<64 x i8> poison, <64 x i8> poison)
+; NEON-NEXT:  Cost Model: Found costs of 2 for: %V8I8 = call <8 x i8> @llvm.smulh.v8i8(<8 x i8> poison, <8 x i8> poison)
+; NEON-NEXT:  Cost Model: Found costs of 3 for: %V16I8 = call <16 x i8> @llvm.smulh.v16i8(<16 x i8> poison, <16 x i8> poison)
+; NEON-NEXT:  Cost Model: Found costs of 6 for: %V32I8 = call <32 x i8> @llvm.smulh.v32i8(<32 x i8> poison, <32 x i8> poison)
+; NEON-NEXT:  Cost Model: Found costs of 12 for: %V64I8 = call <64 x i8> @llvm.smulh.v64i8(<64 x i8> poison, <64 x i8> poison)
 ; NEON-NEXT:  Cost Model: Found costs of 4 for: %V2I16 = call <2 x i16> @llvm.smulh.v2i16(<2 x i16> poison, <2 x i16> poison)
-; NEON-NEXT:  Cost Model: Found costs of 5 for: %V4I16 = call <4 x i16> @llvm.smulh.v4i16(<4 x i16> poison, <4 x i16> poison)
-; NEON-NEXT:  Cost Model: Found costs of 1 for: %V8I16 = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> poison, <8 x i16> poison)
-; NEON-NEXT:  Cost Model: Found costs of 4 for: %V16I16 = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> poison, <16 x i16> poison)
-; NEON-NEXT:  Cost Model: Found costs of 8 for: %V32I16 = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> poison, <32 x i16> poison)
-; NEON-NEXT:  Cost Model: Found costs of RThru:18 CodeSize:12 Lat:18 SizeLat:18 for: %V2I32 = call <2 x i32> @llvm.smulh.v2i32(<2 x i32> poison, <2 x i32> poison)
-; NEON-NEXT:  Cost Model: Found costs of 1 for: %V4I32 = call <4 x i32> @llvm.smulh.v4i32(<4 x i32> poison, <4 x i32> poison)
-; NEON-NEXT:  Cost Model: Found costs of 4 for: %V8I32 = call <8 x i32> @llvm.smulh.v8i32(<8 x i32> poison, <8 x i32> poison)
-; NEON-NEXT:  Cost Model: Found costs of 8 for: %V16I32 = call <16 x i32> @llvm.smulh.v16i32(<16 x i32> poison, <16 x i32> poison)
-; NEON-NEXT:  Cost Model: Found costs of RThru:25 CodeSize:21 Lat:25 SizeLat:25 for: %V2I64 = call <2 x i64> @llvm.smulh.v2i64(<2 x i64> poison, <2 x i64> poison)
-; NEON-NEXT:  Cost Model: Found costs of RThru:50 CodeSize:42 Lat:50 SizeLat:50 for: %V4I64 = call <4 x i64> @llvm.smulh.v4i64(<4 x i64> poison, <4 x i64> poison)
-; NEON-NEXT:  Cost Model: Found costs of RThru:100 CodeSize:84 Lat:100 SizeLat:100 for: %V8I64 = call <8 x i64> @llvm.smulh.v8i64(<8 x i64> poison, <8 x i64> poison)
-; NEON-NEXT:  Cost Model: Found costs of 8 for: %V2I128 = call <2 x i128> @llvm.smulh.v2i128(<2 x i128> poison, <2 x i128> poison)
+; NEON-NEXT:  Cost Model: Found costs of 2 for: %V4I16 = call <4 x i16> @llvm.smulh.v4i16(<4 x i16> poison, <4 x i16> poison)
+; NEON-NEXT:  Cost Model: Found costs of 3 for: %V8I16 = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> poison, <8 x i16> poison)
+; NEON-NEXT:  Cost Model: Found costs of 6 for: %V16I16 = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> poison, <16 x i16> poison)
+; NEON-NEXT:  Cost Model: Found costs of 12 for: %V32I16 = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> poison, <32 x i16> poison)
+; NEON-NEXT:  Cost Model: Found costs of 2 for: %V2I32 = call <2 x i32> @llvm.smulh.v2i32(<2 x i32> poison, <2 x i32> poison)
+; NEON-NEXT:  Cost Model: Found costs of 3 for: %V4I32 = call <4 x i32> @llvm.smulh.v4i32(<4 x i32> poison, <4 x i32> poison)
+; NEON-NEXT:  Cost Model: Found costs of 6 for: %V8I32 = call <8 x i32> @llvm.smulh.v8i32(<8 x i32> poison, <8 x i32> poison)
+; NEON-NEXT:  Cost Model: Found costs of 12 for: %V16I32 = call <16 x i32> @llvm.smulh.v16i32(<16 x i32> poison, <16 x i32> poison)
+; NEON-NEXT:  Cost Model: Found costs of RThru:14 CodeSize:8 Lat:14 SizeLat:14 for: %V2I64 = call <2 x i64> @llvm.smulh.v2i64(<2 x i64> poison, <2 x i64> poison)
+; NEON-NEXT:  Cost Model: Found costs of RThru:28 CodeSize:16 Lat:28 SizeLat:28 for: %V4I64 = call <4 x i64> @llvm.smulh.v4i64(<4 x i64> poison, <4 x i64> poison)
+; NEON-NEXT:  Cost Model: Found costs of RThru:56 CodeSize:32 Lat:56 SizeLat:56 for: %V8I64 = call <8 x i64> @llvm.smulh.v8i64(<8 x i64> poison, <8 x i64> poison)
+; NEON-NEXT:  Cost Model: Found costs of 16 for: %V2I128 = call <2 x i128> @llvm.smulh.v2i128(<2 x i128> poison, <2 x i128> poison)
 ; NEON-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
 ;
-; SVE-LABEL: 'smulh_vec'
-; SVE-NEXT:  Cost Model: Found costs of 2 for: %V2I8 = call <2 x i8> @llvm.smulh.v2i8(<2 x i8> poison, <2 x i8> poison)
-; SVE-NEXT:  Cost Model: Found costs of 2 for: %V4I8 = call <4 x i8> @llvm.smulh.v4i8(<4 x i8> poison, <4 x i8> poison)
-; SVE-NEXT:  Cost Model: Found costs of 2 for: %V8I8 = call <8 x i8> @llvm.smulh.v8i8(<8 x i8> poison, <8 x i8> poison)
-; SVE-NEXT:  Cost Model: Found costs of 2 for: %V16I8 = call <16 x i8> @llvm.smulh.v16i8(<16 x i8> poison, <16 x i8> poison)
-; SVE-NEXT:  Cost Model: Found costs of 4 for: %V32I8 = call <32 x i8> @llvm.smulh.v32i8(<32 x i8> poison, <32 x i8> poison)
-; SVE-NEXT:  Cost Model: Found costs of 8 for: %V64I8 = call <64 x i8> @llvm.smulh.v64i8(<64 x i8> poison, <64 x i8> poison)
-; SVE-NEXT:  Cost Model: Found costs of 2 for: %V2I16 = call <2 x i16> @llvm.smulh.v2i16(<2 x i16> poison, <2 x i16> poison)
-; SVE-NEXT:  Cost Model: Found costs of 2 for: %V4I16 = call <4 x i16> @llvm.smulh.v4i16(<4 x i16> poison, <4 x i16> poison)
-; SVE-NEXT:  Cost Model: Found costs of 2 for: %V8I16 = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> poison, <8 x i16> poison)
-; SVE-NEXT:  Cost Model: Found costs of 4 for: %V16I16 = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> poison, <16 x i16> poison)
-; SVE-NEXT:  Cost Model: Found costs of 8 for: %V32I16 = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> poison, <32 x i16> poison)
-; SVE-NEXT:  Cost Model: Found costs of 2 for: %V2I32 = call <2 x i32> @llvm.smulh.v2i32(<2 x i32> poison, <2 x i32> poison)
-; SVE-NEXT:  Cost Model: Found costs of 2 for: %V4I32 = call <4 x i32> @llvm.smulh.v4i32(<4 x i32> poison, <4 x i32> poison)
-; SVE-NEXT:  Cost Model: Found costs of 4 for: %V8I32 = call <8 x i32> @llvm.smulh.v8i32(<8 x i32> poison, <8 x i32> poison)
-; SVE-NEXT:  Cost Model: Found costs of 8 for: %V16I32 = call <16 x i32> @llvm.smulh.v16i32(<16 x i32> poison, <16 x i32> poison)
-; SVE-NEXT:  Cost Model: Found costs of 2 for: %V2I64 = call <2 x i64> @llvm.smulh.v2i64(<2 x i64> poison, <2 x i64> poison)
-; SVE-NEXT:  Cost Model: Found costs of 4 for: %V4I64 = call <4 x i64> @llvm.smulh.v4i64(<4 x i64> poison, <4 x i64> poison)
-; SVE-NEXT:  Cost Model: Found costs of 8 for: %V8I64 = call <8 x i64> @llvm.smulh.v8i64(<8 x i64> poison, <8 x i64> poison)
-; SVE-NEXT:  Cost Model: Found costs of 8 for: %V2I128 = call <2 x i128> @llvm.smulh.v2i128(<2 x i128> poison, <2 x i128> poison)
-; SVE-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
+; SVE-STD-LABEL: 'smulh_vec'
+; SVE-STD-NEXT:  Cost Model: Found costs of 3 for: %V2I8 = call <2 x i8> @llvm.smulh.v2i8(<2 x i8> poison, <2 x i8> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 3 for: %V4I8 = call <4 x i8> @llvm.smulh.v4i8(<4 x i8> poison, <4 x i8> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 1 for: %V8I8 = call <8 x i8> @llvm.smulh.v8i8(<8 x i8> poison, <8 x i8> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 1 for: %V16I8 = call <16 x i8> @llvm.smulh.v16i8(<16 x i8> poison, <16 x i8> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 2 for: %V32I8 = call <32 x i8> @llvm.smulh.v32i8(<32 x i8> poison, <32 x i8> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 4 for: %V64I8 = call <64 x i8> @llvm.smulh.v64i8(<64 x i8> poison, <64 x i8> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 3 for: %V2I16 = call <2 x i16> @llvm.smulh.v2i16(<2 x i16> poison, <2 x i16> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 1 for: %V4I16 = call <4 x i16> @llvm.smulh.v4i16(<4 x i16> poison, <4 x i16> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 1 for: %V8I16 = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> poison, <8 x i16> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 2 for: %V16I16 = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> poison, <16 x i16> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 4 for: %V32I16 = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> poison, <32 x i16> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 1 for: %V2I32 = call <2 x i32> @llvm.smulh.v2i32(<2 x i32> poison, <2 x i32> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 1 for: %V4I32 = call <4 x i32> @llvm.smulh.v4i32(<4 x i32> poison, <4 x i32> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 2 for: %V8I32 = call <8 x i32> @llvm.smulh.v8i32(<8 x i32> poison, <8 x i32> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 4 for: %V16I32 = call <16 x i32> @llvm.smulh.v16i32(<16 x i32> poison, <16 x i32> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 1 for: %V2I64 = call <2 x i64> @llvm.smulh.v2i64(<2 x i64> poison, <2 x i64> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 2 for: %V4I64 = call <4 x i64> @llvm.smulh.v4i64(<4 x i64> poison, <4 x i64> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 4 for: %V8I64 = call <8 x i64> @llvm.smulh.v8i64(<8 x i64> poison, <8 x i64> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 16 for: %V2I128 = call <2 x i128> @llvm.smulh.v2i128(<2 x i128> poison, <2 x i128> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
+;
+; SVE-HIGH-LABEL: 'smulh_vec'
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 3 for: %V2I8 = call <2 x i8> @llvm.smulh.v2i8(<2 x i8> poison, <2 x i8> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 3 for: %V4I8 = call <4 x i8> @llvm.smulh.v4i8(<4 x i8> poison, <4 x i8> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 1 for: %V8I8 = call <8 x i8> @llvm.smulh.v8i8(<8 x i8> poison, <8 x i8> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 1 for: %V16I8 = call <16 x i8> @llvm.smulh.v16i8(<16 x i8> poison, <16 x i8> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 2 for: %V32I8 = call <32 x i8> @llvm.smulh.v32i8(<32 x i8> poison, <32 x i8> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 4 for: %V64I8 = call <64 x i8> @llvm.smulh.v64i8(<64 x i8> poison, <64 x i8> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 3 for: %V2I16 = call <2 x i16> @llvm.smulh.v2i16(<2 x i16> poison, <2 x i16> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 1 for: %V4I16 = call <4 x i16> @llvm.smulh.v4i16(<4 x i16> poison, <4 x i16> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 1 for: %V8I16 = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> poison, <8 x i16> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 2 for: %V16I16 = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> poison, <16 x i16> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 4 for: %V32I16 = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> poison, <32 x i16> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 1 for: %V2I32 = call <2 x i32> @llvm.smulh.v2i32(<2 x i32> poison, <2 x i32> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 1 for: %V4I32 = call <4 x i32> @llvm.smulh.v4i32(<4 x i32> poison, <4 x i32> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 2 for: %V8I32 = call <8 x i32> @llvm.smulh.v8i32(<8 x i32> poison, <8 x i32> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 4 for: %V16I32 = call <16 x i32> @llvm.smulh.v16i32(<16 x i32> poison, <16 x i32> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of RThru:4 CodeSize:1 Lat:1 SizeLat:1 for: %V2I64 = call <2 x i64> @llvm.smulh.v2i64(<2 x i64> poison, <2 x i64> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of RThru:8 CodeSize:2 Lat:2 SizeLat:2 for: %V4I64 = call <4 x i64> @llvm.smulh.v4i64(<4 x i64> poison, <4 x i64> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of RThru:16 CodeSize:4 Lat:4 SizeLat:4 for: %V8I64 = call <8 x i64> @llvm.smulh.v8i64(<8 x i64> poison, <8 x i64> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of RThru:64 CodeSize:16 Lat:16 SizeLat:16 for: %V2I128 = call <2 x i128> @llvm.smulh.v2i128(<2 x i128> poison, <2 x i128> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
 ;
   %V2I8  = call <2 x i8> @llvm.smulh.v2i8(<2 x i8> poison, <2 x i8> poison)
   %V4I8  = call <4 x i8> @llvm.smulh.v4i8(<4 x i8> poison, <4 x i8> poison)
@@ -113,46 +167,68 @@ define void @umulh_vec() {
 ; NEON-LABEL: 'umulh_vec'
 ; NEON-NEXT:  Cost Model: Found costs of 4 for: %V2I8 = call <2 x i8> @llvm.umulh.v2i8(<2 x i8> poison, <2 x i8> poison)
 ; NEON-NEXT:  Cost Model: Found costs of 4 for: %V4I8 = call <4 x i8> @llvm.umulh.v4i8(<4 x i8> poison, <4 x i8> poison)
-; NEON-NEXT:  Cost Model: Found costs of 5 for: %V8I8 = call <8 x i8> @llvm.umulh.v8i8(<8 x i8> poison, <8 x i8> poison)
-; NEON-NEXT:  Cost Model: Found costs of 1 for: %V16I8 = call <16 x i8> @llvm.umulh.v16i8(<16 x i8> poison, <16 x i8> poison)
-; NEON-NEXT:  Cost Model: Found costs of 4 for: %V32I8 = call <32 x i8> @llvm.umulh.v32i8(<32 x i8> poison, <32 x i8> poison)
-; NEON-NEXT:  Cost Model: Found costs of 8 for: %V64I8 = call <64 x i8> @llvm.umulh.v64i8(<64 x i8> poison, <64 x i8> poison)
+; NEON-NEXT:  Cost Model: Found costs of 2 for: %V8I8 = call <8 x i8> @llvm.umulh.v8i8(<8 x i8> poison, <8 x i8> poison)
+; NEON-NEXT:  Cost Model: Found costs of 3 for: %V16I8 = call <16 x i8> @llvm.umulh.v16i8(<16 x i8> poison, <16 x i8> poison)
+; NEON-NEXT:  Cost Model: Found costs of 6 for: %V32I8 = call <32 x i8> @llvm.umulh.v32i8(<32 x i8> poison, <32 x i8> poison)
+; NEON-NEXT:  Cost Model: Found costs of 12 for: %V64I8 = call <64 x i8> @llvm.umulh.v64i8(<64 x i8> poison, <64 x i8> poison)
 ; NEON-NEXT:  Cost Model: Found costs of 4 for: %V2I16 = call <2 x i16> @llvm.umulh.v2i16(<2 x i16> poison, <2 x i16> poison)
-; NEON-NEXT:  Cost Model: Found costs of 5 for: %V4I16 = call <4 x i16> @llvm.umulh.v4i16(<4 x i16> poison, <4 x i16> poison)
-; NEON-NEXT:  Cost Model: Found costs of 1 for: %V8I16 = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> poison, <8 x i16> poison)
-; NEON-NEXT:  Cost Model: Found costs of 4 for: %V16I16 = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> poison, <16 x i16> poison)
-; NEON-NEXT:  Cost Model: Found costs of 8 for: %V32I16 = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> poison, <32 x i16> poison)
-; NEON-NEXT:  Cost Model: Found costs of RThru:18 CodeSize:12 Lat:18 SizeLat:18 for: %V2I32 = call <2 x i32> @llvm.umulh.v2i32(<2 x i32> poison, <2 x i32> poison)
-; NEON-NEXT:  Cost Model: Found costs of 1 for: %V4I32 = call <4 x i32> @llvm.umulh.v4i32(<4 x i32> poison, <4 x i32> poison)
-; NEON-NEXT:  Cost Model: Found costs of 4 for: %V8I32 = call <8 x i32> @llvm.umulh.v8i32(<8 x i32> poison, <8 x i32> poison)
-; NEON-NEXT:  Cost Model: Found costs of 8 for: %V16I32 = call <16 x i32> @llvm.umulh.v16i32(<16 x i32> poison, <16 x i32> poison)
-; NEON-NEXT:  Cost Model: Found costs of RThru:25 CodeSize:21 Lat:25 SizeLat:25 for: %V2I64 = call <2 x i64> @llvm.umulh.v2i64(<2 x i64> poison, <2 x i64> poison)
-; NEON-NEXT:  Cost Model: Found costs of RThru:50 CodeSize:42 Lat:50 SizeLat:50 for: %V4I64 = call <4 x i64> @llvm.umulh.v4i64(<4 x i64> poison, <4 x i64> poison)
-; NEON-NEXT:  Cost Model: Found costs of RThru:100 CodeSize:84 Lat:100 SizeLat:100 for: %V8I64 = call <8 x i64> @llvm.umulh.v8i64(<8 x i64> poison, <8 x i64> poison)
-; NEON-NEXT:  Cost Model: Found costs of 8 for: %V2I128 = call <2 x i128> @llvm.umulh.v2i128(<2 x i128> poison, <2 x i128> poison)
+; NEON-NEXT:  Cost Model: Found costs of 2 for: %V4I16 = call <4 x i16> @llvm.umulh.v4i16(<4 x i16> poison, <4 x i16> poison)
+; NEON-NEXT:  Cost Model: Found costs of 3 for: %V8I16 = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> poison, <8 x i16> poison)
+; NEON-NEXT:  Cost Model: Found costs of 6 for: %V16I16 = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> poison, <16 x i16> poison)
+; NEON-NEXT:  Cost Model: Found costs of 12 for: %V32I16 = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> poison, <32 x i16> poison)
+; NEON-NEXT:  Cost Model: Found costs of 2 for: %V2I32 = call <2 x i32> @llvm.umulh.v2i32(<2 x i32> poison, <2 x i32> poison)
+; NEON-NEXT:  Cost Model: Found costs of 3 for: %V4I32 = call <4 x i32> @llvm.umulh.v4i32(<4 x i32> poison, <4 x i32> poison)
+; NEON-NEXT:  Cost Model: Found costs of 6 for: %V8I32 = call <8 x i32> @llvm.umulh.v8i32(<8 x i32> poison, <8 x i32> poison)
+; NEON-NEXT:  Cost Model: Found costs of 12 for: %V16I32 = call <16 x i32> @llvm.umulh.v16i32(<16 x i32> poison, <16 x i32> poison)
+; NEON-NEXT:  Cost Model: Found costs of RThru:14 CodeSize:8 Lat:14 SizeLat:14 for: %V2I64 = call <2 x i64> @llvm.umulh.v2i64(<2 x i64> poison, <2 x i64> poison)
+; NEON-NEXT:  Cost Model: Found costs of RThru:28 CodeSize:16 Lat:28 SizeLat:28 for: %V4I64 = call <4 x i64> @llvm.umulh.v4i64(<4 x i64> poison, <4 x i64> poison)
+; NEON-NEXT:  Cost Model: Found costs of RThru:56 CodeSize:32 Lat:56 SizeLat:56 for: %V8I64 = call <8 x i64> @llvm.umulh.v8i64(<8 x i64> poison, <8 x i64> poison)
+; NEON-NEXT:  Cost Model: Found costs of 16 for: %V2I128 = call <2 x i128> @llvm.umulh.v2i128(<2 x i128> poison, <2 x i128> poison)
 ; NEON-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
 ;
-; SVE-LABEL: 'umulh_vec'
-; SVE-NEXT:  Cost Model: Found costs of 2 for: %V2I8 = call <2 x i8> @llvm.umulh.v2i8(<2 x i8> poison, <2 x i8> poison)
-; SVE-NEXT:  Cost Model: Found costs of 2 for: %V4I8 = call <4 x i8> @llvm.umulh.v4i8(<4 x i8> poison, <4 x i8> poison)
-; SVE-NEXT:  Cost Model: Found costs of 2 for: %V8I8 = call <8 x i8> @llvm.umulh.v8i8(<8 x i8> poison, <8 x i8> poison)
-; SVE-NEXT:  Cost Model: Found costs of 2 for: %V16I8 = call <16 x i8> @llvm.umulh.v16i8(<16 x i8> poison, <16 x i8> poison)
-; SVE-NEXT:  Cost Model: Found costs of 4 for: %V32I8 = call <32 x i8> @llvm.umulh.v32i8(<32 x i8> poison, <32 x i8> poison)
-; SVE-NEXT:  Cost Model: Found costs of 8 for: %V64I8 = call <64 x i8> @llvm.umulh.v64i8(<64 x i8> poison, <64 x i8> poison)
-; SVE-NEXT:  Cost Model: Found costs of 2 for: %V2I16 = call <2 x i16> @llvm.umulh.v2i16(<2 x i16> poison, <2 x i16> poison)
-; SVE-NEXT:  Cost Model: Found costs of 2 for: %V4I16 = call <4 x i16> @llvm.umulh.v4i16(<4 x i16> poison, <4 x i16> poison)
-; SVE-NEXT:  Cost Model: Found costs of 2 for: %V8I16 = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> poison, <8 x i16> poison)
-; SVE-NEXT:  Cost Model: Found costs of 4 for: %V16I16 = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> poison, <16 x i16> poison)
-; SVE-NEXT:  Cost Model: Found costs of 8 for: %V32I16 = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> poison, <32 x i16> poison)
-; SVE-NEXT:  Cost Model: Found costs of 2 for: %V2I32 = call <2 x i32> @llvm.umulh.v2i32(<2 x i32> poison, <2 x i32> poison)
-; SVE-NEXT:  Cost Model: Found costs of 2 for: %V4I32 = call <4 x i32> @llvm.umulh.v4i32(<4 x i32> poison, <4 x i32> poison)
-; SVE-NEXT:  Cost Model: Found costs of 4 for: %V8I32 = call <8 x i32> @llvm.umulh.v8i32(<8 x i32> poison, <8 x i32> poison)
-; SVE-NEXT:  Cost Model: Found costs of 8 for: %V16I32 = call <16 x i32> @llvm.umulh.v16i32(<16 x i32> poison, <16 x i32> poison)
-; SVE-NEXT:  Cost Model: Found costs of 2 for: %V2I64 = call <2 x i64> @llvm.umulh.v2i64(<2 x i64> poison, <2 x i64> poison)
-; SVE-NEXT:  Cost Model: Found costs of 4 for: %V4I64 = call <4 x i64> @llvm.umulh.v4i64(<4 x i64> poison, <4 x i64> poison)
-; SVE-NEXT:  Cost Model: Found costs of 8 for: %V8I64 = call <8 x i64> @llvm.umulh.v8i64(<8 x i64> poison, <8 x i64> poison)
-; SVE-NEXT:  Cost Model: Found costs of 8 for: %V2I128 = call <2 x i128> @llvm.umulh.v2i128(<2 x i128> poison, <2 x i128> poison)
-; SVE-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
+; SVE-STD-LABEL: 'umulh_vec'
+; SVE-STD-NEXT:  Cost Model: Found costs of 3 for: %V2I8 = call <2 x i8> @llvm.umulh.v2i8(<2 x i8> poison, <2 x i8> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 3 for: %V4I8 = call <4 x i8> @llvm.umulh.v4i8(<4 x i8> poison, <4 x i8> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 1 for: %V8I8 = call <8 x i8> @llvm.umulh.v8i8(<8 x i8> poison, <8 x i8> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 1 for: %V16I8 = call <16 x i8> @llvm.umulh.v16i8(<16 x i8> poison, <16 x i8> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 2 for: %V32I8 = call <32 x i8> @llvm.umulh.v32i8(<32 x i8> poison, <32 x i8> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 4 for: %V64I8 = call <64 x i8> @llvm.umulh.v64i8(<64 x i8> poison, <64 x i8> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 3 for: %V2I16 = call <2 x i16> @llvm.umulh.v2i16(<2 x i16> poison, <2 x i16> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 1 for: %V4I16 = call <4 x i16> @llvm.umulh.v4i16(<4 x i16> poison, <4 x i16> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 1 for: %V8I16 = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> poison, <8 x i16> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 2 for: %V16I16 = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> poison, <16 x i16> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 4 for: %V32I16 = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> poison, <32 x i16> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 1 for: %V2I32 = call <2 x i32> @llvm.umulh.v2i32(<2 x i32> poison, <2 x i32> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 1 for: %V4I32 = call <4 x i32> @llvm.umulh.v4i32(<4 x i32> poison, <4 x i32> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 2 for: %V8I32 = call <8 x i32> @llvm.umulh.v8i32(<8 x i32> poison, <8 x i32> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 4 for: %V16I32 = call <16 x i32> @llvm.umulh.v16i32(<16 x i32> poison, <16 x i32> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 1 for: %V2I64 = call <2 x i64> @llvm.umulh.v2i64(<2 x i64> poison, <2 x i64> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 2 for: %V4I64 = call <4 x i64> @llvm.umulh.v4i64(<4 x i64> poison, <4 x i64> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 4 for: %V8I64 = call <8 x i64> @llvm.umulh.v8i64(<8 x i64> poison, <8 x i64> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of 16 for: %V2I128 = call <2 x i128> @llvm.umulh.v2i128(<2 x i128> poison, <2 x i128> poison)
+; SVE-STD-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
+;
+; SVE-HIGH-LABEL: 'umulh_vec'
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 3 for: %V2I8 = call <2 x i8> @llvm.umulh.v2i8(<2 x i8> poison, <2 x i8> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 3 for: %V4I8 = call <4 x i8> @llvm.umulh.v4i8(<4 x i8> poison, <4 x i8> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 1 for: %V8I8 = call <8 x i8> @llvm.umulh.v8i8(<8 x i8> poison, <8 x i8> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 1 for: %V16I8 = call <16 x i8> @llvm.umulh.v16i8(<16 x i8> poison, <16 x i8> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 2 for: %V32I8 = call <32 x i8> @llvm.umulh.v32i8(<32 x i8> poison, <32 x i8> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 4 for: %V64I8 = call <64 x i8> @llvm.umulh.v64i8(<64 x i8> poison, <64 x i8> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 3 for: %V2I16 = call <2 x i16> @llvm.umulh.v2i16(<2 x i16> poison, <2 x i16> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 1 for: %V4I16 = call <4 x i16> @llvm.umulh.v4i16(<4 x i16> poison, <4 x i16> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 1 for: %V8I16 = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> poison, <8 x i16> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 2 for: %V16I16 = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> poison, <16 x i16> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 4 for: %V32I16 = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> poison, <32 x i16> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 1 for: %V2I32 = call <2 x i32> @llvm.umulh.v2i32(<2 x i32> poison, <2 x i32> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 1 for: %V4I32 = call <4 x i32> @llvm.umulh.v4i32(<4 x i32> poison, <4 x i32> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 2 for: %V8I32 = call <8 x i32> @llvm.umulh.v8i32(<8 x i32> poison, <8 x i32> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of 4 for: %V16I32 = call <16 x i32> @llvm.umulh.v16i32(<16 x i32> poison, <16 x i32> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of RThru:4 CodeSize:1 Lat:1 SizeLat:1 for: %V2I64 = call <2 x i64> @llvm.umulh.v2i64(<2 x i64> poison, <2 x i64> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of RThru:8 CodeSize:2 Lat:2 SizeLat:2 for: %V4I64 = call <4 x i64> @llvm.umulh.v4i64(<4 x i64> poison, <4 x i64> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of RThru:16 CodeSize:4 Lat:4 SizeLat:4 for: %V8I64 = call <8 x i64> @llvm.umulh.v8i64(<8 x i64> poison, <8 x i64> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of RThru:64 CodeSize:16 Lat:16 SizeLat:16 for: %V2I128 = call <2 x i128> @llvm.umulh.v2i128(<2 x i128> poison, <2 x i128> poison)
+; SVE-HIGH-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
 ;
   %V2I8  = call <2 x i8> @llvm.umulh.v2i8(<2 x i8> poison, <2 x i8> poison)
   %V4I8  = call <4 x i8> @llvm.umulh.v4i8(<4 x i8> poison, <4 x i8> poison)
@@ -181,5 +257,5 @@ define void @umulh_vec() {
   ret void
 }
 ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; SVE-HIGH: {{.*}}
-; SVE-STD: {{.*}}
+; CHECK: {{.*}}
+; SVE: {{.*}}
diff --git a/llvm/test/Analysis/CostModel/AArch64/sve-mulh.ll b/llvm/test/Analysis/CostModel/AArch64/sve-mulh.ll
index 62d355bf1f4c48..28ea6d3b82beee 100644
--- a/llvm/test/Analysis/CostModel/AArch64/sve-mulh.ll
+++ b/llvm/test/Analysis/CostModel/AArch64/sve-mulh.ll
@@ -4,10 +4,10 @@
 
 define void @smulh_scalable() {
 ; CHECK-LABEL: 'smulh_scalable'
-; CHECK-NEXT:  Cost Model: Found costs of 2 for: %nxv16i8 = call <vscale x 16 x i8> @llvm.smulh.nxv16i8(<vscale x 16 x i8> poison, <vscale x 16 x i8> poison)
-; CHECK-NEXT:  Cost Model: Found costs of 2 for: %nxv8i16 = call <vscale x 8 x i16> @llvm.smulh.nxv8i16(<vscale x 8 x i16> poison, <vscale x 8 x i16> poison)
-; CHECK-NEXT:  Cost Model: Found costs of 2 for: %nxv4i32 = call <vscale x 4 x i32> @llvm.smulh.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> poison)
-; CHECK-NEXT:  Cost Model: Found costs of 2 for: %nxv2i64 = call <vscale x 2 x i64> @llvm.smulh.nxv2i64(<vscale x 2 x i64> poison, <vscale x 2 x i64> poison)
+; CHECK-NEXT:  Cost Model: Found costs of 1 for: %nxv16i8 = call <vscale x 16 x i8> @llvm.smulh.nxv16i8(<vscale x 16 x i8> poison, <vscale x 16 x i8> poison)
+; CHECK-NEXT:  Cost Model: Found costs of 1 for: %nxv8i16 = call <vscale x 8 x i16> @llvm.smulh.nxv8i16(<vscale x 8 x i16> poison, <vscale x 8 x i16> poison)
+; CHECK-NEXT:  Cost Model: Found costs of 1 for: %nxv4i32 = call <vscale x 4 x i32> @llvm.smulh.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> poison)
+; CHECK-NEXT:  Cost Model: Found costs of 1 for: %nxv2i64 = call <vscale x 2 x i64> @llvm.smulh.nxv2i64(<vscale x 2 x i64> poison, <vscale x 2 x i64> poison)
 ; CHECK-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
 ;
   %nxv16i8 = call <vscale x 16 x i8> @llvm.smulh(<vscale x 16 x i8> poison, <vscale x 16 x i8> poison)
@@ -19,10 +19,10 @@ define void @smulh_scalable() {
 
 define void @umulh_scalable() {
 ; CHECK-LABEL: 'umulh_scalable'
-; CHECK-NEXT:  Cost Model: Found costs of 2 for: %nxv16i8 = call <vscale x 16 x i8> @llvm.umulh.nxv16i8(<vscale x 16 x i8> poison, <vscale x 16 x i8> poison)
-; CHECK-NEXT:  Cost Model: Found costs of 2 for: %nxv8i16 = call <vscale x 8 x i16> @llvm.umulh.nxv8i16(<vscale x 8 x i16> poison, <vscale x 8 x i16> poison)
-; CHECK-NEXT:  Cost Model: Found costs of 2 for: %nxv4i32 = call <vscale x 4 x i32> @llvm.umulh.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> poison)
-; CHECK-NEXT:  Cost Model: Found costs of 2 for: %nxv2i64 = call <vscale x 2 x i64> @llvm.umulh.nxv2i64(<vscale x 2 x i64> poison, <vscale x 2 x i64> poison)
+; CHECK-NEXT:  Cost Model: Found costs of 1 for: %nxv16i8 = call <vscale x 16 x i8> @llvm.umulh.nxv16i8(<vscale x 16 x i8> poison, <vscale x 16 x i8> poison)
+; CHECK-NEXT:  Cost Model: Found costs of 1 for: %nxv8i16 = call <vscale x 8 x i16> @llvm.umulh.nxv8i16(<vscale x 8 x i16> poison, <vscale x 8 x i16> poison)
+; CHECK-NEXT:  Cost Model: Found costs of 1 for: %nxv4i32 = call <vscale x 4 x i32> @llvm.umulh.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> poison)
+; CHECK-NEXT:  Cost Model: Found costs of 1 for: %nxv2i64 = call <vscale x 2 x i64> @llvm.umulh.nxv2i64(<vscale x 2 x i64> poison, <vscale x 2 x i64> poison)
 ; CHECK-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
 ;
   %nxv16i8 = call <vscale x 16 x i8> @llvm.umulh(<vscale x 16 x i8> poison, <vscale x 16 x i8> poison)



More information about the llvm-commits mailing list