[llvm] [IR] Add ImplicitTrunc argument to ConstantInt::get() (PR #170865)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Sat Dec 6 23:01:20 PST 2025


https://github.com/nikic updated https://github.com/llvm/llvm-project/pull/170865

>From 336f9cb7f247cf5f9b9234d72e9beda93e779ef3 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Fri, 5 Dec 2025 15:53:50 +0100
Subject: [PATCH 1/3] [IR] Add ImplicitTrunc argument to ConstantInt::get()

Add an ImplicitTrunc argument to ConstantInt::get(), which allows
controlling whether implicit truncation of the value is permitted.

This argument currently defaults to true, but will be switched to
false in the future to guard against signed/unsigned confusion,
similar to what has already happened for APInt.

The argument gives an opt-out for cases where the truncation is
intended. The patch contains one illustrative example where this
happens.
---
 llvm/include/llvm/IR/Constants.h | 11 ++++++++---
 llvm/lib/IR/Constants.cpp        | 13 +++++++------
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/llvm/include/llvm/IR/Constants.h b/llvm/include/llvm/IR/Constants.h
index e3f2eb9fa44b8..d03c8851616df 100644
--- a/llvm/include/llvm/IR/Constants.h
+++ b/llvm/include/llvm/IR/Constants.h
@@ -112,16 +112,21 @@ class ConstantInt final : public ConstantData {
 
   /// If Ty is a vector type, return a Constant with a splat of the given
   /// value. Otherwise return a ConstantInt for the given value.
-  LLVM_ABI static Constant *get(Type *Ty, uint64_t V, bool IsSigned = false);
+  /// \param ImplicitTrunc Whether to allow implicit truncation of the value.
+  // TODO: Make ImplicitTrunc default to false.
+  LLVM_ABI static Constant *get(Type *Ty, uint64_t V, bool IsSigned = false,
+                                bool ImplicitTrunc = true);
 
   /// Return a ConstantInt with the specified integer value for the specified
   /// type. If the type is wider than 64 bits, the value will be zero-extended
   /// to fit the type, unless IsSigned is true, in which case the value will
   /// be interpreted as a 64-bit signed integer and sign-extended to fit
   /// the type.
-  /// Get a ConstantInt for a specific value.
+  /// \param ImplicitTrunc Whether to allow implicit truncation of the value.
+  // TODO: Make ImplicitTrunc default to false.
   LLVM_ABI static ConstantInt *get(IntegerType *Ty, uint64_t V,
-                                   bool IsSigned = false);
+                                   bool IsSigned = false,
+                                   bool ImplicitTrunc = true);
 
   /// Return a ConstantInt with the specified value for the specified type. The
   /// value V will be canonicalized to a an unsigned APInt. Accessing it with
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index 6b82da140256f..2f020274c305a 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -960,8 +960,10 @@ ConstantInt *ConstantInt::get(LLVMContext &Context, ElementCount EC,
   return Slot.get();
 }
 
-Constant *ConstantInt::get(Type *Ty, uint64_t V, bool isSigned) {
-  Constant *C = get(cast<IntegerType>(Ty->getScalarType()), V, isSigned);
+Constant *ConstantInt::get(Type *Ty, uint64_t V, bool IsSigned,
+                           bool ImplicitTrunc) {
+  Constant *C =
+      get(cast<IntegerType>(Ty->getScalarType()), V, IsSigned, ImplicitTrunc);
 
   // For vectors, broadcast the value.
   if (VectorType *VTy = dyn_cast<VectorType>(Ty))
@@ -970,11 +972,10 @@ Constant *ConstantInt::get(Type *Ty, uint64_t V, bool isSigned) {
   return C;
 }
 
-ConstantInt *ConstantInt::get(IntegerType *Ty, uint64_t V, bool isSigned) {
-  // TODO: Avoid implicit trunc?
-  // See https://github.com/llvm/llvm-project/issues/112510.
+ConstantInt *ConstantInt::get(IntegerType *Ty, uint64_t V, bool IsSigned,
+                              bool ImplicitTrunc) {
   return get(Ty->getContext(),
-             APInt(Ty->getBitWidth(), V, isSigned, /*implicitTrunc=*/true));
+             APInt(Ty->getBitWidth(), V, IsSigned, ImplicitTrunc));
 }
 
 Constant *ConstantInt::get(Type *Ty, const APInt& V) {

>From 4f19e8ebc8a7dd8fc56bcce78dfca8ead350be0b Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Fri, 5 Dec 2025 16:04:18 +0100
Subject: [PATCH 2/3] Example usage

---
 llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 743c4f574e131..8e7282a4ffefe 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -3811,7 +3811,9 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
         if (VecToReduceCount.isFixed()) {
           unsigned VectorSize = VecToReduceCount.getFixedValue();
           return BinaryOperator::CreateMul(
-              Splat, ConstantInt::get(Splat->getType(), VectorSize));
+              Splat,
+              ConstantInt::get(Splat->getType(), VectorSize, /*IsSigned=*/false,
+                               /*ImplicitTrunc=*/true));
         }
       }
     }

>From 148c496b290df11eeb4888d9fd13a57cf005c9a1 Mon Sep 17 00:00:00 2001
From: Nikita Popov <github at npopov.com>
Date: Sun, 7 Dec 2025 08:01:12 +0100
Subject: [PATCH 3/3] Update llvm/include/llvm/IR/Constants.h

Co-authored-by: Yingwei Zheng <dtcxzyw at qq.com>
---
 llvm/include/llvm/IR/Constants.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/include/llvm/IR/Constants.h b/llvm/include/llvm/IR/Constants.h
index d03c8851616df..39a556abe935b 100644
--- a/llvm/include/llvm/IR/Constants.h
+++ b/llvm/include/llvm/IR/Constants.h
@@ -129,7 +129,7 @@ class ConstantInt final : public ConstantData {
                                    bool ImplicitTrunc = true);
 
   /// Return a ConstantInt with the specified value for the specified type. The
-  /// value V will be canonicalized to a an unsigned APInt. Accessing it with
+  /// value V will be canonicalized to an unsigned APInt. Accessing it with
   /// either getSExtValue() or getZExtValue() will yield a correctly sized and
   /// signed value for the type Ty.
   /// Get a ConstantInt for a specific signed value.



More information about the llvm-commits mailing list