Skip to content

[clang][Interp] Add IntegralAP for arbitrary-precision integers #65844

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Sep 30, 2023

Conversation

tbaederr
Copy link
Contributor

@tbaederr tbaederr commented Sep 9, 2023

This adds IntegralAP backing the two new primtypes IntAP (unsinged arbitrary-precision int) and IntAPS (same but signed).

We use this for int128 support (which isn't available on all host systems we support AFAIK) and I think we can also use this for _BitInt later.

@tbaederr tbaederr requested a review from a team as a code owner September 9, 2023 08:55
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Sep 9, 2023
@llvmbot
Copy link
Member

llvmbot commented Sep 9, 2023

@llvm/pr-subscribers-clang

Changes

This adds IntegralAP backing the two new primtypes IntAP (unsinged arbitrary-precision int) and IntAPS (same but signed).

We use this for int128 support (which isn't available on all host systems we support AFAIK) and I think we can also use this for _BitInt later.

Patch is 20.14 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/65844.diff

12 Files Affected:

  • (modified) clang/lib/AST/Interp/ByteCodeExprGen.cpp (+10-1)
  • (modified) clang/lib/AST/Interp/Context.cpp (+4-2)
  • (modified) clang/lib/AST/Interp/Descriptor.cpp (+9)
  • (modified) clang/lib/AST/Interp/EvalEmitter.cpp (+1)
  • (modified) clang/lib/AST/Interp/Integral.h (+4)
  • (added) clang/lib/AST/Interp/IntegralAP.h (+253)
  • (modified) clang/lib/AST/Interp/Interp.h (+14-7)
  • (modified) clang/lib/AST/Interp/InterpStack.h (+5)
  • (modified) clang/lib/AST/Interp/Opcodes.td (+5-3)
  • (modified) clang/lib/AST/Interp/PrimType.cpp (+1)
  • (modified) clang/lib/AST/Interp/PrimType.h (+13)
  • (modified) clang/test/AST/Interp/literals.cpp (+24)
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 17cf15d8676eb8..ec2ece71b30138 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -171,14 +171,17 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) {
         return this->discard(SubExpr);
     std::optional FromT = classify(SubExpr->getType());
     std::optional ToT = classify(CE->getType());
+
     if (!FromT || !ToT)
       return false;
 
     if (!this->visit(SubExpr))
       return false;
 
-    if (FromT == ToT)
+    if (FromT == ToT) {
+      assert(ToT != PT_IntAP && ToT != PT_IntAPS);
       return true;
+    }
 
     return this->emitCast(*FromT, *ToT, CE);
   }
@@ -1548,6 +1551,9 @@ bool ByteCodeExprGen::visitZeroInitializer(QualType QT,
     return this->emitZeroSint64(E);
   case PT_Uint64:
     return this->emitZeroUint64(E);
+  case PT_IntAP:
+  case PT_IntAPS:
+    assert(false);
   case PT_Ptr:
     return this->emitNullPtr(E);
   case PT_FnPtr:
@@ -1787,6 +1793,9 @@ bool ByteCodeExprGen::emitConst(T Value, PrimType Ty, const Expr *E) {
     return this->emitConstSint64(Value, E);
   case PT_Uint64:
     return this->emitConstUint64(Value, E);
+  case PT_IntAP:
+  case PT_IntAPS:
+    assert(false);
   case PT_Bool:
     return this->emitConstBool(Value, E);
   case PT_Ptr:
diff --git a/clang/lib/AST/Interp/Context.cpp b/clang/lib/AST/Interp/Context.cpp
index 1a732b6c1a092a..ed2b23514e8666 100644
--- a/clang/lib/AST/Interp/Context.cpp
+++ b/clang/lib/AST/Interp/Context.cpp
@@ -102,7 +102,8 @@ std::optional Context::classify(QualType T) const {
     case 8:
       return PT_Sint8;
     default:
-      return std::nullopt;
+      return PT_IntAPS;
+      // return std::nullopt;
     }
   }
 
@@ -117,7 +118,8 @@ std::optional Context::classify(QualType T) const {
     case 8:
       return PT_Uint8;
     default:
-      return std::nullopt;
+      return PT_IntAP;
+      // return std::nullopt;
     }
   }
 
diff --git a/clang/lib/AST/Interp/Descriptor.cpp b/clang/lib/AST/Interp/Descriptor.cpp
index db49a569eff33e..4ecb7466998e70 100644
--- a/clang/lib/AST/Interp/Descriptor.cpp
+++ b/clang/lib/AST/Interp/Descriptor.cpp
@@ -10,6 +10,7 @@
 #include "Boolean.h"
 #include "Floating.h"
 #include "FunctionPointer.h"
+#include "IntegralAP.h"
 #include "Pointer.h"
 #include "PrimType.h"
 #include "Record.h"
@@ -182,6 +183,10 @@ static BlockCtorFn getCtorPrim(PrimType Type) {
   // constructor called.
   if (Type == PT_Float)
     return ctorTy::T>;
+  if (Type == PT_IntAP)
+    return ctorTy::T>;
+  if (Type == PT_IntAPS)
+    return ctorTy::T>;
 
   COMPOSITE_TYPE_SWITCH(Type, return ctorTy, return nullptr);
 }
@@ -191,6 +196,10 @@ static BlockDtorFn getDtorPrim(PrimType Type) {
   // destructor called, since they might allocate memory.
   if (Type == PT_Float)
     return dtorTy::T>;
+  if (Type == PT_IntAP)
+    return dtorTy::T>;
+  if (Type == PT_IntAPS)
+    return dtorTy::T>;
 
   COMPOSITE_TYPE_SWITCH(Type, return dtorTy, return nullptr);
 }
diff --git a/clang/lib/AST/Interp/EvalEmitter.cpp b/clang/lib/AST/Interp/EvalEmitter.cpp
index d26ee8e40a437b..c9332d8b2364fa 100644
--- a/clang/lib/AST/Interp/EvalEmitter.cpp
+++ b/clang/lib/AST/Interp/EvalEmitter.cpp
@@ -8,6 +8,7 @@
 
 #include "EvalEmitter.h"
 #include "Context.h"
+#include "IntegralAP.h"
 #include "Interp.h"
 #include "Opcode.h"
 #include "Program.h"
diff --git a/clang/lib/AST/Interp/Integral.h b/clang/lib/AST/Interp/Integral.h
index 8d5edbb5b764ed..20c632cbac3f09 100644
--- a/clang/lib/AST/Interp/Integral.h
+++ b/clang/lib/AST/Interp/Integral.h
@@ -29,6 +29,8 @@ namespace interp {
 using APInt = llvm::APInt;
 using APSInt = llvm::APSInt;
 
+template  class IntegralAP;
+
 // Helper structure to select the representation.
 template  struct Repr;
 template <> struct Repr<8, false> { using Type = uint8_t; };
@@ -61,6 +63,8 @@ template  class Integral final {
   template  explicit Integral(T V) : V(V) {}
 
 public:
+  using AsUnsigned = Integral;
+
   /// Zero-initializes an integral.
   Integral() : V(0) {}
 
diff --git a/clang/lib/AST/Interp/IntegralAP.h b/clang/lib/AST/Interp/IntegralAP.h
new file mode 100644
index 00000000000000..236430c36883a3
--- /dev/null
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -0,0 +1,253 @@
+//===--- Integral.h - Wrapper for numeric types for the VM ------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines the VM types and helpers operating on types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_INTERP_INTEGRAL_AP_H
+#define LLVM_CLANG_AST_INTERP_INTEGRAL_AP_H
+
+#include "clang/AST/APValue.h"
+#include "clang/AST/ComparisonCategories.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/raw_ostream.h"
+#include 
+#include 
+
+#include "Primitives.h"
+
+namespace clang {
+namespace interp {
+
+using APInt = llvm::APInt;
+using APSInt = llvm::APSInt;
+template  class Integral;
+class Boolean;
+
+template  class IntegralAP final {
+public:
+  APSInt V;
+
+public:
+  using AsUnsigned = IntegralAP;
+
+  template 
+  IntegralAP(T Value) : V(APInt(sizeof(T) * 8, Value, std::is_signed_v)) {}
+
+  IntegralAP(APInt V) : V(V) {}
+  IntegralAP(APSInt V) : V(V) {}
+  IntegralAP(bool b) : V(APInt(8, b, Signed)) {}
+  /// Bullshit value for initialized variables.
+  IntegralAP() : V(APSInt::getMaxValue(1024, Signed)) {}
+
+  IntegralAP operator-() const { return IntegralAP(-V); }
+  // bool operator <=> (const IntegralAP &RHS) const = default;
+  bool operator>(IntegralAP RHS) const { return V > RHS.V; }
+  bool operator>=(IntegralAP RHS) const { return V >= RHS.V; }
+  bool operator<(IntegralAP RHS) const { return V < RHS.V; }
+  bool operator<=(IntegralAP RHS) const { return V <= RHS.V; }
+
+  explicit operator bool() const { return !V.isZero(); }
+  explicit operator int8_t() const { return V.getSExtValue(); }
+  explicit operator uint8_t() const { return V.getZExtValue(); }
+  explicit operator int16_t() const { return V.getSExtValue(); }
+  explicit operator uint16_t() const { return V.getZExtValue(); }
+  explicit operator int32_t() const { return V.getSExtValue(); }
+  explicit operator uint32_t() const { return V.getZExtValue(); }
+  explicit operator int64_t() const { return V.getSExtValue(); }
+  explicit operator uint64_t() const { return V.getZExtValue(); }
+
+  template  static IntegralAP from(T Value, unsigned NumBits = 0) {
+    assert(NumBits > 0);
+    APSInt Copy = APSInt(APInt(NumBits, Value, Signed), !Signed);
+
+    return IntegralAP(Copy);
+  }
+
+  template 
+  static IntegralAP from(IntegralAP V, unsigned NumBits = 0) {
+    if constexpr (Signed == InputSigned)
+      return V;
+
+    APSInt Copy = V.V;
+    Copy.setIsSigned(Signed);
+
+    return IntegralAP(Copy);
+  }
+
+  template 
+  static IntegralAP from(Integral I) {
+    assert(InputSigned);
+    /// TODO: Take bits parameter.
+    APSInt Copy =
+        APSInt(APInt(128, static_cast(I), InputSigned), !Signed);
+    Copy.setIsSigned(Signed);
+
+    assert(Copy.isSigned() == Signed);
+    return IntegralAP(Copy);
+  }
+  static IntegralAP from(const Boolean &B) {
+    assert(false);
+    return IntegralAP::zero();
+  }
+
+  static IntegralAP zero() {
+    assert(false);
+    return IntegralAP(0);
+  }
+
+  static constexpr unsigned bitWidth() { return 128; }
+
+  APSInt toAPSInt(unsigned Bits = 0) const { return V; }
+  APValue toAPValue() const { return APValue(V); }
+
+  bool isZero() const { return false; }
+  bool isPositive() const { return true; }
+  bool isNegative() const { return false; }
+  bool isMin() const { return false; }
+  bool isMax() const { return false; }
+  static bool isSigned() { return Signed; }
+  bool isMinusOne() const { return false; }
+
+  unsigned countLeadingZeros() const { return V.countl_zero(); }
+
+  void print(llvm::raw_ostream &OS) const { OS << V; }
+
+  IntegralAP truncate(unsigned bitWidth) const { return V; }
+  IntegralAP toUnsigned() const {
+    APSInt Copy = V;
+    Copy.setIsSigned(false);
+    return IntegralAP(Copy);
+  }
+
+  ComparisonCategoryResult compare(const IntegralAP &RHS) const {
+    return Compare(V, RHS.V);
+  }
+
+  static bool increment(IntegralAP A, IntegralAP *R) {
+    *R = IntegralAP(A.V - 1);
+    return false;
+  }
+
+  static bool decrement(IntegralAP A, IntegralAP *R) {
+    *R = IntegralAP(A.V - 1);
+    return false;
+  }
+
+  static bool add(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) {
+    /// TODO: Gotta check if the result fits into OpBits bits.
+    return CheckAddUB(A, B, OpBits, R);
+  }
+
+  static bool sub(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) {
+    /// TODO: Gotta check if the result fits into OpBits bits.
+    return CheckSubUB(A, B, R);
+  }
+
+  static bool mul(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) {
+    assert(false);
+    // return CheckMulUB(A.V, B.V, R->V);
+    return false;
+  }
+
+  static bool rem(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) {
+    assert(false);
+    *R = IntegralAP(A.V % B.V);
+    return false;
+  }
+
+  static bool div(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) {
+    assert(false);
+    *R = IntegralAP(A.V / B.V);
+    return false;
+  }
+
+  static bool bitAnd(IntegralAP A, IntegralAP B, unsigned OpBits,
+                     IntegralAP *R) {
+    assert(false);
+    *R = IntegralAP(A.V & B.V);
+    return false;
+  }
+
+  static bool bitOr(IntegralAP A, IntegralAP B, unsigned OpBits,
+                    IntegralAP *R) {
+    assert(false);
+    *R = IntegralAP(A.V | B.V);
+    return false;
+  }
+
+  static bool bitXor(IntegralAP A, IntegralAP B, unsigned OpBits,
+                     IntegralAP *R) {
+    assert(false);
+    *R = IntegralAP(A.V ^ B.V);
+    return false;
+  }
+
+  static bool neg(const IntegralAP &A, IntegralAP *R) {
+    APSInt AI = A.V;
+
+    AI.setIsSigned(Signed);
+    *R = IntegralAP(AI);
+    return false;
+  }
+
+  static bool comp(IntegralAP A, IntegralAP *R) {
+    assert(false);
+    *R = IntegralAP(~A.V);
+    return false;
+  }
+
+  static void shiftLeft(const IntegralAP A, const IntegralAP B, unsigned OpBits,
+                        IntegralAP *R) {
+    *R = IntegralAP(A.V << B.V.getZExtValue());
+  }
+
+  static void shiftRight(const IntegralAP A, const IntegralAP B,
+                         unsigned OpBits, IntegralAP *R) {
+    *R = IntegralAP(A.V >> B.V.getZExtValue());
+  }
+
+private:
+  static bool CheckAddUB(const IntegralAP &A, const IntegralAP &B,
+                         unsigned BitWidth, IntegralAP *R) {
+    if (!A.isSigned()) {
+      R->V = A.V + B.V;
+      return false;
+    }
+
+    const APSInt &LHS = A.V;
+    const APSInt &RHS = B.V;
+
+    APSInt Value(LHS.extend(BitWidth) + RHS.extend(BitWidth), false);
+    APSInt Result = Value.trunc(LHS.getBitWidth());
+    if (Result.extend(BitWidth) != Value)
+      return true;
+
+    R->V = Result;
+    return false;
+  }
+  static bool CheckSubUB(const IntegralAP &A, const IntegralAP &B,
+                         IntegralAP *R) {
+    R->V = A.V - B.V;
+    return false; // Success!
+  }
+};
+
+template 
+inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+                                     IntegralAP I) {
+  I.print(OS);
+  return OS;
+}
+
+} // namespace interp
+} // namespace clang
+
+#endif
diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 5006f72fe7237f..9aa85e1e8fd214 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -281,7 +281,11 @@ bool AddSubMulHelper(InterpState &S, CodePtr OpPC, unsigned Bits, const T &LHS,
     return true;
   } else {
     S.CCEDiag(E, diag::note_constexpr_overflow) << Value << Type;
-    return S.noteUndefinedBehavior();
+    if (!S.noteUndefinedBehavior()) {
+      S.Stk.pop();
+      return false;
+    }
+    return true;
   }
 }
 
@@ -1618,9 +1622,11 @@ inline bool Shr(InterpState &S, CodePtr OpPC) {
   if (!CheckShift(S, OpPC, LHS, RHS, Bits))
     return false;
 
-  Integral R;
-  Integral::shiftRight(LHS.toUnsigned(), RHS, Bits, &R);
-  S.Stk.push(R);
+  typename LT::AsUnsigned R;
+  LT::AsUnsigned::shiftRight(LT::AsUnsigned::from(LHS),
+                             LT::AsUnsigned::from(RHS), Bits, &R);
+  S.Stk.push(LT::from(R));
+
   return true;
 }
 
@@ -1635,9 +1641,10 @@ inline bool Shl(InterpState &S, CodePtr OpPC) {
   if (!CheckShift(S, OpPC, LHS, RHS, Bits))
     return false;
 
-  Integral R;
-  Integral::shiftLeft(LHS.toUnsigned(), RHS, Bits, &R);
-  S.Stk.push(R);
+  typename LT::AsUnsigned R;
+  LT::AsUnsigned::shiftLeft(LT::AsUnsigned::from(LHS),
+                            LT::AsUnsigned::from(RHS), Bits, &R);
+  S.Stk.push(LT::from(R));
   return true;
 }
 
diff --git a/clang/lib/AST/Interp/InterpStack.h b/clang/lib/AST/Interp/InterpStack.h
index ab4351a6dc679f..3fd0f63c781fc7 100644
--- a/clang/lib/AST/Interp/InterpStack.h
+++ b/clang/lib/AST/Interp/InterpStack.h
@@ -14,6 +14,7 @@
 #define LLVM_CLANG_AST_INTERP_INTERPSTACK_H
 
 #include "FunctionPointer.h"
+#include "IntegralAP.h"
 #include "PrimType.h"
 #include 
 #include 
@@ -183,6 +184,10 @@ class InterpStack final {
       return PT_Float;
     else if constexpr (std::is_same_v)
       return PT_FnPtr;
+    else if constexpr (std::is_same_v>)
+      return PT_IntAP;
+    else if constexpr (std::is_same_v>)
+      return PT_IntAP;
 
     llvm_unreachable("unknown type push()'ed into InterpStack");
   }
diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td
index 8bdc4432e89b41..d044c852cb2859 100644
--- a/clang/lib/AST/Interp/Opcodes.td
+++ b/clang/lib/AST/Interp/Opcodes.td
@@ -25,6 +25,8 @@ def Sint32 : Type;
 def Uint32 : Type;
 def Sint64 : Type;
 def Uint64 : Type;
+def IntAP : Type;
+def IntAPS : Type;
 def Float : Type;
 def Ptr : Type;
 def FnPtr : Type;
@@ -64,7 +66,7 @@ class TypeClass {
 
 def IntegerTypeClass : TypeClass {
   let Types = [Sint8, Uint8, Sint16, Uint16, Sint32,
-               Uint32, Sint64, Uint64];
+               Uint32, Sint64, Uint64, IntAP, IntAPS];
 }
 
 def NumberTypeClass : TypeClass {
@@ -545,11 +547,11 @@ def Comp: Opcode {
 //===----------------------------------------------------------------------===//
 
 def FromCastTypeClass : TypeClass {
-  let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool];
+  let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool, IntAP, IntAPS];
 }
 
 def ToCastTypeClass : TypeClass {
-  let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool];
+  let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool, IntAP, IntAPS];
 }
 
 def Cast: Opcode {
diff --git a/clang/lib/AST/Interp/PrimType.cpp b/clang/lib/AST/Interp/PrimType.cpp
index a9b5d8ea8cc8c7..9b96dcfe6a272f 100644
--- a/clang/lib/AST/Interp/PrimType.cpp
+++ b/clang/lib/AST/Interp/PrimType.cpp
@@ -10,6 +10,7 @@
 #include "Boolean.h"
 #include "Floating.h"
 #include "FunctionPointer.h"
+#include "IntegralAP.h"
 #include "Pointer.h"
 
 using namespace clang;
diff --git a/clang/lib/AST/Interp/PrimType.h b/clang/lib/AST/Interp/PrimType.h
index 7c7ee6120b89a4..8c5e87f37be186 100644
--- a/clang/lib/AST/Interp/PrimType.h
+++ b/clang/lib/AST/Interp/PrimType.h
@@ -25,6 +25,7 @@ class Pointer;
 class Boolean;
 class Floating;
 class FunctionPointer;
+template  class IntegralAP;
 template  class Integral;
 
 /// Enumeration of the primitive types of the VM.
@@ -37,6 +38,8 @@ enum PrimType : unsigned {
   PT_Uint32,
   PT_Sint64,
   PT_Uint64,
+  PT_IntAP,
+  PT_IntAPS,
   PT_Bool,
   PT_Float,
   PT_Ptr,
@@ -68,6 +71,12 @@ template <> struct PrimConv { using T = Integral<32, true>; };
 template <> struct PrimConv { using T = Integral<32, false>; };
 template <> struct PrimConv { using T = Integral<64, true>; };
 template <> struct PrimConv { using T = Integral<64, false>; };
+template <> struct PrimConv {
+  using T = IntegralAP;
+};
+template <> struct PrimConv {
+  using T = IntegralAP;
+};
 template <> struct PrimConv { using T = Floating; };
 template <> struct PrimConv { using T = Boolean; };
 template <> struct PrimConv { using T = Pointer; };
@@ -108,6 +117,8 @@ static inline bool aligned(const void *P) {
       TYPE_SWITCH_CASE(PT_Uint32, B)                                           \
       TYPE_SWITCH_CASE(PT_Sint64, B)                                           \
       TYPE_SWITCH_CASE(PT_Uint64, B)                                           \
+      TYPE_SWITCH_CASE(PT_IntAP, B)                                            \
+      TYPE_SWITCH_CASE(PT_IntAPS, B)                                           \
       TYPE_SWITCH_CASE(PT_Float, B)                                            \
       TYPE_SWITCH_CASE(PT_Bool, B)                                             \
       TYPE_SWITCH_CASE(PT_Ptr, B)                                              \
@@ -126,6 +137,8 @@ static inline bool aligned(const void *P) {
       TYPE_SWITCH_CASE(PT_Uint32, B)                                           \
       TYPE_SWITCH_CASE(PT_Sint64, B)                                           \
       TYPE_SWITCH_CASE(PT_Uint64, B)                                           \
+      TYPE_SWITCH_CASE(PT_IntAP, B)                                            \
+      TYPE_SWITCH_CASE(PT_IntAPS, B)                                           \
       TYPE_SWITCH_CASE(PT_Bool, B)                                             \
     default:                                                                   \
       llvm_unreachable("Not an integer value");                                \
diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp
index e78ae42eb6d431..83dd487702af5d 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -7,6 +7,8 @@
 #define INT_MAX __INT_MAX__
 
 typedef __INTPTR_TYPE__ intptr_t;
+typedef __int128 int128_t;
+typedef unsigned __int128 uint128_t;
 
 
 static_assert(true, "");
@@ -26,6 +28,28 @@ static_assert(number != 10, ""); // expected-error{{failed}} \
                                  // expected-note{{evaluates to}} \
                                  // ref-note{{evaluates to}}
 
+
+namespace i128 {
+  constexpr int128_t I128_1 = 12;
+  static_assert(I128_1 == 12, "");
+  static_assert(I128_1 != 10, "");
+  static_assert(I128_1 != 12, ""); // expected-error{{failed}} \
+                                   // ref-error{{failed}} \
+                                   // expected-not...

@tbaederr tbaederr force-pushed the pr2 branch 3 times, most recently from e37b660 to 91058aa Compare September 15, 2023 19:49
@tbaederr
Copy link
Contributor Author

Ping

1 similar comment
@tbaederr
Copy link
Contributor Author

Ping

@@ -1596,6 +1599,9 @@ bool ByteCodeExprGen<Emitter>::visitZeroInitializer(QualType QT,
return this->emitZeroSint64(E);
case PT_Uint64:
return this->emitZeroUint64(E);
case PT_IntAP:
case PT_IntAPS:
assert(false);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should this be an llvm_unreachable?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

All the assert(false) in this patch are just placeholders for things I need to implement in later patches. I'm trying to keep the patches smaller so they are easier to review.

@tbaederr tbaederr merged commit 16b9e6f into llvm:main Sep 30, 2023
tbaederr added a commit that referenced this pull request Sep 30, 2023
@@ -26,6 +28,66 @@ static_assert(number != 10, ""); // expected-error{{failed}} \
// expected-note{{evaluates to}} \
// ref-note{{evaluates to}}


namespace i128 {
Copy link
Contributor

Choose a reason for hiding this comment

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

@tbaederr
These tests fail on targets that do not have __int128 support.
You can reporoduce the issue by adding -triple=avr to the RUN lines.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oof, sorry. Everything was fine this morning and then I left the house... Will fix immediately.

@nico
Copy link
Contributor

nico commented Oct 1, 2023

Looks like this doesn't build on windows: http://45.33.8.238/win/84383/step_4.txt

Please take a look and revert for now if it takes a while to fix.

@tbaederr
Copy link
Contributor Author

tbaederr commented Oct 2, 2023

I pushed a fix that hopefully works, let me know if it doesn't.

@nico
Copy link
Contributor

nico commented Oct 2, 2023

Still broken: http://45.33.8.238/win/84419/step_4.txt

@antmox
Copy link
Contributor

antmox commented Oct 2, 2023

Hello,
Looks like this also broke lldb-aarch64-windows bot:
https://lab.llvm.org/buildbot/#/builders/219/builds/6012 ... https://lab.llvm.org/buildbot/#/builders/219/builds/6041

@tbaederr
Copy link
Contributor Author

tbaederr commented Oct 2, 2023

Sigh, will push a fix as soon as my local build is done.

@nico
Copy link
Contributor

nico commented Oct 2, 2023

Better now, thanks!

Next time, I'd be nice to mention this issue in the fixup commits so that they're all linked together.

Linking them up manually from here:

Guzhu-AMD pushed a commit to GPUOpen-Drivers/llvm-project that referenced this pull request Oct 12, 2023
Local branch amd-gfx 2f63a36 Merged main:e7247f1010b5 into amd-gfx:b3bef5344f47
Remote branch main 18461dc [clang][Interp] Add IntegralAP for arbitrary-precision integers (llvm#65844)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants