[clang] [lldb] [llvm] [mlir] [APInt] Assert correct values in APInt constructor (PR #80309)

Nikita Popov via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 19 09:09:28 PDT 2024


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

>From f47b38cd26107108f082df437196832fbe9ad78d Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Thu, 19 Sep 2024 17:27:13 +0200
Subject: [PATCH] apint only

---
 clang/lib/AST/ByteCode/IntegralAP.h           |   6 +-
 clang/lib/CodeGen/CGVTT.cpp                   |   4 +-
 clang/lib/CodeGen/ItaniumCXXABI.cpp           |   4 +-
 clang/lib/Parse/ParseInit.cpp                 |   4 +-
 clang/lib/Sema/SemaExpr.cpp                   |   7 +-
 clang/lib/Sema/SemaOpenMP.cpp                 |   4 +-
 lldb/source/Expression/DWARFExpression.cpp    |   7 +-
 llvm/include/llvm/ADT/APFixedPoint.h          |   4 +-
 llvm/include/llvm/ADT/APInt.h                 |   2 +-
 llvm/lib/Analysis/ConstantFolding.cpp         |   3 +-
 llvm/lib/Analysis/Loads.cpp                   |   6 +-
 llvm/lib/Analysis/MemoryBuiltins.cpp          |   2 +
 llvm/lib/Analysis/ScalarEvolution.cpp         |   2 +-
 llvm/lib/Bitcode/Reader/BitcodeReader.cpp     |   3 +-
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp |   5 +-
 .../SelectionDAG/SelectionDAGBuilder.cpp      |   3 +-
 .../CodeGen/SelectionDAG/SelectionDAGISel.cpp |   4 +-
 .../CodeGen/SelectionDAG/TargetLowering.cpp   |   8 +-
 llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp      |   2 +-
 llvm/lib/IR/Constants.cpp                     |   4 +-
 .../Target/AArch64/AArch64ISelLowering.cpp    |  32 ++--
 llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp |   2 +-
 .../AMDGPU/AMDGPUInstructionSelector.cpp      |   2 +-
 .../Disassembler/AMDGPUDisassembler.cpp       |   2 +-
 .../MCTargetDesc/AMDGPUMCTargetDesc.cpp       |   2 +-
 llvm/lib/Target/AMDGPU/SIInstrInfo.cpp        |  13 +-
 .../Target/AMDGPU/SIShrinkInstructions.cpp    |   4 +-
 .../lib/Target/ARM/AsmParser/ARMAsmParser.cpp |   4 +-
 .../Hexagon/HexagonConstPropagation.cpp       |   3 +-
 llvm/lib/Target/Hexagon/HexagonGenExtract.cpp |   2 +-
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp   |   4 +-
 llvm/lib/Target/X86/X86ISelLowering.cpp       |   6 +-
 llvm/lib/Transforms/IPO/ArgumentPromotion.cpp |   3 +-
 llvm/lib/Transforms/Utils/SimplifyCFG.cpp     |   2 +-
 llvm/unittests/ADT/APFixedPointTest.cpp       |   9 +-
 llvm/unittests/ADT/APIntTest.cpp              | 180 +++++++++---------
 llvm/unittests/ADT/APSIntTest.cpp             |   8 +-
 llvm/unittests/ADT/StringExtrasTest.cpp       |  10 +-
 .../Analysis/ScalarEvolutionTest.cpp          |   2 +-
 llvm/unittests/IR/MetadataTest.cpp            |  22 ++-
 .../Support/DivisionByConstantTest.cpp        |   2 +-
 mlir/include/mlir/IR/BuiltinAttributes.td     |   4 +-
 mlir/include/mlir/IR/OpImplementation.h       |   3 +-
 .../Conversion/TosaToArith/TosaToArith.cpp    |   2 +-
 .../Dialect/ControlFlow/IR/ControlFlowOps.cpp |   2 +-
 mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp    |   2 +-
 mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp  |   2 +-
 mlir/lib/IR/Builders.cpp                      |  16 +-
 .../SPIRV/Deserialization/Deserializer.cpp    |   6 +-
 .../Dialect/SPIRV/SerializationTest.cpp       |   2 +-
 50 files changed, 246 insertions(+), 191 deletions(-)

diff --git a/clang/lib/AST/ByteCode/IntegralAP.h b/clang/lib/AST/ByteCode/IntegralAP.h
index a4d656433344b7..6ab3d09ec85d5b 100644
--- a/clang/lib/AST/ByteCode/IntegralAP.h
+++ b/clang/lib/AST/ByteCode/IntegralAP.h
@@ -61,7 +61,7 @@ template <bool Signed> class IntegralAP final {
 
   IntegralAP(APInt V) : V(V) {}
   /// Arbitrary value for uninitialized variables.
-  IntegralAP() : IntegralAP(-1, 3) {}
+  IntegralAP() : IntegralAP(Signed ? -1 : 7, 3) {}
 
   IntegralAP operator-() const { return IntegralAP(-V); }
   IntegralAP operator-(const IntegralAP &Other) const {
@@ -112,7 +112,9 @@ template <bool Signed> class IntegralAP final {
 
   template <unsigned Bits, bool InputSigned>
   static IntegralAP from(Integral<Bits, InputSigned> I, unsigned BitWidth) {
-    APInt Copy = APInt(BitWidth, static_cast<uint64_t>(I), InputSigned);
+    // TODO: Avoid implicit trunc?
+    APInt Copy = APInt(BitWidth, static_cast<uint64_t>(I), InputSigned,
+                       /*implicitTrunc=*/true);
 
     return IntegralAP<Signed>(Copy);
   }
diff --git a/clang/lib/CodeGen/CGVTT.cpp b/clang/lib/CodeGen/CGVTT.cpp
index 20bd2c2fc2c642..c861e1f9203058 100644
--- a/clang/lib/CodeGen/CGVTT.cpp
+++ b/clang/lib/CodeGen/CGVTT.cpp
@@ -85,8 +85,8 @@ CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable *VTT,
          cast<llvm::StructType>(VTable->getValueType())
              ->getElementType(AddressPoint.VTableIndex));
      unsigned Offset = ComponentSize * AddressPoint.AddressPointIndex;
-     llvm::ConstantRange InRange(llvm::APInt(32, -Offset, true),
-                                 llvm::APInt(32, VTableSize - Offset, true));
+     llvm::ConstantRange InRange(llvm::APInt(32, -Offset),
+                                 llvm::APInt(32, VTableSize - Offset));
      llvm::Constant *Init = llvm::ConstantExpr::getGetElementPtr(
          VTable->getValueType(), VTable, Idxs, /*InBounds=*/true, InRange);
 
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index dcc35d5689831e..d6f3e9fb21e829 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -2099,8 +2099,8 @@ ItaniumCXXABI::getVTableAddressPoint(BaseSubobject Base,
   unsigned VTableSize =
       ComponentSize * Layout.getVTableSize(AddressPoint.VTableIndex);
   unsigned Offset = ComponentSize * AddressPoint.AddressPointIndex;
-  llvm::ConstantRange InRange(llvm::APInt(32, -Offset, true),
-                              llvm::APInt(32, VTableSize - Offset, true));
+  llvm::ConstantRange InRange(llvm::APInt(32, -Offset),
+                              llvm::APInt(32, VTableSize - Offset));
   return llvm::ConstantExpr::getGetElementPtr(
       VTable->getValueType(), VTable, Indices, /*InBounds=*/true, InRange);
 }
diff --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp
index 0a9a359cdaf979..e7c8d79ccccac3 100644
--- a/clang/lib/Parse/ParseInit.cpp
+++ b/clang/lib/Parse/ParseInit.cpp
@@ -437,7 +437,9 @@ ExprResult Parser::createEmbedExpr() {
   SourceLocation StartLoc = ConsumeAnnotationToken();
   if (Data->BinaryData.size() == 1) {
     Res = IntegerLiteral::Create(Context,
-                                 llvm::APInt(CHAR_BIT, Data->BinaryData.back()),
+                                 llvm::APInt(CHAR_BIT, Data->BinaryData.back(),
+                                             /*isSigned=*/false,
+                                             /*implicitTrunc=*/true),
                                  Context.UnsignedCharTy, StartLoc);
   } else {
     auto CreateStringLiteralFromStringRef = [&](StringRef Str, QualType Ty) {
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 2f7e9c754ce095..b830d6a5ae10d0 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -3590,8 +3590,11 @@ ExprResult Sema::ActOnCharacterConstant(const Token &Tok, Scope *UDLScope) {
 
 ExprResult Sema::ActOnIntegerConstant(SourceLocation Loc, uint64_t Val) {
   unsigned IntSize = Context.getTargetInfo().getIntWidth();
-  return IntegerLiteral::Create(Context, llvm::APInt(IntSize, Val),
-                                Context.IntTy, Loc);
+  // TODO: Avoid implicit trunc?
+  return IntegerLiteral::Create(
+      Context,
+      llvm::APInt(IntSize, Val, /*isSigned=*/false, /*implicitTrunc=*/true),
+      Context.IntTy, Loc);
 }
 
 static Expr *BuildFloatingLiteral(Sema &S, NumericLiteralParser &Literal,
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 9afb8cea26fe78..454a5b41d2c17e 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -5699,7 +5699,9 @@ StmtResult SemaOpenMP::ActOnOpenMPCanonicalLoop(Stmt *AStmt) {
       llvm_unreachable("unhandled unary increment operator");
     }
     Step = IntegerLiteral::Create(
-        Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {});
+        Ctx,
+        llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction, /*isSigned=*/true),
+        LogicalTy, {});
   } else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) {
     if (IncBin->getOpcode() == BO_AddAssign) {
       Step = IncBin->getRHS();
diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
index 22d899f799d0fd..564ddd098c4af6 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -860,10 +860,11 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
   // TODO: Implement a real typed stack, and store the genericness of the value
   // there.
   auto to_generic = [&](auto v) {
+    // TODO: Avoid implicit trunc?
     bool is_signed = std::is_signed<decltype(v)>::value;
-    return Scalar(llvm::APSInt(
-        llvm::APInt(8 * opcodes.GetAddressByteSize(), v, is_signed),
-        !is_signed));
+    return Scalar(llvm::APSInt(llvm::APInt(8 * opcodes.GetAddressByteSize(), v,
+                                           is_signed, /*implicitTrunc=*/true),
+                               !is_signed));
   };
 
   // The default kind is a memory location. This is updated by any
diff --git a/llvm/include/llvm/ADT/APFixedPoint.h b/llvm/include/llvm/ADT/APFixedPoint.h
index ae40db96e4818c..09d4df6d980649 100644
--- a/llvm/include/llvm/ADT/APFixedPoint.h
+++ b/llvm/include/llvm/ADT/APFixedPoint.h
@@ -159,7 +159,9 @@ class APFixedPoint {
   }
 
   APFixedPoint(uint64_t Val, const FixedPointSemantics &Sema)
-      : APFixedPoint(APInt(Sema.getWidth(), Val, Sema.isSigned()), Sema) {}
+      : APFixedPoint(APInt(Sema.getWidth(), Val, Sema.isSigned(),
+                           /*implicitTrunc=*/true),
+                     Sema) {}
 
   // Zero initialization.
   APFixedPoint(const FixedPointSemantics &Sema) : APFixedPoint(0, Sema) {}
diff --git a/llvm/include/llvm/ADT/APInt.h b/llvm/include/llvm/ADT/APInt.h
index a42dae8887392d..a6671c6792fec7 100644
--- a/llvm/include/llvm/ADT/APInt.h
+++ b/llvm/include/llvm/ADT/APInt.h
@@ -109,7 +109,7 @@ class [[nodiscard]] APInt {
   /// \param implicitTrunc allow implicit truncation of non-zero/sign bits of
   ///                      val beyond the range of numBits
   APInt(unsigned numBits, uint64_t val, bool isSigned = false,
-        bool implicitTrunc = true)
+        bool implicitTrunc = false)
       : BitWidth(numBits) {
     if (!implicitTrunc) {
       if (BitWidth == 0) {
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index a7a6de3f3b97b0..a05795c1267bac 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -887,7 +887,8 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
   APInt Offset = APInt(
       BitWidth,
       DL.getIndexedOffsetInType(
-          SrcElemTy, ArrayRef((Value *const *)Ops.data() + 1, Ops.size() - 1)));
+          SrcElemTy, ArrayRef((Value *const *)Ops.data() + 1, Ops.size() - 1)),
+      /*isSigned=*/true, /*implicitTrunc=*/true);
 
   std::optional<ConstantRange> InRange = GEP->getInRange();
   if (InRange)
diff --git a/llvm/lib/Analysis/Loads.cpp b/llvm/lib/Analysis/Loads.cpp
index 957ac883490c45..9dcebf424f8e33 100644
--- a/llvm/lib/Analysis/Loads.cpp
+++ b/llvm/lib/Analysis/Loads.cpp
@@ -95,10 +95,8 @@ static bool isDereferenceableAndAlignedPointer(
 
   auto IsKnownDeref = [&]() {
     bool CheckForNonNull, CheckForFreed;
-    APInt KnownDerefBytes(Size.getBitWidth(),
-                          V->getPointerDereferenceableBytes(DL, CheckForNonNull,
-                                                            CheckForFreed));
-    if (!KnownDerefBytes.getBoolValue() || !KnownDerefBytes.uge(Size) ||
+    if (!Size.ule(V->getPointerDereferenceableBytes(DL, CheckForNonNull,
+                                                    CheckForFreed)) ||
         CheckForFreed)
       return false;
     if (CheckForNonNull &&
diff --git a/llvm/lib/Analysis/MemoryBuiltins.cpp b/llvm/lib/Analysis/MemoryBuiltins.cpp
index e1abf5e4d885ec..dc2dc4c1733b5e 100644
--- a/llvm/lib/Analysis/MemoryBuiltins.cpp
+++ b/llvm/lib/Analysis/MemoryBuiltins.cpp
@@ -767,6 +767,8 @@ SizeOffsetAPInt ObjectSizeOffsetVisitor::visitAllocaInst(AllocaInst &I) {
   TypeSize ElemSize = DL.getTypeAllocSize(I.getAllocatedType());
   if (ElemSize.isScalable() && Options.EvalMode != ObjectSizeOpts::Mode::Min)
     return ObjectSizeOffsetVisitor::unknown();
+  if (!isUIntN(IntTyBits, ElemSize.getKnownMinValue()))
+    return ObjectSizeOffsetVisitor::unknown();
   APInt Size(IntTyBits, ElemSize.getKnownMinValue());
   if (!I.isArrayAllocation())
     return SizeOffsetAPInt(align(Size, I.getAlign()), Zero);
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 08396350697c45..fff0393f916535 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -6874,7 +6874,7 @@ const ConstantRange &ScalarEvolution::getRangeRef(
       bool CanBeNull, CanBeFreed;
       uint64_t DerefBytes =
           V->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed);
-      if (DerefBytes > 1) {
+      if (DerefBytes > 1 && isUIntN(BitWidth, DerefBytes)) {
         // The highest address the object can start is DerefBytes bytes before
         // the end (unsigned max value). If this value is not a multiple of the
         // alignment, the last possible start value is the next lowest multiple
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 027a29764148f0..14c56f6ff51da9 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -858,7 +858,8 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
     } else {
       int64_t Start = BitcodeReader::decodeSignRotatedValue(Record[OpNum++]);
       int64_t End = BitcodeReader::decodeSignRotatedValue(Record[OpNum++]);
-      return ConstantRange(APInt(BitWidth, Start), APInt(BitWidth, End));
+      return ConstantRange(APInt(BitWidth, Start, true),
+                           APInt(BitWidth, End, true));
     }
   }
 
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 3918da3ef031b6..008948309a663b 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -1641,7 +1641,10 @@ SDValue SelectionDAG::getConstant(uint64_t Val, const SDLoc &DL, EVT VT,
   assert((EltVT.getSizeInBits() >= 64 ||
           (uint64_t)((int64_t)Val >> EltVT.getSizeInBits()) + 1 < 2) &&
          "getConstant with a uint64_t value that doesn't fit in the type!");
-  return getConstant(APInt(EltVT.getSizeInBits(), Val), DL, VT, isT, isO);
+  // TODO: Avoid implicit trunc?
+  return getConstant(APInt(EltVT.getSizeInBits(), Val, /*isSigned=*/false,
+                           /*implicitTrunc=*/true),
+                     DL, VT, isT, isO);
 }
 
 SDValue SelectionDAG::getConstant(const APInt &Val, const SDLoc &DL, EVT VT,
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index eec89f04c6356d..b6175b1bcd29dd 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -4337,7 +4337,8 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
           GTI.getSequentialElementStride(DAG.getDataLayout());
       // We intentionally mask away the high bits here; ElementSize may not
       // fit in IdxTy.
-      APInt ElementMul(IdxSize, ElementSize.getKnownMinValue());
+      APInt ElementMul(IdxSize, ElementSize.getKnownMinValue(),
+                       /*isSigned=*/false, /*implicitTrunc=*/true);
       bool ElementScalable = ElementSize.isScalable();
 
       // If this is a scalar constant or a splat vector of constants,
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 2a97580942df36..c854175cde11df 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -2200,7 +2200,9 @@ ScheduleDAGSDNodes *SelectionDAGISel::CreateScheduler() {
 bool SelectionDAGISel::CheckAndMask(SDValue LHS, ConstantSDNode *RHS,
                                     int64_t DesiredMaskS) const {
   const APInt &ActualMask = RHS->getAPIntValue();
-  const APInt &DesiredMask = APInt(LHS.getValueSizeInBits(), DesiredMaskS);
+  // TODO: Avoid implicit trunc?
+  const APInt &DesiredMask = APInt(LHS.getValueSizeInBits(), DesiredMaskS,
+                                   /*isSigned=*/false, /*implicitTrunc=*/true);
 
   // If the actual mask exactly matches, success!
   if (ActualMask == DesiredMask)
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index a293c2391c3283..3e2c09159a8aa3 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -6812,7 +6812,9 @@ TargetLowering::prepareUREMEqFold(EVT SETCCVT, SDValue REMNode,
 
     PAmts.push_back(DAG.getConstant(P, DL, SVT));
     KAmts.push_back(
-        DAG.getConstant(APInt(ShSVT.getSizeInBits(), K), DL, ShSVT));
+        DAG.getConstant(APInt(ShSVT.getSizeInBits(), K, /*isSigned=*/false,
+                              /*implicitTrunc=*/true),
+                        DL, ShSVT));
     QAmts.push_back(DAG.getConstant(Q, DL, SVT));
     return true;
   };
@@ -7083,7 +7085,9 @@ TargetLowering::prepareSREMEqFold(EVT SETCCVT, SDValue REMNode,
     PAmts.push_back(DAG.getConstant(P, DL, SVT));
     AAmts.push_back(DAG.getConstant(A, DL, SVT));
     KAmts.push_back(
-        DAG.getConstant(APInt(ShSVT.getSizeInBits(), K), DL, ShSVT));
+        DAG.getConstant(APInt(ShSVT.getSizeInBits(), K, /*isSigned=*/false,
+                              /*implicitTrunc=*/true),
+                        DL, ShSVT));
     QAmts.push_back(DAG.getConstant(Q, DL, SVT));
     return true;
   };
diff --git a/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp
index 4cce4a77b343f0..e3b7db2380bb00 100644
--- a/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp
+++ b/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp
@@ -588,7 +588,7 @@ GenericValue MCJIT::runFunction(Function *F, ArrayRef<GenericValue> ArgValues) {
       return rv;
     }
     case Type::VoidTyID:
-      rv.IntVal = APInt(32, ((int(*)())(intptr_t)FPtr)());
+      rv.IntVal = APInt(32, ((int (*)())(intptr_t)FPtr)(), true);
       return rv;
     case Type::FloatTyID:
       rv.FloatVal = ((float(*)())(intptr_t)FPtr)();
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index 6d035d53732957..fe4a64ffca7173 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -932,7 +932,9 @@ Constant *ConstantInt::get(Type *Ty, uint64_t V, bool isSigned) {
 }
 
 ConstantInt *ConstantInt::get(IntegerType *Ty, uint64_t V, bool isSigned) {
-  return get(Ty->getContext(), APInt(Ty->getBitWidth(), V, isSigned));
+  // TODO: Avoid implicit trunc?
+  return get(Ty->getContext(),
+             APInt(Ty->getBitWidth(), V, isSigned, /*implicitTrunc=*/true));
 }
 
 Constant *ConstantInt::get(Type *Ty, const APInt& V) {
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index b11ac81069f660..497d1f0f02b5ef 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -2359,10 +2359,11 @@ void AArch64TargetLowering::computeKnownBitsForTargetNode(
   }
   case AArch64ISD::BICi: {
     // Compute the bit cleared value.
-    uint64_t Mask =
-        ~(Op->getConstantOperandVal(1) << Op->getConstantOperandVal(2));
+    APInt Mask =
+        ~(Op->getConstantOperandAPInt(1) << Op->getConstantOperandAPInt(2))
+             .trunc(Known.getBitWidth());
     Known = DAG.computeKnownBits(Op->getOperand(0), Depth + 1);
-    Known &= KnownBits::makeConstant(APInt(Known.getBitWidth(), Mask));
+    Known &= KnownBits::makeConstant(Mask);
     break;
   }
   case AArch64ISD::VLSHR: {
@@ -12706,7 +12707,8 @@ static bool isEXTMask(ArrayRef<int> M, EVT VT, bool &ReverseEXT,
   // Benefit form APInt to handle overflow when calculating expected element.
   unsigned NumElts = VT.getVectorNumElements();
   unsigned MaskBits = APInt(32, NumElts * 2).logBase2();
-  APInt ExpectedElt = APInt(MaskBits, *FirstRealElt + 1);
+  APInt ExpectedElt = APInt(MaskBits, *FirstRealElt + 1, /*isSigned=*/false,
+                            /*implicitTrunc=*/true);
   // The following shuffle indices must be the successive elements after the
   // first real element.
   bool FoundWrongElt = std::any_of(FirstRealElt + 1, M.end(), [&](int Elt) {
@@ -14173,9 +14175,9 @@ static SDValue NormalizeBuildVector(SDValue Op,
     // (with operands cast to integers), then the only possibilities
     // are constants and UNDEFs.
     if (auto *CstLane = dyn_cast<ConstantSDNode>(Lane)) {
-      APInt LowBits(EltTy.getSizeInBits(),
-                    CstLane->getZExtValue());
-      Lane = DAG.getConstant(LowBits.getZExtValue(), dl, MVT::i32);
+      Lane = DAG.getConstant(
+          CstLane->getAPIntValue().trunc(EltTy.getSizeInBits()).getZExtValue(),
+          dl, MVT::i32);
     } else if (Lane.getNode()->isUndef()) {
       Lane = DAG.getUNDEF(MVT::i32);
     } else {
@@ -23978,7 +23980,7 @@ static bool findMoreOptimalIndexType(const MaskedGatherScatterSDNode *N,
   EVT NewIndexVT = IndexVT.changeVectorElementType(MVT::i32);
   // Stride does not scale explicitly by 'Scale', because it happens in
   // the gather/scatter addressing mode.
-  Index = DAG.getStepVector(SDLoc(N), NewIndexVT, APInt(32, Stride));
+  Index = DAG.getStepVector(SDLoc(N), NewIndexVT, APInt(32, Stride, true));
   return true;
 }
 
@@ -28978,7 +28980,7 @@ static SDValue GenerateFixedLengthSVETBL(SDValue Op, SDValue Op1, SDValue Op2,
   unsigned BitsPerElt = VTOp1.getVectorElementType().getSizeInBits();
   unsigned IndexLen = MinSVESize / BitsPerElt;
   unsigned ElementsPerVectorReg = VTOp1.getVectorNumElements();
-  uint64_t MaxOffset = APInt(BitsPerElt, -1, false).getZExtValue();
+  uint64_t MaxOffset = APInt(BitsPerElt, -1, true).getZExtValue();
   EVT MaskEltType = VTOp1.getVectorElementType().changeTypeToInteger();
   EVT MaskType = EVT::getVectorVT(*DAG.getContext(), MaskEltType, IndexLen);
   bool MinMaxEqual = (MinSVESize == MaxSVESize);
@@ -29336,16 +29338,14 @@ bool AArch64TargetLowering::SimplifyDemandedBitsForTargetNode(
     KnownBits KnownOp0 =
         TLO.DAG.computeKnownBits(Op0, OriginalDemandedElts, Depth + 1);
     // Op0 &= ~(ConstantOperandVal(1) << ConstantOperandVal(2))
-    uint64_t BitsToClear = Op->getConstantOperandVal(1)
-                           << Op->getConstantOperandVal(2);
+    APInt BitsToClear =
+        (Op->getConstantOperandAPInt(1) << Op->getConstantOperandAPInt(2))
+            .trunc(KnownOp0.getBitWidth());
     APInt AlreadyZeroedBitsToClear = BitsToClear & KnownOp0.Zero;
-    if (APInt(Known.getBitWidth(), BitsToClear)
-            .isSubsetOf(AlreadyZeroedBitsToClear))
+    if (BitsToClear.isSubsetOf(AlreadyZeroedBitsToClear))
       return TLO.CombineTo(Op, Op0);
 
-    Known = KnownOp0 &
-            KnownBits::makeConstant(APInt(Known.getBitWidth(), ~BitsToClear));
-
+    Known = KnownOp0 & KnownBits::makeConstant(~BitsToClear);
     return false;
   }
   case ISD::INTRINSIC_WO_CHAIN: {
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp
index 380dc7d3312f32..47647cd6c97b9c 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp
@@ -1806,7 +1806,7 @@ bool AMDGPUDAGToDAGISel::SelectGlobalSAddr(SDNode *N,
       // instructions to perform VALU adds with immediates or inline literals.
       unsigned NumLiterals =
           !TII->isInlineConstant(APInt(32, COffsetVal & 0xffffffff)) +
-          !TII->isInlineConstant(APInt(32, COffsetVal >> 32));
+          !TII->isInlineConstant(APInt(32, uint64_t(COffsetVal) >> 32));
       if (Subtarget->getConstantBusLimit(AMDGPU::V_ADD_U32_e64) > NumLiterals)
         return false;
     }
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
index 53085d423cefb8..9bc4769bba8fad 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
@@ -4377,7 +4377,7 @@ AMDGPUInstructionSelector::selectGlobalSAddr(MachineOperand &Root) const {
         // instructions to perform VALU adds with immediates or inline literals.
         unsigned NumLiterals =
             !TII.isInlineConstant(APInt(32, ConstOffset & 0xffffffff)) +
-            !TII.isInlineConstant(APInt(32, ConstOffset >> 32));
+            !TII.isInlineConstant(APInt(32, uint64_t(ConstOffset) >> 32));
         if (STI.getConstantBusLimit(AMDGPU::V_ADD_U32_e64) > NumLiterals)
           return std::nullopt;
       }
diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
index 6c2a6643e67c76..4b69150b0f5ef4 100644
--- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
+++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
@@ -108,7 +108,7 @@ static DecodeStatus decodeSOPPBrTarget(MCInst &Inst, unsigned Imm,
 
   // Our branches take a simm16, but we need two extra bits to account for the
   // factor of 4.
-  APInt SignedOffset(18, Imm * 4, true);
+  APInt SignedOffset = APInt(16, Imm).sext(18) * 4;
   int64_t Offset = (SignedOffset.sext(64) + 4 + Addr).getSExtValue();
 
   if (DAsm->tryAddingSymbolicOperand(Inst, Offset, Addr, true, 2, 2, 0))
diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp
index 37eb0b57fb1537..c49eed9c564ca8 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp
+++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp
@@ -132,7 +132,7 @@ class AMDGPUMCInstrAnalysis : public MCInstrAnalysis {
     int64_t Imm = Inst.getOperand(0).getImm();
     // Our branches take a simm16, but we need two extra bits to account for
     // the factor of 4.
-    APInt SignedOffset(18, Imm * 4, true);
+    APInt SignedOffset = APInt(16, Imm).sext(18) * 4;
     Target = (SignedOffset.sext(64) + Addr + Size).getZExtValue();
     return true;
   }
diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
index c6a9a627d457e7..b8486ec52d2fe5 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
@@ -3401,11 +3401,15 @@ bool SIInstrInfo::foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI,
     case AMDGPU::sub1:
       return Hi_32(Imm);
     case AMDGPU::lo16:
-      return APInt(16, Imm).getSExtValue();
+      return APInt(16, Imm, /*isSigned=*/true, /*implicitTrunc=*/true)
+          .getSExtValue();
     case AMDGPU::hi16:
-      return APInt(32, Imm).ashr(16).getSExtValue();
+      return APInt(32, Imm, /*isSigned=*/true, /*implicitTrunc=*/true)
+          .ashr(16)
+          .getSExtValue();
     case AMDGPU::sub1_lo16:
-      return APInt(16, Hi_32(Imm)).getSExtValue();
+      return APInt(16, Hi_32(Imm), /*isSigned=*/true, /*implicitTrunc=*/true)
+          .getSExtValue();
     case AMDGPU::sub1_hi16:
       return APInt(32, Hi_32(Imm)).ashr(16).getSExtValue();
     }
@@ -3426,7 +3430,8 @@ bool SIInstrInfo::foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI,
                                            : AMDGPU::V_MOV_B32_e32
                                  : Is64Bit ? AMDGPU::S_MOV_B64_IMM_PSEUDO
                                            : AMDGPU::S_MOV_B32;
-    APInt Imm(Is64Bit ? 64 : 32, getImmFor(UseMI.getOperand(1)));
+    APInt Imm(Is64Bit ? 64 : 32, getImmFor(UseMI.getOperand(1)),
+              /*isSigned=*/true, /*implicitTrunc=*/true);
 
     if (RI.isAGPR(*MRI, DstReg)) {
       if (Is64Bit || !isInlineConstant(Imm))
diff --git a/llvm/lib/Target/AMDGPU/SIShrinkInstructions.cpp b/llvm/lib/Target/AMDGPU/SIShrinkInstructions.cpp
index 9967a65244413a..a4dc65a5e6e709 100644
--- a/llvm/lib/Target/AMDGPU/SIShrinkInstructions.cpp
+++ b/llvm/lib/Target/AMDGPU/SIShrinkInstructions.cpp
@@ -213,12 +213,12 @@ static unsigned canModifyToInlineImmOp32(const SIInstrInfo *TII,
     // that SCC is not live as S_NOT_B32 clobbers it. It's probably not worth
     // it, as the reasonable values are already covered by s_movk_i32.
     ModifiedImm = ~SrcImm;
-    if (TII->isInlineConstant(APInt(32, ModifiedImm)))
+    if (TII->isInlineConstant(APInt(32, ModifiedImm, true)))
       return AMDGPU::V_NOT_B32_e32;
   }
 
   ModifiedImm = reverseBits<int32_t>(SrcImm);
-  if (TII->isInlineConstant(APInt(32, ModifiedImm)))
+  if (TII->isInlineConstant(APInt(32, ModifiedImm, true)))
     return Scalar ? AMDGPU::S_BREV_B32 : AMDGPU::V_BFREV_B32_e32;
 
   return 0;
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 7d74f86c164fc7..9299420839f88b 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -1159,7 +1159,9 @@ class ARMOperand : public MCParsedAsmOperand {
     if (!isImm()) return false;
     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
     if (!CE) return false;
-    int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue()));
+    // TODO: Is implicitTrunc correct here?
+    int Val = ARM_AM::getFP32Imm(
+        APInt(32, CE->getValue(), /*isSigned=*/true, /*implicitTrunc=*/true));
     return Val != -1;
   }
 
diff --git a/llvm/lib/Target/Hexagon/HexagonConstPropagation.cpp b/llvm/lib/Target/Hexagon/HexagonConstPropagation.cpp
index dae316ccb5e903..f68444c0b8d462 100644
--- a/llvm/lib/Target/Hexagon/HexagonConstPropagation.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonConstPropagation.cpp
@@ -2503,7 +2503,8 @@ APInt HexagonConstEvaluator::getCmpImm(unsigned Opc, unsigned OpX,
   }
 
   uint64_t Val = MO.getImm();
-  return APInt(32, Val, Signed);
+  // TODO: Is implicitTrunc correct here?
+  return APInt(32, Val, Signed, /*implicitTrunc=*/true);
 }
 
 void HexagonConstEvaluator::replaceWithNop(MachineInstr &MI) {
diff --git a/llvm/lib/Target/Hexagon/HexagonGenExtract.cpp b/llvm/lib/Target/Hexagon/HexagonGenExtract.cpp
index 3274f9162b543a..2ed5150ec64f06 100644
--- a/llvm/lib/Target/Hexagon/HexagonGenExtract.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonGenExtract.cpp
@@ -171,7 +171,7 @@ bool HexagonGenExtract::convert(Instruction *In) {
     // this value.
     if (!LogicalSR && (SR > SL))
       return false;
-    APInt A = APInt(BW, ~0ULL).lshr(SR).shl(SL);
+    APInt A = APInt(BW, ~0ULL, true).lshr(SR).shl(SL);
     CM = ConstantInt::get(Ctx, A);
   }
 
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 189fb741f34cd1..05fd8f4c921601 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -3576,7 +3576,9 @@ static std::optional<VIDSequence> isSimpleVIDSequence(SDValue Op,
     if (!Elt)
       continue;
     APInt ExpectedVal =
-        (APInt(EltSizeInBits, Idx) * *SeqStepNum).sdiv(*SeqStepDenom);
+        (APInt(EltSizeInBits, Idx, /*isSigned=*/false, /*implicitTrunc=*/true) *
+         *SeqStepNum)
+            .sdiv(*SeqStepDenom);
 
     APInt Addend = *Elt - ExpectedVal;
     if (!SeqAddend)
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index c2bce6f01ef8f4..21e4dc06876e1b 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -52697,8 +52697,8 @@ static SDValue combineFMulcFCMulc(SDNode *N, SelectionDAG &DAG,
       if (XOR->getOpcode() == ISD::XOR && XOR.hasOneUse()) {
         KnownBits XORRHS = DAG.computeKnownBits(XOR.getOperand(1));
         if (XORRHS.isConstant()) {
-          APInt ConjugationInt32 = APInt(32, 0x80000000, true);
-          APInt ConjugationInt64 = APInt(64, 0x8000000080000000ULL, true);
+          APInt ConjugationInt32 = APInt(32, 0x80000000);
+          APInt ConjugationInt64 = APInt(64, 0x8000000080000000ULL);
           if ((XORRHS.getBitWidth() == 32 &&
                XORRHS.getConstant() == ConjugationInt32) ||
               (XORRHS.getBitWidth() == 64 &&
@@ -52737,7 +52737,7 @@ static SDValue combineFaddCFmul(SDNode *N, SelectionDAG &DAG,
            Flags.hasNoSignedZeros();
   };
   auto IsVectorAllNegativeZero = [&DAG](SDValue Op) {
-    APInt AI = APInt(32, 0x80008000, true);
+    APInt AI = APInt(32, 0x80008000);
     KnownBits Bits = DAG.computeKnownBits(Op);
     return Bits.getBitWidth() == 32 && Bits.isConstant() &&
            Bits.getConstant() == AI;
diff --git a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
index 1f9b546ed29996..78a2335045c302 100644
--- a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
+++ b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
@@ -101,7 +101,8 @@ using OffsetAndArgPart = std::pair<int64_t, ArgPart>;
 static Value *createByteGEP(IRBuilderBase &IRB, const DataLayout &DL,
                             Value *Ptr, Type *ResElemTy, int64_t Offset) {
   if (Offset != 0) {
-    APInt APOffset(DL.getIndexTypeSizeInBits(Ptr->getType()), Offset);
+    APInt APOffset(DL.getIndexTypeSizeInBits(Ptr->getType()), Offset,
+                   /*isSigned=*/true);
     Ptr = IRB.CreatePtrAdd(Ptr, IRB.getInt(APOffset));
   }
   return Ptr;
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 69c4475a494cbe..7113cd18acfeba 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -7199,7 +7199,7 @@ static bool reduceSwitchRange(SwitchInst *SI, IRBuilder<> &Builder,
 
   for (auto Case : SI->cases()) {
     auto *Orig = Case.getCaseValue();
-    auto Sub = Orig->getValue() - APInt(Ty->getBitWidth(), Base);
+    auto Sub = Orig->getValue() - APInt(Ty->getBitWidth(), Base, true);
     Case.setValue(cast<ConstantInt>(ConstantInt::get(Ty, Sub.lshr(Shift))));
   }
   return true;
diff --git a/llvm/unittests/ADT/APFixedPointTest.cpp b/llvm/unittests/ADT/APFixedPointTest.cpp
index ecb89fbf76c8bb..a0f43fdfcd7e43 100644
--- a/llvm/unittests/ADT/APFixedPointTest.cpp
+++ b/llvm/unittests/ADT/APFixedPointTest.cpp
@@ -240,19 +240,20 @@ void CheckIntPart(const FixedPointSemantics &Sema, int64_t IntPart) {
   APFixedPoint ValWithFract(
       APInt(Sema.getWidth(),
             relativeShr(IntPart, Sema.getLsbWeight()) + FullFactPart,
-            Sema.isSigned()),
+            Sema.isSigned(), /*implicitTrunc=*/true),
       Sema);
   ASSERT_EQ(ValWithFract.getIntPart(), IntPart);
 
   // Just fraction
-  APFixedPoint JustFract(APInt(Sema.getWidth(), FullFactPart, Sema.isSigned()),
+  APFixedPoint JustFract(APInt(Sema.getWidth(), FullFactPart, Sema.isSigned(),
+                               /*implicitTrunc=*/true),
                          Sema);
   ASSERT_EQ(JustFract.getIntPart(), 0);
 
   // Whole number
   APFixedPoint WholeNum(APInt(Sema.getWidth(),
                               relativeShr(IntPart, Sema.getLsbWeight()),
-                              Sema.isSigned()),
+                              Sema.isSigned(), /*implicitTrunc=*/true),
                         Sema);
   ASSERT_EQ(WholeNum.getIntPart(), IntPart);
 
@@ -260,7 +261,7 @@ void CheckIntPart(const FixedPointSemantics &Sema, int64_t IntPart) {
   if (Sema.isSigned()) {
     APFixedPoint Negative(APInt(Sema.getWidth(),
                                 relativeShr(IntPart, Sema.getLsbWeight()),
-                                Sema.isSigned()),
+                                Sema.isSigned(), /*implicitTrunc=*/true),
                           Sema);
     ASSERT_EQ(Negative.getIntPart(), IntPart);
   }
diff --git a/llvm/unittests/ADT/APIntTest.cpp b/llvm/unittests/ADT/APIntTest.cpp
index fff29d24a05299..7a9ac5562e7722 100644
--- a/llvm/unittests/ADT/APIntTest.cpp
+++ b/llvm/unittests/ADT/APIntTest.cpp
@@ -1111,11 +1111,11 @@ TEST(APIntTest, fromString) {
   EXPECT_EQ(APInt(32, 3), APInt(32,  "+11", 2));
   EXPECT_EQ(APInt(32, 4), APInt(32, "+100", 2));
 
-  EXPECT_EQ(APInt(32, uint64_t(-0LL)), APInt(32,   "-0", 2));
-  EXPECT_EQ(APInt(32, uint64_t(-1LL)), APInt(32,   "-1", 2));
-  EXPECT_EQ(APInt(32, uint64_t(-2LL)), APInt(32,  "-10", 2));
-  EXPECT_EQ(APInt(32, uint64_t(-3LL)), APInt(32,  "-11", 2));
-  EXPECT_EQ(APInt(32, uint64_t(-4LL)), APInt(32, "-100", 2));
+  EXPECT_EQ(APInt(32, uint32_t(-0LL)), APInt(32, "-0", 2));
+  EXPECT_EQ(APInt(32, uint32_t(-1LL)), APInt(32, "-1", 2));
+  EXPECT_EQ(APInt(32, uint32_t(-2LL)), APInt(32, "-10", 2));
+  EXPECT_EQ(APInt(32, uint32_t(-3LL)), APInt(32, "-11", 2));
+  EXPECT_EQ(APInt(32, uint32_t(-4LL)), APInt(32, "-100", 2));
 
   EXPECT_EQ(APInt(32,  0), APInt(32,  "0",  8));
   EXPECT_EQ(APInt(32,  1), APInt(32,  "1",  8));
@@ -1131,12 +1131,12 @@ TEST(APIntTest, fromString) {
   EXPECT_EQ(APInt(32, +15), APInt(32,  "+17", 8));
   EXPECT_EQ(APInt(32, +16), APInt(32,  "+20", 8));
 
-  EXPECT_EQ(APInt(32,  uint64_t(-0LL)), APInt(32,  "-0",  8));
-  EXPECT_EQ(APInt(32,  uint64_t(-1LL)), APInt(32,  "-1",  8));
-  EXPECT_EQ(APInt(32,  uint64_t(-7LL)), APInt(32,  "-7",  8));
-  EXPECT_EQ(APInt(32,  uint64_t(-8LL)), APInt(32,  "-10", 8));
-  EXPECT_EQ(APInt(32, uint64_t(-15LL)), APInt(32,  "-17", 8));
-  EXPECT_EQ(APInt(32, uint64_t(-16LL)), APInt(32,  "-20", 8));
+  EXPECT_EQ(APInt(32, uint32_t(-0LL)), APInt(32, "-0", 8));
+  EXPECT_EQ(APInt(32, uint32_t(-1LL)), APInt(32, "-1", 8));
+  EXPECT_EQ(APInt(32, uint32_t(-7LL)), APInt(32, "-7", 8));
+  EXPECT_EQ(APInt(32, uint32_t(-8LL)), APInt(32, "-10", 8));
+  EXPECT_EQ(APInt(32, uint32_t(-15LL)), APInt(32, "-17", 8));
+  EXPECT_EQ(APInt(32, uint32_t(-16LL)), APInt(32, "-20", 8));
 
   EXPECT_EQ(APInt(32,  0), APInt(32,  "0", 10));
   EXPECT_EQ(APInt(32,  1), APInt(32,  "1", 10));
@@ -1145,12 +1145,12 @@ TEST(APIntTest, fromString) {
   EXPECT_EQ(APInt(32, 19), APInt(32, "19", 10));
   EXPECT_EQ(APInt(32, 20), APInt(32, "20", 10));
 
-  EXPECT_EQ(APInt(32,  uint64_t(-0LL)), APInt(32,  "-0", 10));
-  EXPECT_EQ(APInt(32,  uint64_t(-1LL)), APInt(32,  "-1", 10));
-  EXPECT_EQ(APInt(32,  uint64_t(-9LL)), APInt(32,  "-9", 10));
-  EXPECT_EQ(APInt(32, uint64_t(-10LL)), APInt(32, "-10", 10));
-  EXPECT_EQ(APInt(32, uint64_t(-19LL)), APInt(32, "-19", 10));
-  EXPECT_EQ(APInt(32, uint64_t(-20LL)), APInt(32, "-20", 10));
+  EXPECT_EQ(APInt(32, uint32_t(-0LL)), APInt(32, "-0", 10));
+  EXPECT_EQ(APInt(32, uint32_t(-1LL)), APInt(32, "-1", 10));
+  EXPECT_EQ(APInt(32, uint32_t(-9LL)), APInt(32, "-9", 10));
+  EXPECT_EQ(APInt(32, uint32_t(-10LL)), APInt(32, "-10", 10));
+  EXPECT_EQ(APInt(32, uint32_t(-19LL)), APInt(32, "-19", 10));
+  EXPECT_EQ(APInt(32, uint32_t(-20LL)), APInt(32, "-20", 10));
 
   EXPECT_EQ(APInt(32,  0), APInt(32,  "0", 16));
   EXPECT_EQ(APInt(32,  1), APInt(32,  "1", 16));
@@ -1159,12 +1159,12 @@ TEST(APIntTest, fromString) {
   EXPECT_EQ(APInt(32, 31), APInt(32, "1F", 16));
   EXPECT_EQ(APInt(32, 32), APInt(32, "20", 16));
 
-  EXPECT_EQ(APInt(32,  uint64_t(-0LL)), APInt(32,  "-0", 16));
-  EXPECT_EQ(APInt(32,  uint64_t(-1LL)), APInt(32,  "-1", 16));
-  EXPECT_EQ(APInt(32, uint64_t(-15LL)), APInt(32,  "-F", 16));
-  EXPECT_EQ(APInt(32, uint64_t(-16LL)), APInt(32, "-10", 16));
-  EXPECT_EQ(APInt(32, uint64_t(-31LL)), APInt(32, "-1F", 16));
-  EXPECT_EQ(APInt(32, uint64_t(-32LL)), APInt(32, "-20", 16));
+  EXPECT_EQ(APInt(32, uint32_t(-0LL)), APInt(32, "-0", 16));
+  EXPECT_EQ(APInt(32, uint32_t(-1LL)), APInt(32, "-1", 16));
+  EXPECT_EQ(APInt(32, uint32_t(-15LL)), APInt(32, "-F", 16));
+  EXPECT_EQ(APInt(32, uint32_t(-16LL)), APInt(32, "-10", 16));
+  EXPECT_EQ(APInt(32, uint32_t(-31LL)), APInt(32, "-1F", 16));
+  EXPECT_EQ(APInt(32, uint32_t(-32LL)), APInt(32, "-20", 16));
 
   EXPECT_EQ(APInt(32,  0), APInt(32,  "0", 36));
   EXPECT_EQ(APInt(32,  1), APInt(32,  "1", 36));
@@ -1173,12 +1173,12 @@ TEST(APIntTest, fromString) {
   EXPECT_EQ(APInt(32, 71), APInt(32, "1Z", 36));
   EXPECT_EQ(APInt(32, 72), APInt(32, "20", 36));
 
-  EXPECT_EQ(APInt(32,  uint64_t(-0LL)), APInt(32,  "-0", 36));
-  EXPECT_EQ(APInt(32,  uint64_t(-1LL)), APInt(32,  "-1", 36));
-  EXPECT_EQ(APInt(32, uint64_t(-35LL)), APInt(32,  "-Z", 36));
-  EXPECT_EQ(APInt(32, uint64_t(-36LL)), APInt(32, "-10", 36));
-  EXPECT_EQ(APInt(32, uint64_t(-71LL)), APInt(32, "-1Z", 36));
-  EXPECT_EQ(APInt(32, uint64_t(-72LL)), APInt(32, "-20", 36));
+  EXPECT_EQ(APInt(32, uint32_t(-0LL)), APInt(32, "-0", 36));
+  EXPECT_EQ(APInt(32, uint32_t(-1LL)), APInt(32, "-1", 36));
+  EXPECT_EQ(APInt(32, uint32_t(-35LL)), APInt(32, "-Z", 36));
+  EXPECT_EQ(APInt(32, uint32_t(-36LL)), APInt(32, "-10", 36));
+  EXPECT_EQ(APInt(32, uint32_t(-71LL)), APInt(32, "-1Z", 36));
+  EXPECT_EQ(APInt(32, uint32_t(-72LL)), APInt(32, "-20", 36));
 }
 
 TEST(APIntTest, SaturatingMath) {
@@ -1202,10 +1202,10 @@ TEST(APIntTest, SaturatingMath) {
   EXPECT_EQ(APInt(6, 31), AP_42.truncSSat(6));
   EXPECT_EQ(APInt(5, 15), AP_42.truncSSat(5));
 
-  EXPECT_EQ(APInt(8, -56), AP_200.truncSSat(8));
-  EXPECT_EQ(APInt(7, -56), AP_200.truncSSat(7));
-  EXPECT_EQ(APInt(6, -32), AP_200.truncSSat(6));
-  EXPECT_EQ(APInt(5, -16), AP_200.truncSSat(5));
+  EXPECT_EQ(APInt(8, -56, true), AP_200.truncSSat(8));
+  EXPECT_EQ(APInt(7, -56, true), AP_200.truncSSat(7));
+  EXPECT_EQ(APInt(6, -32, true), AP_200.truncSSat(6));
+  EXPECT_EQ(APInt(5, -16, true), AP_200.truncSSat(5));
 
   EXPECT_EQ(APInt(8, 200), AP_100.uadd_sat(AP_100));
   EXPECT_EQ(APInt(8, 255), AP_100.uadd_sat(AP_200));
@@ -1213,52 +1213,53 @@ TEST(APIntTest, SaturatingMath) {
 
   EXPECT_EQ(APInt(8, 110), AP_10.sadd_sat(AP_100));
   EXPECT_EQ(APInt(8, 127), AP_100.sadd_sat(AP_100));
-  EXPECT_EQ(APInt(8, -128), (-AP_100).sadd_sat(-AP_100));
-  EXPECT_EQ(APInt(8, -128), APInt(8, -128).sadd_sat(APInt(8, -128)));
+  EXPECT_EQ(APInt(8, -128, true), (-AP_100).sadd_sat(-AP_100));
+  EXPECT_EQ(APInt(8, -128, true),
+            APInt(8, -128, true).sadd_sat(APInt(8, -128, true)));
 
   EXPECT_EQ(APInt(8, 90), AP_100.usub_sat(AP_10));
   EXPECT_EQ(APInt(8, 0), AP_100.usub_sat(AP_200));
   EXPECT_EQ(APInt(8, 0), APInt(8, 0).usub_sat(APInt(8, 255)));
 
-  EXPECT_EQ(APInt(8, -90), AP_10.ssub_sat(AP_100));
+  EXPECT_EQ(APInt(8, -90, true), AP_10.ssub_sat(AP_100));
   EXPECT_EQ(APInt(8, 127), AP_100.ssub_sat(-AP_100));
-  EXPECT_EQ(APInt(8, -128), (-AP_100).ssub_sat(AP_100));
-  EXPECT_EQ(APInt(8, -128), APInt(8, -128).ssub_sat(APInt(8, 127)));
+  EXPECT_EQ(APInt(8, -128, true), (-AP_100).ssub_sat(AP_100));
+  EXPECT_EQ(APInt(8, -128, true), APInt(8, -128, true).ssub_sat(APInt(8, 127)));
 
   EXPECT_EQ(APInt(8, 250), APInt(8, 50).umul_sat(APInt(8, 5)));
   EXPECT_EQ(APInt(8, 255), APInt(8, 50).umul_sat(APInt(8, 6)));
-  EXPECT_EQ(APInt(8, 255), APInt(8, -128).umul_sat(APInt(8, 3)));
-  EXPECT_EQ(APInt(8, 255), APInt(8, 3).umul_sat(APInt(8, -128)));
-  EXPECT_EQ(APInt(8, 255), APInt(8, -128).umul_sat(APInt(8, -128)));
+  EXPECT_EQ(APInt(8, 255), APInt(8, -128, true).umul_sat(APInt(8, 3)));
+  EXPECT_EQ(APInt(8, 255), APInt(8, 3).umul_sat(APInt(8, -128, true)));
+  EXPECT_EQ(APInt(8, 255), APInt(8, -128, true).umul_sat(APInt(8, -128, true)));
 
   EXPECT_EQ(APInt(8, 125), APInt(8, 25).smul_sat(APInt(8, 5)));
   EXPECT_EQ(APInt(8, 127), APInt(8, 25).smul_sat(APInt(8, 6)));
   EXPECT_EQ(APInt(8, 127), APInt(8, 127).smul_sat(APInt(8, 127)));
-  EXPECT_EQ(APInt(8, -125), APInt(8, -25).smul_sat(APInt(8, 5)));
-  EXPECT_EQ(APInt(8, -125), APInt(8, 25).smul_sat(APInt(8, -5)));
-  EXPECT_EQ(APInt(8, 125), APInt(8, -25).smul_sat(APInt(8, -5)));
+  EXPECT_EQ(APInt(8, -125, true), APInt(8, -25, true).smul_sat(APInt(8, 5)));
+  EXPECT_EQ(APInt(8, -125, true), APInt(8, 25).smul_sat(APInt(8, -5, true)));
+  EXPECT_EQ(APInt(8, 125), APInt(8, -25, true).smul_sat(APInt(8, -5, true)));
   EXPECT_EQ(APInt(8, 125), APInt(8, 25).smul_sat(APInt(8, 5)));
-  EXPECT_EQ(APInt(8, -128), APInt(8, -25).smul_sat(APInt(8, 6)));
-  EXPECT_EQ(APInt(8, -128), APInt(8, 25).smul_sat(APInt(8, -6)));
-  EXPECT_EQ(APInt(8, 127), APInt(8, -25).smul_sat(APInt(8, -6)));
+  EXPECT_EQ(APInt(8, -128, true), APInt(8, -25, true).smul_sat(APInt(8, 6)));
+  EXPECT_EQ(APInt(8, -128, true), APInt(8, 25).smul_sat(APInt(8, -6, true)));
+  EXPECT_EQ(APInt(8, 127), APInt(8, -25, true).smul_sat(APInt(8, -6, true)));
   EXPECT_EQ(APInt(8, 127), APInt(8, 25).smul_sat(APInt(8, 6)));
 
   EXPECT_EQ(APInt(8, 128), APInt(8, 4).ushl_sat(APInt(8, 5)));
   EXPECT_EQ(APInt(8, 255), APInt(8, 4).ushl_sat(APInt(8, 6)));
   EXPECT_EQ(APInt(8, 128), APInt(8, 1).ushl_sat(APInt(8, 7)));
   EXPECT_EQ(APInt(8, 255), APInt(8, 1).ushl_sat(APInt(8, 8)));
-  EXPECT_EQ(APInt(8, 255), APInt(8, -128).ushl_sat(APInt(8, 2)));
+  EXPECT_EQ(APInt(8, 255), APInt(8, -128, true).ushl_sat(APInt(8, 2)));
   EXPECT_EQ(APInt(8, 255), APInt(8, 64).ushl_sat(APInt(8, 2)));
-  EXPECT_EQ(APInt(8, 255), APInt(8, 64).ushl_sat(APInt(8, -2)));
+  EXPECT_EQ(APInt(8, 255), APInt(8, 64).ushl_sat(APInt(8, -2, true)));
 
   EXPECT_EQ(APInt(8, 64), APInt(8, 4).sshl_sat(APInt(8, 4)));
   EXPECT_EQ(APInt(8, 127), APInt(8, 4).sshl_sat(APInt(8, 5)));
   EXPECT_EQ(APInt(8, 127), APInt(8, 1).sshl_sat(APInt(8, 8)));
-  EXPECT_EQ(APInt(8, -64), APInt(8, -4).sshl_sat(APInt(8, 4)));
-  EXPECT_EQ(APInt(8, -128), APInt(8, -4).sshl_sat(APInt(8, 5)));
-  EXPECT_EQ(APInt(8, -128), APInt(8, -4).sshl_sat(APInt(8, 6)));
-  EXPECT_EQ(APInt(8, -128), APInt(8, -1).sshl_sat(APInt(8, 7)));
-  EXPECT_EQ(APInt(8, -128), APInt(8, -1).sshl_sat(APInt(8, 8)));
+  EXPECT_EQ(APInt(8, -64, true), APInt(8, -4, true).sshl_sat(APInt(8, 4)));
+  EXPECT_EQ(APInt(8, -128, true), APInt(8, -4, true).sshl_sat(APInt(8, 5)));
+  EXPECT_EQ(APInt(8, -128, true), APInt(8, -4, true).sshl_sat(APInt(8, 6)));
+  EXPECT_EQ(APInt(8, -128, true), APInt(8, -1, true).sshl_sat(APInt(8, 7)));
+  EXPECT_EQ(APInt(8, -128, true), APInt(8, -1, true).sshl_sat(APInt(8, 8)));
 }
 
 TEST(APIntTest, FromArray) {
@@ -1400,39 +1401,39 @@ TEST(APIntTest, toString) {
   S.clear();
 
   isSigned = false;
-  APInt(8, 255, isSigned).toString(S, 2, isSigned, true);
+  APInt(8, 255).toString(S, 2, isSigned, true);
   EXPECT_EQ(std::string(S), "0b11111111");
   S.clear();
-  APInt(8, 255, isSigned).toString(S, 8, isSigned, true);
+  APInt(8, 255).toString(S, 8, isSigned, true);
   EXPECT_EQ(std::string(S), "0377");
   S.clear();
-  APInt(8, 255, isSigned).toString(S, 10, isSigned, true);
+  APInt(8, 255).toString(S, 10, isSigned, true);
   EXPECT_EQ(std::string(S), "255");
   S.clear();
-  APInt(8, 255, isSigned).toString(S, 16, isSigned, true, /*UpperCase=*/false);
+  APInt(8, 255).toString(S, 16, isSigned, true, /*UpperCase=*/false);
   EXPECT_EQ(std::string(S), "0xff");
   S.clear();
-  APInt(8, 255, isSigned).toString(S, 16, isSigned, true);
+  APInt(8, 255).toString(S, 16, isSigned, true);
   EXPECT_EQ(std::string(S), "0xFF");
   S.clear();
-  APInt(8, 255, isSigned).toString(S, 36, isSigned, false);
+  APInt(8, 255).toString(S, 36, isSigned, false);
   EXPECT_EQ(std::string(S), "73");
   S.clear();
 
   isSigned = true;
-  APInt(8, 255, isSigned).toString(S, 2, isSigned, true);
+  APInt(8, 255).toString(S, 2, isSigned, true);
   EXPECT_EQ(std::string(S), "-0b1");
   S.clear();
-  APInt(8, 255, isSigned).toString(S, 8, isSigned, true);
+  APInt(8, 255).toString(S, 8, isSigned, true);
   EXPECT_EQ(std::string(S), "-01");
   S.clear();
-  APInt(8, 255, isSigned).toString(S, 10, isSigned, true);
+  APInt(8, 255).toString(S, 10, isSigned, true);
   EXPECT_EQ(std::string(S), "-1");
   S.clear();
-  APInt(8, 255, isSigned).toString(S, 16, isSigned, true);
+  APInt(8, 255).toString(S, 16, isSigned, true);
   EXPECT_EQ(std::string(S), "-0x1");
   S.clear();
-  APInt(8, 255, isSigned).toString(S, 36, isSigned, false);
+  APInt(8, 255).toString(S, 36, isSigned, false);
   EXPECT_EQ(std::string(S), "-1");
   S.clear();
 
@@ -1515,7 +1516,7 @@ TEST(APIntTest, Rotate) {
   EXPECT_EQ(APInt(32, 2), APInt(32, 1).rotl(APInt(33, 33)));
   EXPECT_EQ(APInt(32, (1 << 8)), APInt(32, 1).rotl(APInt(32, 40)));
   EXPECT_EQ(APInt(32, (1 << 30)), APInt(32, 1).rotl(APInt(31, 30)));
-  EXPECT_EQ(APInt(32, (1 << 31)), APInt(32, 1).rotl(APInt(31, 31)));
+  EXPECT_EQ(APInt(32, (1u << 31)), APInt(32, 1).rotl(APInt(31, 31)));
 
   EXPECT_EQ(APInt(32, 1), APInt(32, 1).rotl(APInt(1, 0)));
   EXPECT_EQ(APInt(32, 2), APInt(32, 1).rotl(APInt(1, 1)));
@@ -1542,24 +1543,24 @@ TEST(APIntTest, Rotate) {
   EXPECT_EQ(APInt(8, 16),  APInt(8, 1).rotr(4));
   EXPECT_EQ(APInt(8, 1),   APInt(8, 1).rotr(8));
 
-  EXPECT_EQ(APInt(32, (1 << 31)), APInt(32, 1).rotr(33));
-  EXPECT_EQ(APInt(32, (1 << 31)), APInt(32, 1).rotr(APInt(32, 33)));
+  EXPECT_EQ(APInt(32, (1u << 31)), APInt(32, 1).rotr(33));
+  EXPECT_EQ(APInt(32, (1u << 31)), APInt(32, 1).rotr(APInt(32, 33)));
 
-  EXPECT_EQ(APInt(32, (1 << 31)), APInt(32, 1).rotr(33));
-  EXPECT_EQ(APInt(32, (1 << 31)), APInt(32, 1).rotr(APInt(32, 33)));
-  EXPECT_EQ(APInt(32, (1 << 31)), APInt(32, 1).rotr(APInt(33, 33)));
+  EXPECT_EQ(APInt(32, (1u << 31)), APInt(32, 1).rotr(33));
+  EXPECT_EQ(APInt(32, (1u << 31)), APInt(32, 1).rotr(APInt(32, 33)));
+  EXPECT_EQ(APInt(32, (1u << 31)), APInt(32, 1).rotr(APInt(33, 33)));
   EXPECT_EQ(APInt(32, (1 << 24)), APInt(32, 1).rotr(APInt(32, 40)));
 
   EXPECT_EQ(APInt(32, (1 << 2)), APInt(32, 1).rotr(APInt(31, 30)));
   EXPECT_EQ(APInt(32, (1 << 1)), APInt(32, 1).rotr(APInt(31, 31)));
 
   EXPECT_EQ(APInt(32, 1), APInt(32, 1).rotr(APInt(1, 0)));
-  EXPECT_EQ(APInt(32, (1 << 31)), APInt(32, 1).rotr(APInt(1, 1)));
+  EXPECT_EQ(APInt(32, (1u << 31)), APInt(32, 1).rotr(APInt(1, 1)));
 
   EXPECT_EQ(APInt(32, (1 << 28)), APInt(32, 1).rotr(APInt(3, 4)));
 
   EXPECT_EQ(APInt(32, 1), APInt(32, 1).rotr(APInt(64, 64)));
-  EXPECT_EQ(APInt(32, (1 << 31)), APInt(32, 1).rotr(APInt(64, 65)));
+  EXPECT_EQ(APInt(32, (1u << 31)), APInt(32, 1).rotr(APInt(64, 65)));
 
   EXPECT_EQ(APInt(7, 48), APInt(7, 3).rotr(APInt(7, 3)));
   EXPECT_EQ(APInt(7, 48), APInt(7, 3).rotr(APInt(7, 10)));
@@ -1581,7 +1582,7 @@ TEST(APIntTest, Splat) {
 
   APInt ValB(3, 5);
   EXPECT_EQ(APInt(4, 0xD), APInt::getSplat(4, ValB));
-  EXPECT_EQ(APInt(15, 0xDB6D), APInt::getSplat(15, ValB));
+  EXPECT_EQ(APInt(15, 0x5B6D), APInt::getSplat(15, ValB));
 }
 
 TEST(APIntTest, tcDecrement) {
@@ -2858,7 +2859,7 @@ TEST(APIntTest, sext) {
   EXPECT_EQ(31U, i32_min.countr_zero());
   EXPECT_EQ(32U, i32_min.popcount());
 
-  APInt i32_neg1(APInt(32, ~uint64_t(0)).sext(63));
+  APInt i32_neg1(APInt(32, ~uint32_t(0)).sext(63));
   EXPECT_EQ(i32_neg1, i32_neg1.sext(63));
   EXPECT_EQ(63U, i32_neg1.countl_one());
   EXPECT_EQ(0U, i32_neg1.countr_zero());
@@ -2991,7 +2992,7 @@ TEST(APIntTest, RoundingUDiv) {
 
 TEST(APIntTest, RoundingSDiv) {
   for (int64_t Ai = -128; Ai <= 127; Ai++) {
-    APInt A(8, Ai);
+    APInt A(8, Ai, true);
 
     if (Ai != 0) {
       APInt Zero(8, 0);
@@ -3004,7 +3005,7 @@ TEST(APIntTest, RoundingSDiv) {
       if (Bi == 0)
         continue;
 
-      APInt B(8, Bi);
+      APInt B(8, Bi, true);
       APInt QuoTowardZero = A.sdiv(B);
       {
         APInt Quo = APIntOps::RoundingSDiv(A, B, APInt::Rounding::UP);
@@ -3063,10 +3064,10 @@ TEST(APIntTest, Average) {
   APInt Ap100(32, +100);
   APInt Ap101(32, +101);
   APInt Ap200(32, +200);
-  APInt Am1(32, -1);
-  APInt Am100(32, -100);
-  APInt Am101(32, -101);
-  APInt Am200(32, -200);
+  APInt Am1(32, -1, true);
+  APInt Am100(32, -100, true);
+  APInt Am101(32, -101, true);
+  APInt Am200(32, -200, true);
   APInt AmSMin = APInt::getSignedMinValue(32);
   APInt ApSMax = APInt::getSignedMaxValue(32);
 
@@ -3076,7 +3077,7 @@ TEST(APIntTest, Average) {
   EXPECT_EQ(APIntOps::RoundingSDiv(Ap100 + Ap200, A2, APInt::Rounding::UP),
             APIntOps::avgCeilS(Ap100, Ap200));
 
-  EXPECT_EQ(APInt(32, -150), APIntOps::avgFloorS(Am100, Am200));
+  EXPECT_EQ(APInt(32, -150, true), APIntOps::avgFloorS(Am100, Am200));
   EXPECT_EQ(APIntOps::RoundingSDiv(Am100 + Am200, A2, APInt::Rounding::DOWN),
             APIntOps::avgFloorS(Am100, Am200));
   EXPECT_EQ(APIntOps::RoundingSDiv(Am100 + Am200, A2, APInt::Rounding::UP),
@@ -3089,10 +3090,10 @@ TEST(APIntTest, Average) {
   EXPECT_EQ(APIntOps::RoundingSDiv(Ap100 + Ap101, A2, APInt::Rounding::UP),
             APIntOps::avgCeilS(Ap100, Ap101));
 
-  EXPECT_EQ(APInt(32, -101), APIntOps::avgFloorS(Am100, Am101));
+  EXPECT_EQ(APInt(32, -101, true), APIntOps::avgFloorS(Am100, Am101));
   EXPECT_EQ(APIntOps::RoundingSDiv(Am100 + Am101, A2, APInt::Rounding::DOWN),
             APIntOps::avgFloorS(Am100, Am101));
-  EXPECT_EQ(APInt(32, -100), APIntOps::avgCeilS(Am100, Am101));
+  EXPECT_EQ(APInt(32, -100, true), APIntOps::avgCeilS(Am100, Am101));
   EXPECT_EQ(APIntOps::RoundingSDiv(Am100 + Am101, A2, APInt::Rounding::UP),
             APIntOps::avgCeilS(Am100, Am101));
 
@@ -3304,7 +3305,8 @@ TEST(APIntTest, SolveQuadraticEquationWrap) {
       for (int B = Low; B != High; ++B) {
         for (int C = Low; C != High; ++C) {
           std::optional<APInt> S = APIntOps::SolveQuadraticEquationWrap(
-              APInt(Width, A), APInt(Width, B), APInt(Width, C), Width);
+              APInt(Width, A, true), APInt(Width, B, true),
+              APInt(Width, C, true), Width);
           if (S)
             Validate(A, B, C, Width, S->getSExtValue());
         }
@@ -3399,10 +3401,10 @@ TEST(APIntTest, GetMostSignificantDifferentBitExaustive) {
 }
 
 TEST(APIntTest, SignbitZeroChecks) {
-  EXPECT_TRUE(APInt(8, -1).isNegative());
-  EXPECT_FALSE(APInt(8, -1).isNonNegative());
-  EXPECT_FALSE(APInt(8, -1).isStrictlyPositive());
-  EXPECT_TRUE(APInt(8, -1).isNonPositive());
+  EXPECT_TRUE(APInt(8, -1, true).isNegative());
+  EXPECT_FALSE(APInt(8, -1, true).isNonNegative());
+  EXPECT_FALSE(APInt(8, -1, true).isStrictlyPositive());
+  EXPECT_TRUE(APInt(8, -1, true).isNonPositive());
 
   EXPECT_FALSE(APInt(8, 0).isNegative());
   EXPECT_TRUE(APInt(8, 0).isNonNegative());
diff --git a/llvm/unittests/ADT/APSIntTest.cpp b/llvm/unittests/ADT/APSIntTest.cpp
index f804eba3ca83eb..2d2a64433da94d 100644
--- a/llvm/unittests/ADT/APSIntTest.cpp
+++ b/llvm/unittests/ADT/APSIntTest.cpp
@@ -74,14 +74,14 @@ TEST(APSIntTest, getExtValue) {
   EXPECT_TRUE(APSInt(APInt(3, 7), false).isSigned());
   EXPECT_TRUE(APSInt(APInt(4, 7), true).isUnsigned());
   EXPECT_TRUE(APSInt(APInt(4, 7), false).isSigned());
-  EXPECT_TRUE(APSInt(APInt(4, -7), true).isUnsigned());
-  EXPECT_TRUE(APSInt(APInt(4, -7), false).isSigned());
+  EXPECT_TRUE(APSInt(APInt(4, -7, true), true).isUnsigned());
+  EXPECT_TRUE(APSInt(APInt(4, -7, true), false).isSigned());
   EXPECT_EQ(7, APSInt(APInt(3, 7), true).getExtValue());
   EXPECT_EQ(-1, APSInt(APInt(3, 7), false).getExtValue());
   EXPECT_EQ(7, APSInt(APInt(4, 7), true).getExtValue());
   EXPECT_EQ(7, APSInt(APInt(4, 7), false).getExtValue());
-  EXPECT_EQ(9, APSInt(APInt(4, -7), true).getExtValue());
-  EXPECT_EQ(-7, APSInt(APInt(4, -7), false).getExtValue());
+  EXPECT_EQ(9, APSInt(APInt(4, -7, true), true).getExtValue());
+  EXPECT_EQ(-7, APSInt(APInt(4, -7, true), false).getExtValue());
 }
 TEST(APSIntTest, tryExtValue) {
   ASSERT_EQ(-7, APSInt(APInt(64, -7), false).tryExtValue().value_or(42));
diff --git a/llvm/unittests/ADT/StringExtrasTest.cpp b/llvm/unittests/ADT/StringExtrasTest.cpp
index 51f7c3948a3146..36908a98aa2ae7 100644
--- a/llvm/unittests/ADT/StringExtrasTest.cpp
+++ b/llvm/unittests/ADT/StringExtrasTest.cpp
@@ -308,11 +308,11 @@ TEST(StringExtrasTest, toStringAPInt) {
   EXPECT_EQ(toString(APInt(8, 255, isSigned), 36, isSigned, false), "73");
 
   isSigned = true;
-  EXPECT_EQ(toString(APInt(8, 255, isSigned), 2, isSigned, true), "-0b1");
-  EXPECT_EQ(toString(APInt(8, 255, isSigned), 8, isSigned, true), "-01");
-  EXPECT_EQ(toString(APInt(8, 255, isSigned), 10, isSigned, true), "-1");
-  EXPECT_EQ(toString(APInt(8, 255, isSigned), 16, isSigned, true), "-0x1");
-  EXPECT_EQ(toString(APInt(8, 255, isSigned), 36, isSigned, false), "-1");
+  EXPECT_EQ(toString(APInt(8, -1, isSigned), 2, isSigned, true), "-0b1");
+  EXPECT_EQ(toString(APInt(8, -1, isSigned), 8, isSigned, true), "-01");
+  EXPECT_EQ(toString(APInt(8, -1, isSigned), 10, isSigned, true), "-1");
+  EXPECT_EQ(toString(APInt(8, -1, isSigned), 16, isSigned, true), "-0x1");
+  EXPECT_EQ(toString(APInt(8, -1, isSigned), 36, isSigned, false), "-1");
 }
 
 TEST(StringExtrasTest, toStringAPSInt) {
diff --git a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
index d4d90d80f4cea1..37c61e4e4fa714 100644
--- a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
+++ b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
@@ -984,7 +984,7 @@ TEST_F(ScalarEvolutionsTest, SCEVAddRecFromPHIwithLargeConstantAccum) {
   // entry:
   BranchInst::Create(LoopBB, EntryBB);
   // loop:
-  auto *MinInt32 = ConstantInt::get(Context, APInt(32, 0x80000000U, true));
+  auto *MinInt32 = ConstantInt::get(Context, APInt(32, 0x80000000U));
   auto *Int32_16 = ConstantInt::get(Context, APInt(32, 16));
   auto *Br = BranchInst::Create(
       LoopBB, ExitBB, UndefValue::get(Type::getInt1Ty(Context)), LoopBB);
diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp
index e99893498dde58..4572ec622ef624 100644
--- a/llvm/unittests/IR/MetadataTest.cpp
+++ b/llvm/unittests/IR/MetadataTest.cpp
@@ -4223,16 +4223,18 @@ TEST_F(DIExpressionTest, foldConstant) {
   DIExpression *Expr;
   DIExpression *NewExpr;
 
-#define EXPECT_FOLD_CONST(StartWidth, StartValue, EndWidth, EndValue, NumElts)  \
-  Int = ConstantInt::get(Context, APInt(StartWidth, StartValue));               \
-  std::tie(NewExpr, NewInt) = Expr->constantFold(Int);                          \
-  ASSERT_EQ(NewInt->getBitWidth(), EndWidth##u);                                \
-  EXPECT_EQ(NewInt->getValue(), APInt(EndWidth, EndValue));                     \
+#define EXPECT_FOLD_CONST(StartWidth, StartValue, StartIsSigned, EndWidth,     \
+                          EndValue, EndIsSigned, NumElts)                      \
+  Int =                                                                        \
+      ConstantInt::get(Context, APInt(StartWidth, StartValue, StartIsSigned)); \
+  std::tie(NewExpr, NewInt) = Expr->constantFold(Int);                         \
+  ASSERT_EQ(NewInt->getBitWidth(), EndWidth##u);                               \
+  EXPECT_EQ(NewInt->getValue(), APInt(EndWidth, EndValue, EndIsSigned));       \
   EXPECT_EQ(NewExpr->getNumElements(), NumElts##u)
 
   // Unfoldable expression should return the original unmodified Int/Expr.
   Expr = DIExpression::get(Context, {dwarf::DW_OP_deref});
-  EXPECT_FOLD_CONST(32, 117, 32, 117, 1);
+  EXPECT_FOLD_CONST(32, 117, false, 32, 117, false, 1);
   EXPECT_EQ(NewExpr, Expr);
   EXPECT_EQ(NewInt, Int);
   EXPECT_TRUE(NewExpr->startsWithDeref());
@@ -4240,18 +4242,18 @@ TEST_F(DIExpressionTest, foldConstant) {
   // One unsigned bit-width conversion.
   Expr = DIExpression::get(
       Context, {dwarf::DW_OP_LLVM_convert, 72, dwarf::DW_ATE_unsigned});
-  EXPECT_FOLD_CONST(8, 12, 72, 12, 0);
+  EXPECT_FOLD_CONST(8, 12, false, 72, 12, false, 0);
 
   // Two unsigned bit-width conversions (mask truncation).
   Expr = DIExpression::get(
       Context, {dwarf::DW_OP_LLVM_convert, 8, dwarf::DW_ATE_unsigned,
                 dwarf::DW_OP_LLVM_convert, 16, dwarf::DW_ATE_unsigned});
-  EXPECT_FOLD_CONST(32, -1, 16, 0xff, 0);
+  EXPECT_FOLD_CONST(32, -1, true, 16, 0xff, false, 0);
 
   // Sign extension.
   Expr = DIExpression::get(
       Context, {dwarf::DW_OP_LLVM_convert, 32, dwarf::DW_ATE_signed});
-  EXPECT_FOLD_CONST(16, -1, 32, -1, 0);
+  EXPECT_FOLD_CONST(16, -1, true, 32, -1, true, 0);
 
   // Get non-foldable operations back in the new Expr.
   uint64_t Elements[] = {dwarf::DW_OP_deref, dwarf::DW_OP_stack_value};
@@ -4260,7 +4262,7 @@ TEST_F(DIExpressionTest, foldConstant) {
       Context, {dwarf::DW_OP_LLVM_convert, 32, dwarf::DW_ATE_signed});
   Expr = DIExpression::append(Expr, Expected);
   ASSERT_EQ(Expr->getNumElements(), 5u);
-  EXPECT_FOLD_CONST(16, -1, 32, -1, 2);
+  EXPECT_FOLD_CONST(16, -1, true, 32, -1, true, 2);
   EXPECT_EQ(NewExpr->getElements(), Expected);
 
 #undef EXPECT_FOLD_CONST
diff --git a/llvm/unittests/Support/DivisionByConstantTest.cpp b/llvm/unittests/Support/DivisionByConstantTest.cpp
index 2b17f98bb75b2f..715dded68ff017 100644
--- a/llvm/unittests/Support/DivisionByConstantTest.cpp
+++ b/llvm/unittests/Support/DivisionByConstantTest.cpp
@@ -32,7 +32,7 @@ APInt SignedDivideUsingMagic(APInt Numerator, APInt Divisor,
   unsigned Bits = Numerator.getBitWidth();
 
   APInt Factor(Bits, 0);
-  APInt ShiftMask(Bits, -1);
+  APInt ShiftMask(Bits, -1, true);
   if (Divisor.isOne() || Divisor.isAllOnes()) {
     // If d is +1/-1, we just multiply the numerator by +1/-1.
     Factor = Divisor.getSExtValue();
diff --git a/mlir/include/mlir/IR/BuiltinAttributes.td b/mlir/include/mlir/IR/BuiltinAttributes.td
index f0d41754001400..530ba7d2f11e5c 100644
--- a/mlir/include/mlir/IR/BuiltinAttributes.td
+++ b/mlir/include/mlir/IR/BuiltinAttributes.td
@@ -701,8 +701,10 @@ def Builtin_IntegerAttr : Builtin_Attr<"Integer", "integer",
         return $_get(type.getContext(), type, apValue);
       }
 
+      // TODO: Avoid implicit trunc?
       IntegerType intTy = ::llvm::cast<IntegerType>(type);
-      APInt apValue(intTy.getWidth(), value, intTy.isSignedInteger());
+      APInt apValue(intTy.getWidth(), value, intTy.isSignedInteger(),
+                    /*implicitTrunc=*/true);
       return $_get(type.getContext(), type, apValue);
     }]>
   ];
diff --git a/mlir/include/mlir/IR/OpImplementation.h b/mlir/include/mlir/IR/OpImplementation.h
index e2472eea8a3714..606a56c7fd55b5 100644
--- a/mlir/include/mlir/IR/OpImplementation.h
+++ b/mlir/include/mlir/IR/OpImplementation.h
@@ -749,7 +749,8 @@ class AsmParser {
     // zero for non-negated integers.
     result =
         (IntT)uintResult.sextOrTrunc(sizeof(IntT) * CHAR_BIT).getLimitedValue();
-    if (APInt(uintResult.getBitWidth(), result) != uintResult)
+    if (APInt(uintResult.getBitWidth(), result, /*isSigned=*/true,
+              /*implicitTrunc=*/true) != uintResult)
       return emitError(loc, "integer value too large");
     return success();
   }
diff --git a/mlir/lib/Conversion/TosaToArith/TosaToArith.cpp b/mlir/lib/Conversion/TosaToArith/TosaToArith.cpp
index 50e57682a2dc8d..593dbaa6c6545a 100644
--- a/mlir/lib/Conversion/TosaToArith/TosaToArith.cpp
+++ b/mlir/lib/Conversion/TosaToArith/TosaToArith.cpp
@@ -43,7 +43,7 @@ Type matchContainerType(Type element, Type container) {
 TypedAttr getConstantAttr(Type type, int64_t value, PatternRewriter &rewriter) {
   if (auto shapedTy = dyn_cast<ShapedType>(type)) {
     Type eTy = shapedTy.getElementType();
-    APInt valueInt(eTy.getIntOrFloatBitWidth(), value);
+    APInt valueInt(eTy.getIntOrFloatBitWidth(), value, /*isSigned=*/true);
     return DenseIntElementsAttr::get(shapedTy, valueInt);
   }
 
diff --git a/mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp b/mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp
index 98b429de1fd85c..edd7f607f24f4d 100644
--- a/mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp
+++ b/mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp
@@ -528,7 +528,7 @@ static ParseResult parseSwitchOpCases(
     int64_t value = 0;
     if (failed(parser.parseInteger(value)))
       return failure();
-    values.push_back(APInt(bitWidth, value));
+    values.push_back(APInt(bitWidth, value, /*isSigned=*/true));
 
     Block *destination;
     SmallVector<OpAsmParser::UnresolvedOperand> operands;
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 205d7494d4378c..4bed20d66f8f6d 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -513,7 +513,7 @@ static ParseResult parseSwitchOpCases(
     int64_t value = 0;
     if (failed(parser.parseInteger(value)))
       return failure();
-    values.push_back(APInt(bitWidth, value));
+    values.push_back(APInt(bitWidth, value, /*isSigned=*/true));
 
     Block *destination;
     SmallVector<OpAsmParser::UnresolvedOperand> operands;
diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
index db47276dcefe95..adef50cd8d3971 100644
--- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
+++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
@@ -1073,7 +1073,7 @@ static ParseResult parseMembersIndex(OpAsmParser &parser,
     if (parser.parseInteger(value))
       return failure();
     shapeTmp++;
-    values.push_back(APInt(32, value));
+    values.push_back(APInt(32, value, /*isSigned=*/true));
     return success();
   };
 
diff --git a/mlir/lib/IR/Builders.cpp b/mlir/lib/IR/Builders.cpp
index 144a13df2179b7..305f7ea6ff4395 100644
--- a/mlir/lib/IR/Builders.cpp
+++ b/mlir/lib/IR/Builders.cpp
@@ -230,7 +230,10 @@ DenseIntElementsAttr Builder::getIndexTensorAttr(ArrayRef<int64_t> values) {
 }
 
 IntegerAttr Builder::getI32IntegerAttr(int32_t value) {
-  return IntegerAttr::get(getIntegerType(32), APInt(32, value));
+  // The APInt always uses isSigned=true here because we accept the value
+  // as int32_t.
+  return IntegerAttr::get(getIntegerType(32),
+                          APInt(32, value, /*isSigned=*/true));
 }
 
 IntegerAttr Builder::getSI32IntegerAttr(int32_t value) {
@@ -248,14 +251,19 @@ IntegerAttr Builder::getI16IntegerAttr(int16_t value) {
 }
 
 IntegerAttr Builder::getI8IntegerAttr(int8_t value) {
-  return IntegerAttr::get(getIntegerType(8), APInt(8, value));
+  // The APInt always uses isSigned=true here because we accept the value
+  // as int8_t.
+  return IntegerAttr::get(getIntegerType(8),
+                          APInt(8, value, /*isSigned=*/true));
 }
 
 IntegerAttr Builder::getIntegerAttr(Type type, int64_t value) {
   if (type.isIndex())
     return IntegerAttr::get(type, APInt(64, value));
-  return IntegerAttr::get(
-      type, APInt(type.getIntOrFloatBitWidth(), value, type.isSignedInteger()));
+  // TODO: Avoid implicit trunc?
+  return IntegerAttr::get(type, APInt(type.getIntOrFloatBitWidth(), value,
+                                      type.isSignedInteger(),
+                                      /*implicitTrunc=*/true));
 }
 
 IntegerAttr Builder::getIntegerAttr(Type type, const APInt &value) {
diff --git a/mlir/lib/Target/SPIRV/Deserialization/Deserializer.cpp b/mlir/lib/Target/SPIRV/Deserialization/Deserializer.cpp
index 38293f7106a05a..236e0ec100a0de 100644
--- a/mlir/lib/Target/SPIRV/Deserialization/Deserializer.cpp
+++ b/mlir/lib/Target/SPIRV/Deserialization/Deserializer.cpp
@@ -1284,9 +1284,11 @@ LogicalResult spirv::Deserializer::processConstant(ArrayRef<uint32_t> operands,
         uint32_t word1;
         uint32_t word2;
       } words = {operands[2], operands[3]};
-      value = APInt(64, llvm::bit_cast<uint64_t>(words), /*isSigned=*/true);
+      value = APInt(64, llvm::bit_cast<uint64_t>(words), /*isSigned=*/true,
+                    /*implicitTrunc=*/true);
     } else if (bitwidth <= 32) {
-      value = APInt(bitwidth, operands[2], /*isSigned=*/true);
+      value = APInt(bitwidth, operands[2], /*isSigned=*/true,
+                    /*implicitTrunc=*/true);
     }
 
     auto attr = opBuilder.getIntegerAttr(intType, value);
diff --git a/mlir/unittests/Dialect/SPIRV/SerializationTest.cpp b/mlir/unittests/Dialect/SPIRV/SerializationTest.cpp
index 9d2f690ed898af..ef89c1645d373f 100644
--- a/mlir/unittests/Dialect/SPIRV/SerializationTest.cpp
+++ b/mlir/unittests/Dialect/SPIRV/SerializationTest.cpp
@@ -176,7 +176,7 @@ TEST_F(SerializationTest, SignlessVsSignedIntegerConstantBitExtension) {
       IntegerType::get(&context, 16, IntegerType::Signless);
   auto signedInt16Type = IntegerType::get(&context, 16, IntegerType::Signed);
   // Check the bit extension of same value under different signedness semantics.
-  APInt signlessIntConstVal(signlessInt16Type.getWidth(), -1,
+  APInt signlessIntConstVal(signlessInt16Type.getWidth(), 0xffff,
                             signlessInt16Type.getSignedness());
   APInt signedIntConstVal(signedInt16Type.getWidth(), -1,
                           signedInt16Type.getSignedness());



More information about the cfe-commits mailing list