[llvm] [ConstantInt] Disable implicit truncation in ConstantInt::get() (PR #171456)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 19 07:34:56 PST 2025


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

>From 5c85c8783c75feee7514eb4c19e664b9bae5fd30 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Tue, 9 Dec 2025 12:04:38 +0100
Subject: [PATCH 01/10] [IR] Disable implicit truncation in ConstantInt::get()
 by default

---
 llvm/include/llvm/IR/Constants.h | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/llvm/include/llvm/IR/Constants.h b/llvm/include/llvm/IR/Constants.h
index af9d25dd7fcd8..da2716ee18864 100644
--- a/llvm/include/llvm/IR/Constants.h
+++ b/llvm/include/llvm/IR/Constants.h
@@ -113,9 +113,8 @@ 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.
   /// \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);
+                                bool ImplicitTrunc = false);
 
   /// 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
@@ -123,10 +122,9 @@ class ConstantInt final : public ConstantData {
   /// be interpreted as a 64-bit signed integer and sign-extended to fit
   /// the type.
   /// \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 ImplicitTrunc = true);
+                                   bool ImplicitTrunc = false);
 
   /// Return a ConstantInt with the specified value for the specified type. The
   /// value V will be canonicalized to an unsigned APInt. Accessing it with
@@ -134,12 +132,11 @@ class ConstantInt final : public ConstantData {
   /// signed value for the type Ty.
   /// Get a ConstantInt for a specific signed value.
   /// \param ImplicitTrunc Whether to allow implicit truncation of the value.
-  // TODO: Make ImplicitTrunc default to false.
   static ConstantInt *getSigned(IntegerType *Ty, int64_t V,
-                                bool ImplicitTrunc = true) {
+                                bool ImplicitTrunc = false) {
     return get(Ty, V, /*IsSigned=*/true, ImplicitTrunc);
   }
-  static Constant *getSigned(Type *Ty, int64_t V, bool ImplicitTrunc = true) {
+  static Constant *getSigned(Type *Ty, int64_t V, bool ImplicitTrunc = false) {
     return get(Ty, V, /*IsSigned=*/true, ImplicitTrunc);
   }
 

>From 6278d69f05a332897dd68eb3227f6db9d5f4e38b Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Tue, 9 Dec 2025 12:22:32 +0100
Subject: [PATCH 02/10] [SCEV] Allow implicit truncation for now, to reduce
 scope

---
 llvm/lib/Analysis/ScalarEvolution.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index e1f90264be7a2..770de89eccfb9 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -485,7 +485,10 @@ const SCEV *ScalarEvolution::getConstant(const APInt &Val) {
 const SCEV *
 ScalarEvolution::getConstant(Type *Ty, uint64_t V, bool isSigned) {
   IntegerType *ITy = cast<IntegerType>(getEffectiveSCEVType(Ty));
-  return getConstant(ConstantInt::get(ITy, V, isSigned));
+  // TODO: Avoid implicit trunc?
+  // See https://github.com/llvm/llvm-project/issues/112510.
+  return getConstant(
+      ConstantInt::get(ITy, V, isSigned, /*ImplicitTrunc=*/true));
 }
 
 const SCEV *ScalarEvolution::getVScale(Type *Ty) {

>From 4bae249085777726cc394c864c9219ae21e64a13 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Tue, 9 Dec 2025 12:43:29 +0100
Subject: [PATCH 03/10] [MachineIRBuilder] Allow implicit trunc for now

To limit scope.
---
 llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index 3906b311addf0..e379975672c2d 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -363,7 +363,9 @@ MachineInstrBuilder MachineIRBuilder::buildConstant(const DstOp &Res,
                                                     int64_t Val) {
   auto IntN = IntegerType::get(getMF().getFunction().getContext(),
                                Res.getLLTTy(*getMRI()).getScalarSizeInBits());
-  ConstantInt *CI = ConstantInt::get(IntN, Val, true);
+  // TODO: Avoid implicit trunc?
+  // See https://github.com/llvm/llvm-project/issues/112510.
+  ConstantInt *CI = ConstantInt::getSigned(IntN, Val, /*implicitTrunc=*/true);
   return buildConstant(Res, *CI);
 }
 

>From 360f7db573d3ddfe9904f1fa97f061bb2a481b33 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Tue, 9 Dec 2025 14:51:18 +0100
Subject: [PATCH 04/10] [FastISel] Allow implicit trunc in FastISel for now

To reduce scope.
---
 llvm/lib/CodeGen/SelectionDAG/FastISel.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
index 51391f1aeecde..03727b77b3e1a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -1943,7 +1943,10 @@ Register FastISel::fastEmit_ri_(MVT VT, unsigned Opcode, Register Op0,
     // fast-isel, which would be very slow.
     IntegerType *ITy =
         IntegerType::get(FuncInfo.Fn->getContext(), VT.getSizeInBits());
-    MaterialReg = getRegForValue(ConstantInt::get(ITy, Imm));
+    // TODO: Avoid implicit trunc?
+    // See https://github.com/llvm/llvm-project/issues/112510.
+    MaterialReg = getRegForValue(
+        ConstantInt::get(ITy, Imm, /*IsSigned=*/false, /*ImplicitTrunc=*/true));
     if (!MaterialReg)
       return Register();
   }

>From 201d733bb77365e1edc34cc64a87c8c356d254f6 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Mon, 15 Dec 2025 12:19:31 +0100
Subject: [PATCH 05/10] [MemorySanitizer] Allow implicit truncation for now

---
 llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
index 32ee16c89b4fe..9909037ba8ec5 100644
--- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
@@ -1791,7 +1791,10 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
           constToIntPtr(VectTy->getElementType(), C));
     }
     assert(IntPtrTy == MS.IntptrTy);
-    return ConstantInt::get(MS.IntptrTy, C);
+    // TODO: Avoid implicit trunc?
+    // See https://github.com/llvm/llvm-project/issues/112510.
+    return ConstantInt::get(MS.IntptrTy, C, /*IsSigned=*/false,
+                            /*ImplicitTrunc=*/true);
   }
 
   /// Returns the integer shadow offset that corresponds to a given

>From 672ea75e2a2bb21431023d457b116b8f5401170f Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Mon, 15 Dec 2025 12:21:37 +0100
Subject: [PATCH 06/10] [SPIRV] Allow implicit truncation for now

---
 llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
index 9162da1c12a73..9a2b0771e4dc0 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
@@ -436,7 +436,10 @@ Register SPIRVGlobalRegistry::buildConstantInt(uint64_t Val,
   assert(SpvType);
   auto &MF = MIRBuilder.getMF();
   const IntegerType *Ty = cast<IntegerType>(getTypeForSPIRVType(SpvType));
-  auto *const CI = ConstantInt::get(const_cast<IntegerType *>(Ty), Val);
+  // TODO: Avoid implicit trunc?
+  // See https://github.com/llvm/llvm-project/issues/112510.
+  auto *const CI = ConstantInt::get(const_cast<IntegerType *>(Ty), Val,
+                                    /*IsSigned=*/false, /*ImplicitTrunc=*/true);
   Register Res = find(CI, &MF);
   if (Res.isValid())
     return Res;

>From 586fcde03ff59ec358055a17fa7a582c11a9e76f Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Mon, 15 Dec 2025 12:22:59 +0100
Subject: [PATCH 07/10] [LSR] Allow implicit truncation for now

---
 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
index e12caa2136962..70a6b52dbb313 100644
--- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -331,7 +331,10 @@ class Immediate : public details::FixedOrScalableQuantity<Immediate, int64_t> {
   }
 
   const SCEV *getUnknownSCEV(ScalarEvolution &SE, Type *Ty) const {
-    const SCEV *SU = SE.getUnknown(ConstantInt::getSigned(Ty, Quantity));
+    // TODO: Avoid implicit trunc?
+    // See https://github.com/llvm/llvm-project/issues/112510.
+    const SCEV *SU = SE.getUnknown(
+        ConstantInt::getSigned(Ty, Quantity, /*ImplicitTrunc=*/true));
     if (Scalable)
       SU = SE.getMulExpr(SU, SE.getVScale(SU->getType()));
     return SU;

>From d1ef5d445f785a4ee5e07c4191d86d56b6b6795d Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Mon, 15 Dec 2025 12:31:55 +0100
Subject: [PATCH 08/10] [CGP] Allow implicit truncation for now

---
 llvm/lib/CodeGen/CodeGenPrepare.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index 01f49b8ecccff..99fd463de8859 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -6880,7 +6880,10 @@ bool CodeGenPrepare::splitLargeGEPOffsets() {
       }
       IRBuilder<> NewBaseBuilder(NewBaseInsertBB, NewBaseInsertPt);
       // Create a new base.
-      Value *BaseIndex = ConstantInt::get(PtrIdxTy, BaseOffset);
+      // TODO: Avoid implicit trunc?
+      // See https://github.com/llvm/llvm-project/issues/112510.
+      Value *BaseIndex =
+          ConstantInt::getSigned(PtrIdxTy, BaseOffset, /*ImplicitTrunc=*/true);
       NewBaseGEP = OldBase;
       if (NewBaseGEP->getType() != I8PtrTy)
         NewBaseGEP = NewBaseBuilder.CreatePointerCast(NewBaseGEP, I8PtrTy);

>From 6461582402f905eec7833a23b50bc344e45c6141 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Fri, 19 Dec 2025 10:11:28 +0100
Subject: [PATCH 09/10] [LSR] Allow implicit truncatino in two more places

---
 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
index 70a6b52dbb313..df12766a648b4 100644
--- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -5806,10 +5806,12 @@ Value *LSRInstance::Expand(const LSRUse &LU, const LSRFixup &LF,
     if (LU.Kind == LSRUse::ICmpZero) {
       // The other interesting way of "folding" with an ICmpZero is to use a
       // negated immediate.
-      if (!ICmpScaledV)
-        ICmpScaledV =
-            ConstantInt::getSigned(IntTy, -(uint64_t)Offset.getFixedValue());
-      else {
+      if (!ICmpScaledV) {
+        // TODO: Avoid implicit trunc?
+        // See https://github.com/llvm/llvm-project/issues/112510.
+        ICmpScaledV = ConstantInt::getSigned(
+            IntTy, -(uint64_t)Offset.getFixedValue(), /*ImplicitTrunc=*/true);
+      } else {
         Ops.push_back(SE.getUnknown(ICmpScaledV));
         ICmpScaledV = ConstantInt::get(IntTy, Offset.getFixedValue());
       }
@@ -5859,8 +5861,11 @@ Value *LSRInstance::Expand(const LSRUse &LU, const LSRFixup &LF,
       assert((F.Scale == 0 || F.Scale == 1) &&
              "ICmp does not support folding a global value and "
              "a scale at the same time!");
+      // TODO: Avoid implicit trunc?
+      // See https://github.com/llvm/llvm-project/issues/112510.
       Constant *C = ConstantInt::getSigned(SE.getEffectiveSCEVType(OpTy),
-                                           -(uint64_t)Offset.getFixedValue());
+                                           -(uint64_t)Offset.getFixedValue(),
+                                           /*ImplicitTrunc=*/true);
       if (C->getType() != OpTy) {
         C = ConstantFoldCastOperand(
             CastInst::getCastOpcode(C, false, OpTy, false), C, OpTy,

>From d4071d69ed593444fc7ea34be1d4d54509e2ed44 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Fri, 19 Dec 2025 16:27:07 +0100
Subject: [PATCH 10/10] [LSR] Use getSigned(ImplicitTrunc=true) in one more
 place

Just getSigned() is sufficient for the test case, but given that
we can get overflow in the other three cases, we can probably also
get it here, so defensively set ImplicitTrunc=true here as well.
---
 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
index df12766a648b4..edb8b3b4c67e3 100644
--- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -5813,7 +5813,8 @@ Value *LSRInstance::Expand(const LSRUse &LU, const LSRFixup &LF,
             IntTy, -(uint64_t)Offset.getFixedValue(), /*ImplicitTrunc=*/true);
       } else {
         Ops.push_back(SE.getUnknown(ICmpScaledV));
-        ICmpScaledV = ConstantInt::get(IntTy, Offset.getFixedValue());
+        ICmpScaledV = ConstantInt::getSigned(IntTy, Offset.getFixedValue(),
+                                             /*ImplicitTrunc=*/true);
       }
     } else {
       // Just add the immediate values. These again are expected to be matched



More information about the llvm-commits mailing list