Skip to content

Conversation

@nikic
Copy link
Contributor

@nikic nikic commented Dec 9, 2025

Disable implicit truncation in the ConstantInt constructor by default. This means that it needs to be passed a signed/unsigned (depending on the IsSigned flag) value matching the bit width.

The intention is to prevent the recurring bug where people write something like ConstantInt::get(Ty, -1), and this "works" until Ty is larger than 64-bit and then the value is incorrect due to missing type extension.

This is the continuation of #112670, which originally allowed implicit truncation in this constructor to reduce initial scope of the change.

In a number of places, set ImplicitTrunc=true with a TODO to reduce the scope of the change. Other places that violate the new requirement have been fixed in advance.

nikic added a commit that referenced this pull request Dec 12, 2025
Explicitly cast the value to (int) before negating, so it gets properly
sign extended. Otherwise we end up with a large unsigned value instead
of a negative value for large bit widths.

This was found while working on
#171456.
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Dec 12, 2025
Explicitly cast the value to (int) before negating, so it gets properly
sign extended. Otherwise we end up with a large unsigned value instead
of a negative value for large bit widths.

This was found while working on
llvm/llvm-project#171456.
anonymouspc pushed a commit to anonymouspc/llvm that referenced this pull request Dec 15, 2025
Explicitly cast the value to (int) before negating, so it gets properly
sign extended. Otherwise we end up with a large unsigned value instead
of a negative value for large bit widths.

This was found while working on
llvm#171456.
nikic added a commit that referenced this pull request Dec 16, 2025
Use getSigned() to create the 1 or -1 constant, so it gets properly sign
extended.

This miscompile was found while working on
#171456.
@nikic nikic force-pushed the constantint-implicit-trunc-false branch from 0eb2003 to 9e2cace Compare December 16, 2025 08:52
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Dec 16, 2025
…172301)

Use getSigned() to create the 1 or -1 constant, so it gets properly sign
extended.

This miscompile was found while working on
llvm/llvm-project#171456.
@github-actions
Copy link

github-actions bot commented Dec 16, 2025

🐧 Linux x64 Test Results

  • 187911 tests passed
  • 4989 tests skipped

✅ The build succeeded and all tests passed.

@nikic nikic force-pushed the constantint-implicit-trunc-false branch 2 times, most recently from 2f4c8d2 to 989ffc3 Compare December 17, 2025 14:22
@nikic nikic marked this pull request as ready for review December 17, 2025 14:24
@nikic nikic requested review from RKSimon, dtcxzyw and topperc December 17, 2025 14:24
@llvmbot
Copy link
Member

llvmbot commented Dec 17, 2025

@llvm/pr-subscribers-llvm-analysis
@llvm/pr-subscribers-compiler-rt-sanitizer
@llvm/pr-subscribers-llvm-selectiondag

@llvm/pr-subscribers-llvm-transforms

Author: Nikita Popov (nikic)

Changes

Disable implicit truncation in the ConstantInt constructor by default. This means that it needs to be passed a signed/unsigned (depending on the IsSigned flag) value matching the bit width.

The intention is to prevent the recurring bug where people write something like ConstantInt::get(Ty, -1), and this "works" until Ty is larger than 64-bit and then the value is incorrect due to missing type extension.

This is the continuation of #112670, which originally allowed implicit truncation in this constructor to reduce initial scope of the change.

In a number of places, set ImplicitTrunc=true with a TODO to reduce the scope of the change. Other places that violate the new requirement have been fixed in advance.


Full diff: https://github.com/llvm/llvm-project/pull/171456.diff

8 Files Affected:

  • (modified) llvm/include/llvm/IR/Constants.h (+2-4)
  • (modified) llvm/lib/Analysis/ScalarEvolution.cpp (+4-1)
  • (modified) llvm/lib/CodeGen/CodeGenPrepare.cpp (+4-1)
  • (modified) llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp (+4-1)
  • (modified) llvm/lib/CodeGen/SelectionDAG/FastISel.cpp (+4-1)
  • (modified) llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp (+4-1)
  • (modified) llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp (+4-1)
  • (modified) llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp (+4-1)
diff --git a/llvm/include/llvm/IR/Constants.h b/llvm/include/llvm/IR/Constants.h
index 39a556abe935b..6aa79846f10f5 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
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) {
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index 587c1372b19cb..7ec6113aaeafc 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -6881,7 +6881,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::get(
+          PtrIdxTy, BaseOffset, /*IsSigned=*/true, /*ImplicitTrunc=*/true);
       NewBaseGEP = OldBase;
       if (NewBaseGEP->getType() != I8PtrTy)
         NewBaseGEP = NewBaseBuilder.CreatePointerCast(NewBaseGEP, I8PtrTy);
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index 3906b311addf0..f4779d9a122f0 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -363,7 +363,10 @@ 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::get(IntN, Val, /*isSigned=*/true, /*implicitTrunc=*/true);
   return buildConstant(Res, *CI);
 }
 
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();
   }
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
index 5d96a67500dff..7325dee73d8f2 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;
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
diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
index e12caa2136962..7f28ea6f5c875 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::get(
+        Ty, Quantity, /*IsSigned=*/true, /*ImplicitTrunc=*/true));
     if (Scalable)
       SU = SE.getMulExpr(SU, SE.getVScale(SU->getType()));
     return SU;

@llvmbot
Copy link
Member

llvmbot commented Dec 17, 2025

@llvm/pr-subscribers-backend-spir-v

Author: Nikita Popov (nikic)

Changes

Disable implicit truncation in the ConstantInt constructor by default. This means that it needs to be passed a signed/unsigned (depending on the IsSigned flag) value matching the bit width.

The intention is to prevent the recurring bug where people write something like ConstantInt::get(Ty, -1), and this "works" until Ty is larger than 64-bit and then the value is incorrect due to missing type extension.

This is the continuation of #112670, which originally allowed implicit truncation in this constructor to reduce initial scope of the change.

In a number of places, set ImplicitTrunc=true with a TODO to reduce the scope of the change. Other places that violate the new requirement have been fixed in advance.


Full diff: https://github.com/llvm/llvm-project/pull/171456.diff

8 Files Affected:

  • (modified) llvm/include/llvm/IR/Constants.h (+2-4)
  • (modified) llvm/lib/Analysis/ScalarEvolution.cpp (+4-1)
  • (modified) llvm/lib/CodeGen/CodeGenPrepare.cpp (+4-1)
  • (modified) llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp (+4-1)
  • (modified) llvm/lib/CodeGen/SelectionDAG/FastISel.cpp (+4-1)
  • (modified) llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp (+4-1)
  • (modified) llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp (+4-1)
  • (modified) llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp (+4-1)
diff --git a/llvm/include/llvm/IR/Constants.h b/llvm/include/llvm/IR/Constants.h
index 39a556abe935ba..6aa79846f10f5f 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
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index e1f90264be7a26..770de89eccfb9a 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) {
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index 587c1372b19cb0..7ec6113aaeafc1 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -6881,7 +6881,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::get(
+          PtrIdxTy, BaseOffset, /*IsSigned=*/true, /*ImplicitTrunc=*/true);
       NewBaseGEP = OldBase;
       if (NewBaseGEP->getType() != I8PtrTy)
         NewBaseGEP = NewBaseBuilder.CreatePointerCast(NewBaseGEP, I8PtrTy);
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index 3906b311addf00..f4779d9a122f0c 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -363,7 +363,10 @@ 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::get(IntN, Val, /*isSigned=*/true, /*implicitTrunc=*/true);
   return buildConstant(Res, *CI);
 }
 
diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
index 51391f1aeecdef..03727b77b3e1a0 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();
   }
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
index 5d96a67500dffd..7325dee73d8f24 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;
diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
index 32ee16c89b4fee..9909037ba8ec51 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
diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
index e12caa21369626..7f28ea6f5c8750 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::get(
+        Ty, Quantity, /*IsSigned=*/true, /*ImplicitTrunc=*/true));
     if (Scalable)
       SU = SE.getMulExpr(SU, SE.getVScale(SU->getType()));
     return SU;

Copy link
Collaborator

@RKSimon RKSimon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SGTM - just a couple of queries.

What about ConstantInt::getSigned - have you considered adding a ImplicitTrunc flag to that as well?

Also, we've only got a few weeks before next release branch (including the quiet holiday period with less reports), and its likely random assert regression bugs will inevitably appear for a few months - are we OK with that (and merging fixes etc.)?

@dtcxzyw
Copy link
Member

dtcxzyw commented Dec 17, 2025

Also, we've only got a few weeks before next release branch (including the quiet holiday period with less reports), and its likely random assert regression bugs will inevitably appear for a few months - are we OK with that (and merging fixes etc.)?

I'd like to land this patch after the next release.

@nikic
Copy link
Contributor Author

nikic commented Dec 17, 2025

Also, we've only got a few weeks before next release branch (including the quiet holiday period with less reports), and its likely random assert regression bugs will inevitably appear for a few months - are we OK with that (and merging fixes etc.)?

My plan was to land this change on main and then revert it on the release branch.

@dtcxzyw
Copy link
Member

dtcxzyw commented Dec 18, 2025

Crash reproducer:

; bin/opt -passes=instcombine reduced.ll -S
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

define i16 @func_125(i16 %0) {
entry:
  %conv = sext i16 %0 to i64
  %conv2.i = trunc i64 %conv to i8
  %conv.i.i = sext i8 %conv2.i to i16
  %1 = shl i16 %conv.i.i, 1
  ret i16 %1
}
opt: /data/zyw/dev/llvm-project/llvm/include/llvm/ADT/APInt.h:127: llvm::APInt::APInt(unsigned int, uint64_t, bool, bool): Assertion `llvm::isUIntN(BitWidth, val) && "Value is not an N-bit unsigned value"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace and instructions to reproduce the bug.
Stack dump:
0.      Program arguments: bin/opt -passes=instcombine reduced.ll -S
1.      Running pass "function(instcombine<max-iterations=1;verify-fixpoint>)" on module "reduced.ll"
2.      Running pass "instcombine<max-iterations=1;verify-fixpoint>" on function "func_125"
 #0 0x00007975bb1f7a32 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /data/zyw/dev/llvm-project/llvm/lib/Support/Unix/Signals.inc:846:3
 #1 0x00007975bb1f494c llvm::sys::RunSignalHandlers() /data/zyw/dev/llvm-project/llvm/lib/Support/Signals.cpp:108:20
 #2 0x00007975bb1f5171 SignalHandler(int, siginfo_t*, void*) /data/zyw/dev/llvm-project/llvm/lib/Support/Unix/Signals.inc:429:14
 #3 0x00007975bac45330 (/lib/x86_64-linux-gnu/libc.so.6+0x45330)
 #4 0x00007975bac9eb2c __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
 #5 0x00007975bac9eb2c __pthread_kill_internal ./nptl/pthread_kill.c:78:10
 #6 0x00007975bac9eb2c pthread_kill ./nptl/pthread_kill.c:89:10
 #7 0x00007975bac4527e raise ./signal/../sysdeps/posix/raise.c:27:6
 #8 0x00007975bac288ff abort ./stdlib/abort.c:81:7
 #9 0x00007975bac2881b _nl_load_domain ./intl/loadmsgcat.c:1177:9
#10 0x00007975bac3b517 (/lib/x86_64-linux-gnu/libc.so.6+0x3b517)
#11 0x00007975b49205ae llvm::APInt::APInt(unsigned int, unsigned long, bool, bool) /data/zyw/dev/llvm-project/llvm/include/llvm/ADT/APInt.h:127:11
#12 0x00007975b49501c9 llvm::ConstantInt::get(llvm::IntegerType*, unsigned long, bool, bool) /data/zyw/dev/llvm-project/llvm/lib/IR/Constants.cpp:977:13
#13 0x00007975b49501c9 llvm::ConstantInt::get(llvm::Type*, unsigned long, bool, bool) /data/zyw/dev/llvm-project/llvm/lib/IR/Constants.cpp:966:10
#14 0x00007975ba17c296 dropRedundantMaskingOfLeftShiftInput /data/zyw/dev/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp:290:45
#15 0x00007975ba17c296 llvm::InstCombinerImpl::visitShl(llvm::BinaryOperator&) /data/zyw/dev/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp:1054:60
#16 0x00007975ba06b4e5 llvm::InstCombinerImpl::run() /data/zyw/dev/llvm-project/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp:5714:36
#17 0x00007975ba06cc7c combineInstructionsOverFunction(llvm::Function&, llvm::InstructionWorklist&, llvm::AAResults*, llvm::AssumptionCache&, llvm::TargetLibraryInfo&, llvm::TargetTransformInfo&, llvm::DominatorTree&, llvm::OptimizationRemarkEmitter&, llvm::BlockFrequencyInfo*, llvm::BranchProbabilityInfo*, llvm::ProfileSummaryInfo*, llvm::InstCombineOptions const&) /data/zyw/dev/llvm-project/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp:6028:5
#18 0x00007975ba06d688 llvm::InstCombinePass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) /data/zyw/dev/llvm-project/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp:6089:3
#19 0x00007975b78ef045 llvm::detail::PassModel<llvm::Function, llvm::InstCombinePass, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) /data/zyw/dev/llvm-project/llvm/include/llvm/IR/PassManagerInternal.h:92:3
#20 0x00007975b4acf79d llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) /data/zyw/dev/llvm-project/llvm/include/llvm/IR/PassManagerImpl.h:80:18
#21 0x00007975ba2bea05 llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) /data/zyw/dev/llvm-project/llvm/include/llvm/IR/PassManagerInternal.h:92:3
#22 0x00007975b4acfbd7 llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) /data/zyw/dev/llvm-project/llvm/lib/IR/PassManager.cpp:132:41
#23 0x00007975bb3f4e95 llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) /data/zyw/dev/llvm-project/llvm/include/llvm/IR/PassManagerInternal.h:92:3
#24 0x00007975b4ad0e56 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) /data/zyw/dev/llvm-project/llvm/include/llvm/IR/PassManagerImpl.h:80:18
#25 0x00007975bb400c1c llvm::SmallPtrSetImplBase::~SmallPtrSetImplBase() /data/zyw/dev/llvm-project/llvm/include/llvm/ADT/SmallPtrSet.h:89:5
#26 0x00007975bb400c1c llvm::SmallPtrSetImpl<llvm::AnalysisKey*>::~SmallPtrSetImpl() /data/zyw/dev/llvm-project/llvm/include/llvm/ADT/SmallPtrSet.h:368:35
#27 0x00007975bb400c1c llvm::SmallPtrSet<llvm::AnalysisKey*, 2u>::~SmallPtrSet() /data/zyw/dev/llvm-project/llvm/include/llvm/ADT/SmallPtrSet.h:527:7
#28 0x00007975bb400c1c llvm::PreservedAnalyses::~PreservedAnalyses() /data/zyw/dev/llvm-project/llvm/include/llvm/IR/Analysis.h:112:7
#29 0x00007975bb400c1c llvm::runPassPipeline(llvm::StringRef, llvm::Module&, llvm::TargetMachine*, llvm::TargetLibraryInfoImpl*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::StringRef, llvm::ArrayRef<llvm::PassPlugin>, llvm::ArrayRef<std::function<void (llvm::PassBuilder&)>>, llvm::opt_tool::OutputKind, llvm::opt_tool::VerifierKind, bool, bool, bool, bool, bool, bool, bool, bool) /data/zyw/dev/llvm-project/llvm/tools/opt/NewPMDriver.cpp:574:10
#30 0x00007975bb40c60b optMain /data/zyw/dev/llvm-project/llvm/tools/opt/optdriver.cpp:760:5
#31 0x00007975bac2a1ca __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3
#32 0x00007975bac2a28b call_init ./csu/../csu/libc-start.c:128:20
#33 0x00007975bac2a28b __libc_start_main ./csu/../csu/libc-start.c:347:5
#34 0x000058f5dd1ad095 _start (bin/opt+0x1095)
Aborted (core dumped)

mahesh-attarde pushed a commit to mahesh-attarde/llvm-project that referenced this pull request Dec 19, 2025
mahesh-attarde pushed a commit to mahesh-attarde/llvm-project that referenced this pull request Dec 19, 2025
Priyanshu3820 pushed a commit to Priyanshu3820/llvm-project that referenced this pull request Dec 20, 2025
Explicitly cast the value to (int) before negating, so it gets properly
sign extended. Otherwise we end up with a large unsigned value instead
of a negative value for large bit widths.

This was found while working on
llvm#171456.
@dtcxzyw
Copy link
Member

dtcxzyw commented Dec 20, 2025

Crash reproducer:

; bin/opt -passes=loop-vectorize test.ll -S
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

define i32 @main() {
entry:
  br label %for.cond101.preheader.i.i

for.cond101.preheader.i.i:                        ; preds = %for.cond101.preheader.i.i, %entry
  %storemerge20.i.i = phi i64 [ 1, %entry ], [ %inc268.i.i, %for.cond101.preheader.i.i ]
  %conv1537.lcssa1419.i.i = phi i1 [ false, %entry ], [ %tobool147.not.16.i.i, %for.cond101.preheader.i.i ]
  %.lcssa81618.i.i = phi i32 [ 0, %entry ], [ %cast.1.i.i, %for.cond101.preheader.i.i ]
  %cast.1.i.i = select i1 %conv1537.lcssa1419.i.i, i32 1, i32 0
  %tobool147.not.16.i.i = xor i1 %conv1537.lcssa1419.i.i, true
  %inc268.i.i = add i64 %storemerge20.i.i, 1
  %cmp97.not.i.i = icmp eq i64 %inc268.i.i, 0
  br i1 %cmp97.not.i.i, label %func_125.exit, label %for.cond101.preheader.i.i

func_125.exit:                                    ; preds = %for.cond101.preheader.i.i
  ret i32 0
}

opt: /data/zyw/dev/llvm-project/llvm/include/llvm/ADT/APInt.h:127: llvm::APInt::APInt(unsigned int, uint64_t, bool, bool): Assertion `llvm::isUIntN(BitWidth, val) && "Value is not an N-bit unsigned value"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace and instructions to reproduce the bug.
Stack dump:
0.      Program arguments: bin/opt -passes=loop-vectorize reduced.ll -S
1.      Running pass "function(loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>)" on module "reduced.ll"
2.      Running pass "loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>" on function "main"
 #0 0x000078a18cff6df2 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /data/zyw/dev/llvm-project/llvm/lib/Support/Unix/Signals.inc:846:3
 #1 0x000078a18cff3d0c llvm::sys::RunSignalHandlers() /data/zyw/dev/llvm-project/llvm/lib/Support/Signals.cpp:108:20
 #2 0x000078a18cff4531 SignalHandler(int, siginfo_t*, void*) /data/zyw/dev/llvm-project/llvm/lib/Support/Unix/Signals.inc:429:14
 #3 0x000078a18ca45330 (/lib/x86_64-linux-gnu/libc.so.6+0x45330)
 #4 0x000078a18ca9eb2c __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
 #5 0x000078a18ca9eb2c __pthread_kill_internal ./nptl/pthread_kill.c:78:10
 #6 0x000078a18ca9eb2c pthread_kill ./nptl/pthread_kill.c:89:10
 #7 0x000078a18ca4527e raise ./signal/../sysdeps/posix/raise.c:27:6
 #8 0x000078a18ca288ff abort ./stdlib/abort.c:81:7
 #9 0x000078a18ca2881b _nl_load_domain ./intl/loadmsgcat.c:1177:9
#10 0x000078a18ca3b517 (/lib/x86_64-linux-gnu/libc.so.6+0x3b517)
#11 0x000078a18671fe9e llvm::APInt::APInt(unsigned int, unsigned long, bool, bool) /data/zyw/dev/llvm-project/llvm/include/llvm/ADT/APInt.h:127:11
#12 0x000078a18674fa59 llvm::ConstantInt::get(llvm::IntegerType*, unsigned long, bool, bool) /data/zyw/dev/llvm-project/llvm/lib/IR/Constants.cpp:977:13
#13 0x000078a18674fa59 llvm::ConstantInt::get(llvm::Type*, unsigned long, bool, bool) /data/zyw/dev/llvm-project/llvm/lib/IR/Constants.cpp:966:10
#14 0x000078a186822f3f llvm::SmallVectorBase<unsigned int>::capacity() const /data/zyw/dev/llvm-project/llvm/include/llvm/ADT/SmallVector.h:81:36
#15 0x000078a186822f3f llvm::Constant* const* llvm::SmallVectorTemplateCommon<llvm::Constant*, void>::reserveForParamAndGetAddressImpl<llvm::SmallVectorTemplateBase<llvm::Constant*, true>>(llvm::SmallVectorTemplateBase<llvm::Constant*, true>*, llvm::Constant* const&, unsigned long) /data/zyw/dev/llvm-project/llvm/include/llvm/ADT/SmallVector.h:236:9
#16 0x000078a186822f3f llvm::SmallVectorTemplateBase<llvm::Constant*, true>::reserveForParamAndGetAddress(llvm::Constant*&, unsigned long) /data/zyw/dev/llvm-project/llvm/include/llvm/ADT/SmallVector.h:538:47
#17 0x000078a186822f3f llvm::SmallVectorTemplateBase<llvm::Constant*, true>::push_back(llvm::Constant*) /data/zyw/dev/llvm-project/llvm/include/llvm/ADT/SmallVector.h:563:51
#18 0x000078a186822f3f llvm::IRBuilderBase::CreateStepVector(llvm::Type*, llvm::Twine const&) /data/zyw/dev/llvm-project/llvm/lib/IR/IRBuilder.cpp:160:22
#19 0x000078a188cb7ee4 llvm::VPInstructionWithType::execute(llvm::VPTransformState&) /data/zyw/dev/llvm-project/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp:1408:39
#20 0x000078a188c59851 llvm::ilist_detail::node_base_prevnext<llvm::ilist_node_base<true, void>, true>::getNext() const /data/zyw/dev/llvm-project/llvm/include/llvm/ADT/ilist_node_base.h:42:38
#21 0x000078a188c59851 llvm::ilist_node_impl<llvm::ilist_detail::node_options<llvm::VPRecipeBase, true, false, void, false, void>>::getNext() /data/zyw/dev/llvm-project/llvm/include/llvm/ADT/ilist_node.h:108:66
#22 0x000078a188c59851 llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::VPRecipeBase, true, false, void, false, void>, false, false>::operator++() /data/zyw/dev/llvm-project/llvm/include/llvm/ADT/ilist_iterator.h:187:25
#23 0x000078a188c59851 llvm::VPBasicBlock::executeRecipes(llvm::VPTransformState*, llvm::BasicBlock*) /data/zyw/dev/llvm-project/llvm/lib/Transforms/Vectorize/VPlan.cpp:542:31
#24 0x000078a188c6c56d llvm::VPBasicBlock::execute(llvm::VPTransformState*) /data/zyw/dev/llvm-project/llvm/lib/Transforms/Vectorize/VPlan.cpp:525:28
#25 0x000078a188c733e1 llvm::VPlan::execute(llvm::VPTransformState*) /data/zyw/dev/llvm-project/llvm/lib/Transforms/Vectorize/VPlan.cpp:937:29
#26 0x000078a188ad8ba4 llvm::LoopVectorizationPlanner::executePlan(llvm::ElementCount, unsigned int, llvm::VPlan&, llvm::InnerLoopVectorizer&, llvm::DominatorTree*, bool) /data/zyw/dev/llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:7498:57
#27 0x000078a188af2efb llvm::DenseMap<llvm::SCEV const*, llvm::Value*, llvm::DenseMapInfo<llvm::SCEV const*, void>, llvm::detail::DenseMapPair<llvm::SCEV const*, llvm::Value*>>::~DenseMap() /data/zyw/dev/llvm-project/llvm/include/llvm/ADT/DenseMap.h:788:22
#28 0x000078a188af2efb llvm::LoopVectorizePass::processLoop(llvm::Loop*) /data/zyw/dev/llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:10223:20
#29 0x000078a188af5461 llvm::LoopVectorizePass::runImpl(llvm::Function&) /data/zyw/dev/llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:10276:27
#30 0x000078a188af58f7 llvm::LoopVectorizePass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) /data/zyw/dev/llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:10314:39
#31 0x000078a1896eeec5 llvm::detail::PassModel<llvm::Function, llvm::LoopVectorizePass, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) /data/zyw/dev/llvm-project/llvm/include/llvm/IR/PassManagerInternal.h:92:3
#32 0x000078a1868cdadd llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) /data/zyw/dev/llvm-project/llvm/include/llvm/IR/PassManagerImpl.h:80:18
#33 0x000078a18c0be015 llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) /data/zyw/dev/llvm-project/llvm/include/llvm/IR/PassManagerInternal.h:92:3
#34 0x000078a1868cdf17 llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) /data/zyw/dev/llvm-project/llvm/lib/IR/PassManager.cpp:132:41
#35 0x000078a18d16ee55 llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) /data/zyw/dev/llvm-project/llvm/include/llvm/IR/PassManagerInternal.h:92:3
#36 0x000078a1868cf196 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) /data/zyw/dev/llvm-project/llvm/include/llvm/IR/PassManagerImpl.h:80:18
#37 0x000078a18d17abdc llvm::SmallPtrSetImplBase::~SmallPtrSetImplBase() /data/zyw/dev/llvm-project/llvm/include/llvm/ADT/SmallPtrSet.h:89:5
#38 0x000078a18d17abdc llvm::SmallPtrSetImpl<llvm::AnalysisKey*>::~SmallPtrSetImpl() /data/zyw/dev/llvm-project/llvm/include/llvm/ADT/SmallPtrSet.h:368:35
#39 0x000078a18d17abdc llvm::SmallPtrSet<llvm::AnalysisKey*, 2u>::~SmallPtrSet() /data/zyw/dev/llvm-project/llvm/include/llvm/ADT/SmallPtrSet.h:527:7
#40 0x000078a18d17abdc llvm::PreservedAnalyses::~PreservedAnalyses() /data/zyw/dev/llvm-project/llvm/include/llvm/IR/Analysis.h:112:7
#41 0x000078a18d17abdc llvm::runPassPipeline(llvm::StringRef, llvm::Module&, llvm::TargetMachine*, llvm::TargetLibraryInfoImpl*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::StringRef, llvm::ArrayRef<llvm::PassPlugin>, llvm::ArrayRef<std::function<void (llvm::PassBuilder&)>>, llvm::opt_tool::OutputKind, llvm::opt_tool::VerifierKind, bool, bool, bool, bool, bool, bool, bool, bool) /data/zyw/dev/llvm-project/llvm/tools/opt/NewPMDriver.cpp:574:10
#42 0x000078a18d1865bb optMain /data/zyw/dev/llvm-project/llvm/tools/opt/optdriver.cpp:758:5
#43 0x000078a18ca2a1ca __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3
#44 0x000078a18ca2a28b call_init ./csu/../csu/libc-start.c:128:20
#45 0x000078a18ca2a28b __libc_start_main ./csu/../csu/libc-start.c:347:5
#46 0x00005c286da03095 _start (bin/opt+0x1095)
Aborted (core dumped)

@nikic
Copy link
Contributor Author

nikic commented Dec 23, 2025

I've submitted #173229 to fix that case. Also included the change in this PR for further testing.

@RKSimon RKSimon self-requested a review December 23, 2025 12:03
valadaptive pushed a commit to valadaptive/llvm-project that referenced this pull request Dec 24, 2025
Use getSigned() to create the 1 or -1 constant, so it gets properly sign
extended.

This miscompile was found while working on
llvm#171456.
valadaptive pushed a commit to valadaptive/llvm-project that referenced this pull request Dec 24, 2025
valadaptive pushed a commit to valadaptive/llvm-project that referenced this pull request Dec 24, 2025
…172875)

For consistency with `ConstantInt::get()`, add an ImplicitTrunc
parameter to `ConstantInt::getSigned()` as well. It currently defaults
to true and will be flipped to false in the future (by llvm#171456).
valadaptive pushed a commit to valadaptive/llvm-project that referenced this pull request Dec 24, 2025
valadaptive pushed a commit to valadaptive/llvm-project that referenced this pull request Dec 24, 2025
nikic added a commit that referenced this pull request Dec 25, 2025
LV can create step vectors that wrap around, e.g. `step-vector i1` with
VF>2. Allow truncation when creating the vector constant to avoid an
assertion failure with #171456.

After #173494 the definition of
the llvm.stepvector intrinsic has been changed to make it have wrapping
semantics, so the semantics for the fixed and scalable case match now.
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Dec 25, 2025
…#173229)

LV can create step vectors that wrap around, e.g. `step-vector i1` with
VF>2. Allow truncation when creating the vector constant to avoid an
assertion failure with llvm/llvm-project#171456.

After llvm/llvm-project#173494 the definition of
the llvm.stepvector intrinsic has been changed to make it have wrapping
semantics, so the semantics for the fixed and scalable case match now.
Copy link
Member

@dtcxzyw dtcxzyw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think my existing fuzzing corpus cannot discover more violations. It should be fine to land and wait for crash reports from other continuous fuzzing systems.
Remember to notify the release manager to revert this patch in the next release.

Copy link
Collaborator

@RKSimon RKSimon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (with a suitable merge conflict fix) - no objections to either immediate committal (+ reversion in 22.x) or waiting for 22.x to branch

Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants