[llvm] [AArch64][CostModel] Add cost model for pdep/pext instructions (PR #207657)

Yashwant Singh via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 20 20:54:11 PDT 2026


https://github.com/yashssh updated https://github.com/llvm/llvm-project/pull/207657

>From bfa286962e13c4a46894dcba3a4e6f10c090caff Mon Sep 17 00:00:00 2001
From: Yashwant Singh <yashwants at nvidia.com>
Date: Sun, 5 Jul 2026 22:41:15 -0700
Subject: [PATCH 1/3] [AArch64][CostModel] Add cost model for pdep/pext
 instructions

---
 .../Target/AArch64/AArch64ISelLowering.cpp    |  5 +-
 llvm/lib/Target/AArch64/AArch64Subtarget.h    |  8 ++++
 .../AArch64/AArch64TargetTransformInfo.cpp    | 23 +++++++++
 .../Analysis/CostModel/AArch64/pdep-pext.ll   | 47 +++++++++++++++++++
 4 files changed, 79 insertions(+), 4 deletions(-)
 create mode 100644 llvm/test/Analysis/CostModel/AArch64/pdep-pext.ll

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 613fdd2813f63..d0b9130385962 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -2164,10 +2164,7 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
     }
 
     // Map generic PEXT/PDEP to SVE2 bitperm BEXT/BDEP instructions.
-    if (Subtarget->hasSVEBitPerm() &&
-        (Subtarget->isSVEAvailable() ||
-         (Subtarget->isSVEorStreamingSVEAvailable() &&
-          Subtarget->hasSSVE_BitPerm()))) {
+    if (Subtarget->isSVEBitPermAvailable()) {
       for (auto VT : {MVT::nxv16i8, MVT::nxv8i16, MVT::nxv4i32, MVT::nxv2i64}) {
         setOperationAction({ISD::PEXT, ISD::PDEP}, VT, Custom);
       }
diff --git a/llvm/lib/Target/AArch64/AArch64Subtarget.h b/llvm/lib/Target/AArch64/AArch64Subtarget.h
index b8303224a8976..9404ec2643a54 100644
--- a/llvm/lib/Target/AArch64/AArch64Subtarget.h
+++ b/llvm/lib/Target/AArch64/AArch64Subtarget.h
@@ -237,6 +237,14 @@ class AArch64Subtarget final : public AArch64GenSubtargetInfo {
     return isSVEAvailable() || (isSVEorStreamingSVEAvailable() && hasSME2());
   }
 
+  /// Returns true if SVE bit-permute instructions (bext/bdep/bgrp) can be
+  /// emitted.
+  bool isSVEBitPermAvailable() const {
+    return hasSVEBitPerm() &&
+           (isSVEAvailable() ||
+            (isSVEorStreamingSVEAvailable() && hasSSVE_BitPerm()));
+  }
+
   unsigned getMinVectorRegisterBitWidth() const {
     // Don't assume any minimum vector size when PSTATE.SM may not be 0, because
     // we don't yet support streaming-compatible codegen support that we trust
diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
index 9d448b4a8681a..109a247f16d25 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
@@ -863,6 +863,29 @@ AArch64TTIImpl::getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
     }
     break;
   }
+  case Intrinsic::pdep:
+  case Intrinsic::pext: {
+    unsigned BW = RetTy->getScalarSizeInBits();
+    if (ST->isSVEBitPermAvailable() && BW <= 64) {
+      Type *VecTy = VectorType::get(RetTy, 64 / BW, false);
+      InstructionCost Cost =
+          getVectorInstrCost(Instruction::InsertElement, VecTy, CostKind, 0,
+                             nullptr, nullptr) +
+          getVectorInstrCost(Instruction::InsertElement, VecTy, CostKind, 0,
+                             nullptr, nullptr) +
+          1 +
+          getVectorInstrCost(Instruction::ExtractElement, VecTy, CostKind, 0,
+                             nullptr, nullptr);
+      return Cost;
+    }
+    // Without bit-permute, pdep/pext expand to the Hacker's Delight scalar
+    // sequence: O(log2(BW)) parallel-prefix stages, each a CLMUL-by-all-ones
+    // (~log2(BW) shift-xors) plus a handful of scalar ALU ops. That is
+    // O(log2(BW)^2) work; cost ~ LogBW * (LogBW + 7) matches the emitted
+    // sequence (~48/61/79 insns for i16/i32/i64).
+    unsigned LogBW = Log2_32_Ceil(BW);
+    return getTypeLegalizationCost(RetTy).first * LogBW * (LogBW + 7);
+  }
   case Intrinsic::ctpop: {
     if (!ST->hasNEON()) {
       // 32-bit or 64-bit ctpop without NEON is 12 instructions.
diff --git a/llvm/test/Analysis/CostModel/AArch64/pdep-pext.ll b/llvm/test/Analysis/CostModel/AArch64/pdep-pext.ll
new file mode 100644
index 0000000000000..1960a2d1514b7
--- /dev/null
+++ b/llvm/test/Analysis/CostModel/AArch64/pdep-pext.ll
@@ -0,0 +1,47 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
+; RUN: opt < %s -passes="print<cost-model>" 2>&1 -disable-output -mtriple=aarch64-- | FileCheck %s --check-prefixes=CHECK-NO-BITPERM
+; RUN: opt < %s -passes="print<cost-model>" 2>&1 -disable-output -mtriple=aarch64-- -mattr=+sve2-bitperm | FileCheck %s --check-prefixes=CHECK-BITPERM
+
+define void @pdep() {
+; CHECK-NO-BITPERM-LABEL: 'pdep'
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 30 for instruction: %i8 = call i8 @llvm.pdep.i8(i8 poison, i8 poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 44 for instruction: %i16 = call i16 @llvm.pdep.i16(i16 poison, i16 poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 60 for instruction: %i32 = call i32 @llvm.pdep.i32(i32 poison, i32 poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 78 for instruction: %i64 = call i64 @llvm.pdep.i64(i64 poison, i64 poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret void
+;
+; CHECK-BITPERM-LABEL: 'pdep'
+; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %i8 = call i8 @llvm.pdep.i8(i8 poison, i8 poison)
+; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %i16 = call i16 @llvm.pdep.i16(i16 poison, i16 poison)
+; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %i32 = call i32 @llvm.pdep.i32(i32 poison, i32 poison)
+; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %i64 = call i64 @llvm.pdep.i64(i64 poison, i64 poison)
+; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret void
+;
+  %i8 = call i8 @llvm.pdep.i8(i8 poison, i8 poison)
+  %i16 = call i16 @llvm.pdep.i16(i16 poison, i16 poison)
+  %i32 = call i32 @llvm.pdep.i32(i32 poison, i32 poison)
+  %i64 = call i64 @llvm.pdep.i64(i64 poison, i64 poison)
+  ret void
+}
+
+define void @pext() {
+; CHECK-NO-BITPERM-LABEL: 'pext'
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 30 for instruction: %i8 = call i8 @llvm.pext.i8(i8 poison, i8 poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 44 for instruction: %i16 = call i16 @llvm.pext.i16(i16 poison, i16 poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 60 for instruction: %i32 = call i32 @llvm.pext.i32(i32 poison, i32 poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 78 for instruction: %i64 = call i64 @llvm.pext.i64(i64 poison, i64 poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret void
+;
+; CHECK-BITPERM-LABEL: 'pext'
+; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %i8 = call i8 @llvm.pext.i8(i8 poison, i8 poison)
+; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %i16 = call i16 @llvm.pext.i16(i16 poison, i16 poison)
+; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %i32 = call i32 @llvm.pext.i32(i32 poison, i32 poison)
+; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %i64 = call i64 @llvm.pext.i64(i64 poison, i64 poison)
+; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret void
+;
+  %i8 = call i8 @llvm.pext.i8(i8 poison, i8 poison)
+  %i16 = call i16 @llvm.pext.i16(i16 poison, i16 poison)
+  %i32 = call i32 @llvm.pext.i32(i32 poison, i32 poison)
+  %i64 = call i64 @llvm.pext.i64(i64 poison, i64 poison)
+  ret void
+}

>From 9479b0686891582ae6579e515212146f0289cc25 Mon Sep 17 00:00:00 2001
From: Yashwant Singh <yashwants at nvidia.com>
Date: Wed, 8 Jul 2026 00:10:20 -0700
Subject: [PATCH 2/3] Address review comments

---
 llvm/include/llvm/CodeGen/BasicTTIImpl.h         |  6 ++++++
 .../AArch64/AArch64TargetTransformInfo.cpp       | 10 ++--------
 .../test/Analysis/CostModel/AArch64/pdep-pext.ll | 16 ++++++++--------
 3 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
index 3240b9fd861e4..88aa7f4b61c4f 100644
--- a/llvm/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
@@ -2757,6 +2757,12 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
     case Intrinsic::bitreverse:
       ISD = ISD::BITREVERSE;
       break;
+    case Intrinsic::pdep:
+    case Intrinsic::pext:
+      ISD = IID == Intrinsic::pdep ? ISD::PDEP : ISD::PEXT;
+      // When not legal/custom, pdep/pext expand to a long inline sequence
+      SingleCallCost = 20;
+      break;
     case Intrinsic::ucmp:
       ISD = ISD::UCMP;
       break;
diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
index 109a247f16d25..a0cded5263022 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
@@ -866,7 +866,7 @@ AArch64TTIImpl::getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
   case Intrinsic::pdep:
   case Intrinsic::pext: {
     unsigned BW = RetTy->getScalarSizeInBits();
-    if (ST->isSVEBitPermAvailable() && BW <= 64) {
+    if (!RetTy->isVectorTy() && ST->isSVEBitPermAvailable() && BW <= 64) {
       Type *VecTy = VectorType::get(RetTy, 64 / BW, false);
       InstructionCost Cost =
           getVectorInstrCost(Instruction::InsertElement, VecTy, CostKind, 0,
@@ -878,13 +878,7 @@ AArch64TTIImpl::getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
                              nullptr, nullptr);
       return Cost;
     }
-    // Without bit-permute, pdep/pext expand to the Hacker's Delight scalar
-    // sequence: O(log2(BW)) parallel-prefix stages, each a CLMUL-by-all-ones
-    // (~log2(BW) shift-xors) plus a handful of scalar ALU ops. That is
-    // O(log2(BW)^2) work; cost ~ LogBW * (LogBW + 7) matches the emitted
-    // sequence (~48/61/79 insns for i16/i32/i64).
-    unsigned LogBW = Log2_32_Ceil(BW);
-    return getTypeLegalizationCost(RetTy).first * LogBW * (LogBW + 7);
+    break;
   }
   case Intrinsic::ctpop: {
     if (!ST->hasNEON()) {
diff --git a/llvm/test/Analysis/CostModel/AArch64/pdep-pext.ll b/llvm/test/Analysis/CostModel/AArch64/pdep-pext.ll
index 1960a2d1514b7..90d38dfc698d7 100644
--- a/llvm/test/Analysis/CostModel/AArch64/pdep-pext.ll
+++ b/llvm/test/Analysis/CostModel/AArch64/pdep-pext.ll
@@ -4,10 +4,10 @@
 
 define void @pdep() {
 ; CHECK-NO-BITPERM-LABEL: 'pdep'
-; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 30 for instruction: %i8 = call i8 @llvm.pdep.i8(i8 poison, i8 poison)
-; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 44 for instruction: %i16 = call i16 @llvm.pdep.i16(i16 poison, i16 poison)
-; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 60 for instruction: %i32 = call i32 @llvm.pdep.i32(i32 poison, i32 poison)
-; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 78 for instruction: %i64 = call i64 @llvm.pdep.i64(i64 poison, i64 poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %i8 = call i8 @llvm.pdep.i8(i8 poison, i8 poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %i16 = call i16 @llvm.pdep.i16(i16 poison, i16 poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %i32 = call i32 @llvm.pdep.i32(i32 poison, i32 poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %i64 = call i64 @llvm.pdep.i64(i64 poison, i64 poison)
 ; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret void
 ;
 ; CHECK-BITPERM-LABEL: 'pdep'
@@ -26,10 +26,10 @@ define void @pdep() {
 
 define void @pext() {
 ; CHECK-NO-BITPERM-LABEL: 'pext'
-; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 30 for instruction: %i8 = call i8 @llvm.pext.i8(i8 poison, i8 poison)
-; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 44 for instruction: %i16 = call i16 @llvm.pext.i16(i16 poison, i16 poison)
-; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 60 for instruction: %i32 = call i32 @llvm.pext.i32(i32 poison, i32 poison)
-; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 78 for instruction: %i64 = call i64 @llvm.pext.i64(i64 poison, i64 poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %i8 = call i8 @llvm.pext.i8(i8 poison, i8 poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %i16 = call i16 @llvm.pext.i16(i16 poison, i16 poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %i32 = call i32 @llvm.pext.i32(i32 poison, i32 poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %i64 = call i64 @llvm.pext.i64(i64 poison, i64 poison)
 ; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret void
 ;
 ; CHECK-BITPERM-LABEL: 'pext'

>From d3b0cd0af31763be23e303050f21ff4046414f1b Mon Sep 17 00:00:00 2001
From: Yashwant Singh <yashwants at nvidia.com>
Date: Mon, 20 Jul 2026 02:12:27 -0700
Subject: [PATCH 3/3] Address review comments(generic cost on clmul expansion)

---
 llvm/include/llvm/CodeGen/BasicTTIImpl.h      | 30 +++++++++--
 .../Analysis/CostModel/AArch64/pdep-pext.ll   | 52 ++++++++++++++++---
 .../CostModel/X86/intrinsic-cost-kinds.ll     | 32 ++++++------
 3 files changed, 87 insertions(+), 27 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
index 88aa7f4b61c4f..1d1eacbef4701 100644
--- a/llvm/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
@@ -2758,10 +2758,10 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
       ISD = ISD::BITREVERSE;
       break;
     case Intrinsic::pdep:
+      ISD = ISD::PDEP;
+      break;
     case Intrinsic::pext:
-      ISD = IID == Intrinsic::pdep ? ISD::PDEP : ISD::PEXT;
-      // When not legal/custom, pdep/pext expand to a long inline sequence
-      SingleCallCost = 20;
+      ISD = ISD::PEXT;
       break;
     case Intrinsic::ucmp:
       ISD = ISD::UCMP;
@@ -3158,6 +3158,30 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
       InstructionCost PerBitCost = std::min(PerBitCostMul, PerBitCostBittest);
       return BW * PerBitCost;
     }
+    case Intrinsic::pdep:
+    case Intrinsic::pext: {
+      if (RetTy->isVectorTy())
+        break;
+      // Based on Hacker's Delight ยง7-5: Expand, or Generalized Insert.
+      // Below cost is accurate for pext, pdep will be similar.
+      unsigned BW = RetTy->getScalarSizeInBits();
+      InstructionCost AndCost =
+          thisT()->getArithmeticInstrCost(Instruction::And, RetTy, CostKind);
+      InstructionCost ShiftCost =
+          thisT()->getArithmeticInstrCost(Instruction::Shl, RetTy, CostKind);
+      InstructionCost OrCost =
+          thisT()->getArithmeticInstrCost(Instruction::Or, RetTy, CostKind);
+      InstructionCost XorCost =
+          thisT()->getArithmeticInstrCost(Instruction::Xor, RetTy, CostKind);
+      IntrinsicCostAttributes ClmulAttrs(Intrinsic::clmul, RetTy, {RetTy, RetTy});
+      InstructionCost MulCost =
+          thisT()->getIntrinsicInstrCost(ClmulAttrs, CostKind);
+
+      int Iterations = Log2_32_Ceil(BW);
+      InstructionCost Cost = AndCost + ShiftCost;  // Prefix cost
+      Cost += Iterations * (MulCost + 2*AndCost + 2*ShiftCost + OrCost + 2*XorCost);
+      return Cost;
+    }
     default:
       break;
     }
diff --git a/llvm/test/Analysis/CostModel/AArch64/pdep-pext.ll b/llvm/test/Analysis/CostModel/AArch64/pdep-pext.ll
index 90d38dfc698d7..fd7455bd19f73 100644
--- a/llvm/test/Analysis/CostModel/AArch64/pdep-pext.ll
+++ b/llvm/test/Analysis/CostModel/AArch64/pdep-pext.ll
@@ -4,10 +4,16 @@
 
 define void @pdep() {
 ; CHECK-NO-BITPERM-LABEL: 'pdep'
-; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %i8 = call i8 @llvm.pdep.i8(i8 poison, i8 poison)
-; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %i16 = call i16 @llvm.pdep.i16(i16 poison, i16 poison)
-; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %i32 = call i32 @llvm.pdep.i32(i32 poison, i32 poison)
-; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %i64 = call i64 @llvm.pdep.i64(i64 poison, i64 poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 44 for instruction: %i8 = call i8 @llvm.pdep.i8(i8 poison, i8 poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 222 for instruction: %i16 = call i16 @llvm.pdep.i16(i16 poison, i16 poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 252 for instruction: %i32 = call i32 @llvm.pdep.i32(i32 poison, i32 poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 302 for instruction: %i64 = call i64 @llvm.pdep.i64(i64 poison, i64 poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 1792 for instruction: %v8i16 = call <8 x i16> @llvm.pdep.v8i16(<8 x i16> poison, <8 x i16> poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 1016 for instruction: %v4i32 = call <4 x i32> @llvm.pdep.v4i32(<4 x i32> poison, <4 x i32> poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 608 for instruction: %v2i64 = call <2 x i64> @llvm.pdep.v2i64(<2 x i64> poison, <2 x i64> poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Invalid cost for instruction: %nxv8i16 = call <vscale x 8 x i16> @llvm.pdep.nxv8i16(<vscale x 8 x i16> poison, <vscale x 8 x i16> poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Invalid cost for instruction: %nxv4i32 = call <vscale x 4 x i32> @llvm.pdep.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Invalid cost for instruction: %nxv2i64 = call <vscale x 2 x i64> @llvm.pdep.nxv2i64(<vscale x 2 x i64> poison, <vscale x 2 x i64> poison)
 ; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret void
 ;
 ; CHECK-BITPERM-LABEL: 'pdep'
@@ -15,21 +21,39 @@ define void @pdep() {
 ; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %i16 = call i16 @llvm.pdep.i16(i16 poison, i16 poison)
 ; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %i32 = call i32 @llvm.pdep.i32(i32 poison, i32 poison)
 ; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %i64 = call i64 @llvm.pdep.i64(i64 poison, i64 poison)
+; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 72 for instruction: %v8i16 = call <8 x i16> @llvm.pdep.v8i16(<8 x i16> poison, <8 x i16> poison)
+; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 36 for instruction: %v4i32 = call <4 x i32> @llvm.pdep.v4i32(<4 x i32> poison, <4 x i32> poison)
+; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 18 for instruction: %v2i64 = call <2 x i64> @llvm.pdep.v2i64(<2 x i64> poison, <2 x i64> poison)
+; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %nxv8i16 = call <vscale x 8 x i16> @llvm.pdep.nxv8i16(<vscale x 8 x i16> poison, <vscale x 8 x i16> poison)
+; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %nxv4i32 = call <vscale x 4 x i32> @llvm.pdep.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> poison)
+; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %nxv2i64 = call <vscale x 2 x i64> @llvm.pdep.nxv2i64(<vscale x 2 x i64> poison, <vscale x 2 x i64> poison)
 ; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret void
 ;
   %i8 = call i8 @llvm.pdep.i8(i8 poison, i8 poison)
   %i16 = call i16 @llvm.pdep.i16(i16 poison, i16 poison)
   %i32 = call i32 @llvm.pdep.i32(i32 poison, i32 poison)
   %i64 = call i64 @llvm.pdep.i64(i64 poison, i64 poison)
+  %v8i16 = call <8 x i16> @llvm.pdep.v8i16(<8 x i16> poison, <8 x i16> poison)
+  %v4i32 = call <4 x i32> @llvm.pdep.v4i32(<4 x i32> poison, <4 x i32> poison)
+  %v2i64 = call <2 x i64> @llvm.pdep.v2i64(<2 x i64> poison, <2 x i64> poison)
+  %nxv8i16 = call <vscale x 8 x i16> @llvm.pdep.nxv8i16(<vscale x 8 x i16> poison, <vscale x 8 x i16> poison)
+  %nxv4i32 = call <vscale x 4 x i32> @llvm.pdep.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> poison)
+  %nxv2i64 = call <vscale x 2 x i64> @llvm.pdep.nxv2i64(<vscale x 2 x i64> poison, <vscale x 2 x i64> poison)
   ret void
 }
 
 define void @pext() {
 ; CHECK-NO-BITPERM-LABEL: 'pext'
-; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %i8 = call i8 @llvm.pext.i8(i8 poison, i8 poison)
-; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %i16 = call i16 @llvm.pext.i16(i16 poison, i16 poison)
-; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %i32 = call i32 @llvm.pext.i32(i32 poison, i32 poison)
-; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %i64 = call i64 @llvm.pext.i64(i64 poison, i64 poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 44 for instruction: %i8 = call i8 @llvm.pext.i8(i8 poison, i8 poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 222 for instruction: %i16 = call i16 @llvm.pext.i16(i16 poison, i16 poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 252 for instruction: %i32 = call i32 @llvm.pext.i32(i32 poison, i32 poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 302 for instruction: %i64 = call i64 @llvm.pext.i64(i64 poison, i64 poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 1792 for instruction: %v8i16 = call <8 x i16> @llvm.pext.v8i16(<8 x i16> poison, <8 x i16> poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 1016 for instruction: %v4i32 = call <4 x i32> @llvm.pext.v4i32(<4 x i32> poison, <4 x i32> poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 608 for instruction: %v2i64 = call <2 x i64> @llvm.pext.v2i64(<2 x i64> poison, <2 x i64> poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Invalid cost for instruction: %nxv8i16 = call <vscale x 8 x i16> @llvm.pext.nxv8i16(<vscale x 8 x i16> poison, <vscale x 8 x i16> poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Invalid cost for instruction: %nxv4i32 = call <vscale x 4 x i32> @llvm.pext.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> poison)
+; CHECK-NO-BITPERM-NEXT:  Cost Model: Invalid cost for instruction: %nxv2i64 = call <vscale x 2 x i64> @llvm.pext.nxv2i64(<vscale x 2 x i64> poison, <vscale x 2 x i64> poison)
 ; CHECK-NO-BITPERM-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret void
 ;
 ; CHECK-BITPERM-LABEL: 'pext'
@@ -37,11 +61,23 @@ define void @pext() {
 ; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %i16 = call i16 @llvm.pext.i16(i16 poison, i16 poison)
 ; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %i32 = call i32 @llvm.pext.i32(i32 poison, i32 poison)
 ; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %i64 = call i64 @llvm.pext.i64(i64 poison, i64 poison)
+; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 72 for instruction: %v8i16 = call <8 x i16> @llvm.pext.v8i16(<8 x i16> poison, <8 x i16> poison)
+; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 36 for instruction: %v4i32 = call <4 x i32> @llvm.pext.v4i32(<4 x i32> poison, <4 x i32> poison)
+; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 18 for instruction: %v2i64 = call <2 x i64> @llvm.pext.v2i64(<2 x i64> poison, <2 x i64> poison)
+; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %nxv8i16 = call <vscale x 8 x i16> @llvm.pext.nxv8i16(<vscale x 8 x i16> poison, <vscale x 8 x i16> poison)
+; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %nxv4i32 = call <vscale x 4 x i32> @llvm.pext.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> poison)
+; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %nxv2i64 = call <vscale x 2 x i64> @llvm.pext.nxv2i64(<vscale x 2 x i64> poison, <vscale x 2 x i64> poison)
 ; CHECK-BITPERM-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret void
 ;
   %i8 = call i8 @llvm.pext.i8(i8 poison, i8 poison)
   %i16 = call i16 @llvm.pext.i16(i16 poison, i16 poison)
   %i32 = call i32 @llvm.pext.i32(i32 poison, i32 poison)
   %i64 = call i64 @llvm.pext.i64(i64 poison, i64 poison)
+  %v8i16 = call <8 x i16> @llvm.pext.v8i16(<8 x i16> poison, <8 x i16> poison)
+  %v4i32 = call <4 x i32> @llvm.pext.v4i32(<4 x i32> poison, <4 x i32> poison)
+  %v2i64 = call <2 x i64> @llvm.pext.v2i64(<2 x i64> poison, <2 x i64> poison)
+  %nxv8i16 = call <vscale x 8 x i16> @llvm.pext.nxv8i16(<vscale x 8 x i16> poison, <vscale x 8 x i16> poison)
+  %nxv4i32 = call <vscale x 4 x i32> @llvm.pext.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> poison)
+  %nxv2i64 = call <vscale x 2 x i64> @llvm.pext.nxv2i64(<vscale x 2 x i64> poison, <vscale x 2 x i64> poison)
   ret void
 }
diff --git a/llvm/test/Analysis/CostModel/X86/intrinsic-cost-kinds.ll b/llvm/test/Analysis/CostModel/X86/intrinsic-cost-kinds.ll
index 45e19b93e41cf..30094e78a21d3 100644
--- a/llvm/test/Analysis/CostModel/X86/intrinsic-cost-kinds.ll
+++ b/llvm/test/Analysis/CostModel/X86/intrinsic-cost-kinds.ll
@@ -310,23 +310,23 @@ define void @fshl(i32 %a, i32 %b, i32 %c, <16 x i32> %va, <16 x i32> %vb, <16 x
 
 define void @pdep(i32 %a, i32 %b, <16 x i32> %va, <16 x i32> %vb) {
 ; THRU-LABEL: 'pdep'
-; THRU-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: %s = call i32 @llvm.pdep.i32(i32 %a, i32 %b)
-; THRU-NEXT:  Cost Model: Found an estimated cost of 100 for instruction: %v = call <16 x i32> @llvm.pdep.v16i32(<16 x i32> %va, <16 x i32> %vb)
+; THRU-NEXT:  Cost Model: Found an estimated cost of 252 for instruction: %s = call i32 @llvm.pdep.i32(i32 %a, i32 %b)
+; THRU-NEXT:  Cost Model: Found an estimated cost of 4116 for instruction: %v = call <16 x i32> @llvm.pdep.v16i32(<16 x i32> %va, <16 x i32> %vb)
 ; THRU-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret void
 ;
 ; LATE-LABEL: 'pdep'
-; LATE-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: %s = call i32 @llvm.pdep.i32(i32 %a, i32 %b)
-; LATE-NEXT:  Cost Model: Found an estimated cost of 100 for instruction: %v = call <16 x i32> @llvm.pdep.v16i32(<16 x i32> %va, <16 x i32> %vb)
+; LATE-NEXT:  Cost Model: Found an estimated cost of 492 for instruction: %s = call i32 @llvm.pdep.i32(i32 %a, i32 %b)
+; LATE-NEXT:  Cost Model: Found an estimated cost of 7956 for instruction: %v = call <16 x i32> @llvm.pdep.v16i32(<16 x i32> %va, <16 x i32> %vb)
 ; LATE-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
 ;
 ; SIZE-LABEL: 'pdep'
-; SIZE-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: %s = call i32 @llvm.pdep.i32(i32 %a, i32 %b)
-; SIZE-NEXT:  Cost Model: Found an estimated cost of 100 for instruction: %v = call <16 x i32> @llvm.pdep.v16i32(<16 x i32> %va, <16 x i32> %vb)
+; SIZE-NEXT:  Cost Model: Found an estimated cost of 252 for instruction: %s = call i32 @llvm.pdep.i32(i32 %a, i32 %b)
+; SIZE-NEXT:  Cost Model: Found an estimated cost of 4116 for instruction: %v = call <16 x i32> @llvm.pdep.v16i32(<16 x i32> %va, <16 x i32> %vb)
 ; SIZE-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
 ;
 ; SIZE_LATE-LABEL: 'pdep'
-; SIZE_LATE-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: %s = call i32 @llvm.pdep.i32(i32 %a, i32 %b)
-; SIZE_LATE-NEXT:  Cost Model: Found an estimated cost of 100 for instruction: %v = call <16 x i32> @llvm.pdep.v16i32(<16 x i32> %va, <16 x i32> %vb)
+; SIZE_LATE-NEXT:  Cost Model: Found an estimated cost of 252 for instruction: %s = call i32 @llvm.pdep.i32(i32 %a, i32 %b)
+; SIZE_LATE-NEXT:  Cost Model: Found an estimated cost of 4116 for instruction: %v = call <16 x i32> @llvm.pdep.v16i32(<16 x i32> %va, <16 x i32> %vb)
 ; SIZE_LATE-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
 ;
   %s = call i32 @llvm.pdep.i32(i32 %a, i32 %b)
@@ -336,23 +336,23 @@ define void @pdep(i32 %a, i32 %b, <16 x i32> %va, <16 x i32> %vb) {
 
 define void @pext(i32 %a, i32 %b, <16 x i32> %va, <16 x i32> %vb) {
 ; THRU-LABEL: 'pext'
-; THRU-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: %s = call i32 @llvm.pext.i32(i32 %a, i32 %b)
-; THRU-NEXT:  Cost Model: Found an estimated cost of 100 for instruction: %v = call <16 x i32> @llvm.pext.v16i32(<16 x i32> %va, <16 x i32> %vb)
+; THRU-NEXT:  Cost Model: Found an estimated cost of 252 for instruction: %s = call i32 @llvm.pext.i32(i32 %a, i32 %b)
+; THRU-NEXT:  Cost Model: Found an estimated cost of 4116 for instruction: %v = call <16 x i32> @llvm.pext.v16i32(<16 x i32> %va, <16 x i32> %vb)
 ; THRU-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret void
 ;
 ; LATE-LABEL: 'pext'
-; LATE-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: %s = call i32 @llvm.pext.i32(i32 %a, i32 %b)
-; LATE-NEXT:  Cost Model: Found an estimated cost of 100 for instruction: %v = call <16 x i32> @llvm.pext.v16i32(<16 x i32> %va, <16 x i32> %vb)
+; LATE-NEXT:  Cost Model: Found an estimated cost of 492 for instruction: %s = call i32 @llvm.pext.i32(i32 %a, i32 %b)
+; LATE-NEXT:  Cost Model: Found an estimated cost of 7956 for instruction: %v = call <16 x i32> @llvm.pext.v16i32(<16 x i32> %va, <16 x i32> %vb)
 ; LATE-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
 ;
 ; SIZE-LABEL: 'pext'
-; SIZE-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: %s = call i32 @llvm.pext.i32(i32 %a, i32 %b)
-; SIZE-NEXT:  Cost Model: Found an estimated cost of 100 for instruction: %v = call <16 x i32> @llvm.pext.v16i32(<16 x i32> %va, <16 x i32> %vb)
+; SIZE-NEXT:  Cost Model: Found an estimated cost of 252 for instruction: %s = call i32 @llvm.pext.i32(i32 %a, i32 %b)
+; SIZE-NEXT:  Cost Model: Found an estimated cost of 4116 for instruction: %v = call <16 x i32> @llvm.pext.v16i32(<16 x i32> %va, <16 x i32> %vb)
 ; SIZE-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
 ;
 ; SIZE_LATE-LABEL: 'pext'
-; SIZE_LATE-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: %s = call i32 @llvm.pext.i32(i32 %a, i32 %b)
-; SIZE_LATE-NEXT:  Cost Model: Found an estimated cost of 100 for instruction: %v = call <16 x i32> @llvm.pext.v16i32(<16 x i32> %va, <16 x i32> %vb)
+; SIZE_LATE-NEXT:  Cost Model: Found an estimated cost of 252 for instruction: %s = call i32 @llvm.pext.i32(i32 %a, i32 %b)
+; SIZE_LATE-NEXT:  Cost Model: Found an estimated cost of 4116 for instruction: %v = call <16 x i32> @llvm.pext.v16i32(<16 x i32> %va, <16 x i32> %vb)
 ; SIZE_LATE-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
 ;
   %s = call i32 @llvm.pext.i32(i32 %a, i32 %b)



More information about the llvm-commits mailing list