[llvm] [LLVM] Add `Type::getTruncatedType()` and use it in Intrinsics.cpp (PR #196239)

Rahul Joshi via llvm-commits llvm-commits at lists.llvm.org
Wed May 6 22:00:21 PDT 2026


https://github.com/jurahul created https://github.com/llvm/llvm-project/pull/196239

None

>From cd595a199e3fd0d74de6a9d499fb7d68e50ed2f7 Mon Sep 17 00:00:00 2001
From: Rahul Joshi <rjoshi at nvidia.com>
Date: Wed, 6 May 2026 21:58:31 -0700
Subject: [PATCH] [LLVM] Add `Type::getTruncatedType()` and use it in
 Intrinsics.cpp

---
 llvm/include/llvm/IR/DerivedTypes.h | 30 +++++++++++++++++------
 llvm/include/llvm/IR/Type.h         |  4 +++
 llvm/lib/IR/Intrinsics.cpp          | 38 +++++------------------------
 3 files changed, 32 insertions(+), 40 deletions(-)

diff --git a/llvm/include/llvm/IR/DerivedTypes.h b/llvm/include/llvm/IR/DerivedTypes.h
index c272f091e31a4..517baf06fb400 100644
--- a/llvm/include/llvm/IR/DerivedTypes.h
+++ b/llvm/include/llvm/IR/DerivedTypes.h
@@ -70,6 +70,14 @@ class IntegerType : public Type {
     return Type::getIntNTy(getContext(), 2 * getScalarSizeInBits());
   }
 
+  /// Returns type half as wide the input type.
+  IntegerType *getTruncatedType() const {
+    unsigned BitWidth = getScalarSizeInBits();
+    assert((BitWidth & 1) == 0 &&
+           "Cannot truncate integer type with odd bit-width");
+    return Type::getIntNTy(getContext(), BitWidth / 2);
+  }
+
   /// Get the number of bits in this IntegerType
   unsigned getBitWidth() const { return getSubclassData(); }
 
@@ -542,9 +550,9 @@ class VectorType : public Type {
   // the input type, and the element type is an integer or float type which
   // is half as wide as the elements in the input type.
   static VectorType *getTruncatedElementVectorType(VectorType *VTy) {
-    Type *EltTy;
-    if (VTy->getElementType()->isFloatingPointTy()) {
-      switch(VTy->getElementType()->getTypeID()) {
+    Type *EltTy = VTy->getElementType();
+    if (EltTy->isFloatingPointTy()) {
+      switch (EltTy->getTypeID()) {
       case DoubleTyID:
         EltTy = Type::getFloatTy(VTy->getContext());
         break;
@@ -555,11 +563,7 @@ class VectorType : public Type {
         llvm_unreachable("Cannot create narrower fp vector element type");
       }
     } else {
-      unsigned EltBits =
-          VTy->getElementType()->getPrimitiveSizeInBits().getFixedValue();
-      assert((EltBits & 1) == 0 &&
-             "Cannot truncate vector element with odd bit-width");
-      EltTy = IntegerType::get(VTy->getContext(), EltBits / 2);
+      EltTy = cast<IntegerType>(EltTy)->getTruncatedType();
     }
     return VectorType::get(EltTy, VTy->getElementCount());
   }
@@ -801,6 +805,16 @@ Type *Type::getExtendedType() const {
   return cast<IntegerType>(this)->getExtendedType();
 }
 
+Type *Type::getTruncatedType() const {
+  assert(
+      isIntOrIntVectorTy() &&
+      "Original type expected to be a vector of integers or a scalar integer.");
+  if (auto *VTy = dyn_cast<VectorType>(this))
+    return VectorType::getTruncatedElementVectorType(
+        const_cast<VectorType *>(VTy));
+  return cast<IntegerType>(this)->getTruncatedType();
+}
+
 Type *Type::getWithNewType(Type *EltTy) const {
   if (auto *VTy = dyn_cast<VectorType>(this))
     return VectorType::get(EltTy, VTy->getElementCount());
diff --git a/llvm/include/llvm/IR/Type.h b/llvm/include/llvm/IR/Type.h
index 4217d797cdf28..7d40e5dac9463 100644
--- a/llvm/include/llvm/IR/Type.h
+++ b/llvm/include/llvm/IR/Type.h
@@ -444,6 +444,10 @@ class Type {
   /// wide as in the original type. For vectors, preserves element count.
   LLVM_ABI inline Type *getExtendedType() const;
 
+  /// Given scalar/vector integer type, returns a type with elements half as
+  /// wide as in the original type. For vectors, preserves element count.
+  LLVM_ABI inline Type *getTruncatedType() const;
+
   /// Get the address space of this pointer or pointer vector type.
   LLVM_ABI inline unsigned getPointerAddressSpace() const;
 
diff --git a/llvm/lib/IR/Intrinsics.cpp b/llvm/lib/IR/Intrinsics.cpp
index 00cc17b3cabf5..ff57d335c9a13 100644
--- a/llvm/lib/IR/Intrinsics.cpp
+++ b/llvm/lib/IR/Intrinsics.cpp
@@ -554,22 +554,10 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
   case IITDescriptor::Overloaded:
   case IITDescriptor::VecOfAnyPtrsToElt:
     return OverloadTys[D.getOverloadIndex()];
-  case IITDescriptor::Extend: {
-    Type *Ty = OverloadTys[D.getOverloadIndex()];
-    if (VectorType *VTy = dyn_cast<VectorType>(Ty))
-      return VectorType::getExtendedElementVectorType(VTy);
-
-    return IntegerType::get(Context, 2 * cast<IntegerType>(Ty)->getBitWidth());
-  }
-  case IITDescriptor::Trunc: {
-    Type *Ty = OverloadTys[D.getOverloadIndex()];
-    if (VectorType *VTy = dyn_cast<VectorType>(Ty))
-      return VectorType::getTruncatedElementVectorType(VTy);
-
-    IntegerType *ITy = cast<IntegerType>(Ty);
-    assert(ITy->getBitWidth() % 2 == 0);
-    return IntegerType::get(Context, ITy->getBitWidth() / 2);
-  }
+  case IITDescriptor::Extend:
+    return OverloadTys[D.getOverloadIndex()]->getExtendedType();
+  case IITDescriptor::Trunc:
+    return OverloadTys[D.getOverloadIndex()]->getTruncatedType();
   case IITDescriptor::Subdivide2:
   case IITDescriptor::Subdivide4: {
     Type *Ty = OverloadTys[D.getOverloadIndex()];
@@ -960,14 +948,7 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
     if (D.getOverloadIndex() >= OverloadTys.size())
       return IsDeferredCheck || DeferCheck(Ty);
 
-    Type *NewTy = OverloadTys[D.getOverloadIndex()];
-    if (VectorType *VTy = dyn_cast<VectorType>(NewTy))
-      NewTy = VectorType::getExtendedElementVectorType(VTy);
-    else if (IntegerType *ITy = dyn_cast<IntegerType>(NewTy))
-      NewTy = IntegerType::get(ITy->getContext(), 2 * ITy->getBitWidth());
-    else
-      return true;
-
+    Type *NewTy = OverloadTys[D.getOverloadIndex()]->getExtendedType();
     return Ty != NewTy;
   }
   case IITDescriptor::Trunc: {
@@ -975,14 +956,7 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
     if (D.getOverloadIndex() >= OverloadTys.size())
       return IsDeferredCheck || DeferCheck(Ty);
 
-    Type *NewTy = OverloadTys[D.getOverloadIndex()];
-    if (VectorType *VTy = dyn_cast<VectorType>(NewTy))
-      NewTy = VectorType::getTruncatedElementVectorType(VTy);
-    else if (IntegerType *ITy = dyn_cast<IntegerType>(NewTy))
-      NewTy = IntegerType::get(ITy->getContext(), ITy->getBitWidth() / 2);
-    else
-      return true;
-
+    Type *NewTy = OverloadTys[D.getOverloadIndex()]->getTruncatedType();
     return Ty != NewTy;
   }
   case IITDescriptor::OneNthEltsVec: {



More information about the llvm-commits mailing list