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

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 28 12:10:37 PST 2025


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

>From d43263d9f79bc30fd043aee9a9462dfcb7f31486 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 3bb2fa28cced8..dc279221733d5 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 41c2a46fb0e3005a3e98ec83b8883e3482f175e9 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 010a2cf855631..9edb804a3881e 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 737c61b70e94342302e0242df7484b2d7842dc3f 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 76d5d2b444b1f34c6ac8f97256493f95c06d82ae 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 38fd3a4f789593f2f416499a7334898dc1525d09 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 53e5091d35f47..fb70a0906712f 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 32361524460fdf797a131d4ce0e69361ede766dd 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 f7fe071f4f165ec60f5e5cefcebf3efd4bad6297 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 3edc65c37f2350acd6f1afcf2c813d56280289f6 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 6bf49c495e3d51f8f8afc115fcb97b1a2715b0e8 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 68bdf4b4a98a4ce1f1726382265ee9c846889c24 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