[clang] [clang][Interp] IntegralAP zero-init (PR #68081)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 18 05:37:20 PDT 2023


https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/68081

>From d6b0b306353fb2d8eaef6835f6313277eaf94bbd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Tue, 3 Oct 2023 11:05:27 +0200
Subject: [PATCH] [clang][Interp] IntegralAP zero-init

---
 clang/lib/AST/Interp/ByteCodeExprGen.cpp |  4 ++--
 clang/lib/AST/Interp/IntegralAP.h        | 11 ++++++-----
 clang/lib/AST/Interp/Interp.h            | 10 ++++++++++
 clang/lib/AST/Interp/Opcodes.td          | 15 ++++++++++++++-
 clang/test/AST/Interp/intap.cpp          | 15 +++++++++++++++
 5 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index e9e20b222d5d34f..d9389e7b0033191 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1665,9 +1665,9 @@ bool ByteCodeExprGen<Emitter>::visitZeroInitializer(PrimType T, QualType QT,
   case PT_Uint64:
     return this->emitZeroUint64(E);
   case PT_IntAP:
+    return this->emitZeroIntAP(Ctx.getBitWidth(QT), E);
   case PT_IntAPS:
-    assert(false);
-    return false;
+    return this->emitZeroIntAPS(Ctx.getBitWidth(QT), E);
   case PT_Ptr:
     return this->emitNullPtr(E);
   case PT_FnPtr:
diff --git a/clang/lib/AST/Interp/IntegralAP.h b/clang/lib/AST/Interp/IntegralAP.h
index fd120944a25043e..ebf362238ba09d5 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -78,7 +78,8 @@ template <bool Signed> class IntegralAP final {
 
   template <typename T> static IntegralAP from(T Value, unsigned NumBits = 0) {
     assert(NumBits > 0);
-    APSInt Copy = APSInt(APInt(NumBits, static_cast<int64_t>(Value), Signed), !Signed);
+    APSInt Copy =
+        APSInt(APInt(NumBits, static_cast<uint64_t>(Value), Signed), !Signed);
 
     return IntegralAP<Signed>(Copy);
   }
@@ -97,16 +98,16 @@ template <bool Signed> class IntegralAP final {
   template <unsigned Bits, bool InputSigned>
   static IntegralAP from(Integral<Bits, InputSigned> I, unsigned BitWidth) {
     APSInt Copy =
-        APSInt(APInt(BitWidth, static_cast<int64_t>(I), InputSigned), !Signed);
+        APSInt(APInt(BitWidth, static_cast<uint64_t>(I), InputSigned), !Signed);
     Copy.setIsSigned(Signed);
 
     assert(Copy.isSigned() == Signed);
     return IntegralAP<Signed>(Copy);
   }
 
-  static IntegralAP zero() {
-    assert(false);
-    return IntegralAP(0);
+  static IntegralAP zero(int32_t BitWidth) {
+    APSInt V = APSInt(APInt(BitWidth, 0LL, Signed), !Signed);
+    return IntegralAP(V);
   }
 
   constexpr unsigned bitWidth() const { return V.getBitWidth(); }
diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 3d226a40f9cf608..4b081301655cfb2 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1688,6 +1688,16 @@ bool Zero(InterpState &S, CodePtr OpPC) {
   return true;
 }
 
+static inline bool ZeroIntAP(InterpState &S, CodePtr OpPC, uint32_t BitWidth) {
+  S.Stk.push<IntegralAP<false>>(IntegralAP<false>::zero(BitWidth));
+  return true;
+}
+
+static inline bool ZeroIntAPS(InterpState &S, CodePtr OpPC, uint32_t BitWidth) {
+  S.Stk.push<IntegralAP<true>>(IntegralAP<true>::zero(BitWidth));
+  return true;
+}
+
 template <PrimType Name, class T = typename PrimConv<Name>::T>
 inline bool Null(InterpState &S, CodePtr OpPC) {
   S.Stk.push<T>();
diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td
index 9d390fed152417f..e1e7e5e2efbb059 100644
--- a/clang/lib/AST/Interp/Opcodes.td
+++ b/clang/lib/AST/Interp/Opcodes.td
@@ -72,6 +72,11 @@ def IntegerTypeClass : TypeClass {
                Uint32, Sint64, Uint64, IntAP, IntAPS];
 }
 
+def FixedSizeIntegralTypeClass : TypeClass {
+  let Types = [Sint8, Uint8, Sint16, Uint16, Sint32,
+               Uint32, Sint64, Uint64, Bool];
+}
+
 def NumberTypeClass : TypeClass {
   let Types = !listconcat(IntegerTypeClass.Types, [Float]);
 }
@@ -243,10 +248,18 @@ def ConstBool : ConstOpcode<Bool, ArgBool>;
 
 // [] -> [Integer]
 def Zero : Opcode {
-  let Types = [AluTypeClass];
+  let Types = [FixedSizeIntegralTypeClass];
   let HasGroup = 1;
 }
 
+def ZeroIntAP : Opcode {
+  let Args = [ArgUint32];
+}
+
+def ZeroIntAPS : Opcode {
+  let Args = [ArgUint32];
+}
+
 // [] -> [Pointer]
 def Null : Opcode {
   let Types = [PtrTypeClass];
diff --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp
index ef7a0d4f0dfdab0..27fae1b904351ce 100644
--- a/clang/test/AST/Interp/intap.cpp
+++ b/clang/test/AST/Interp/intap.cpp
@@ -17,6 +17,16 @@ constexpr MaxBitInt A_ = 0;
 constexpr MaxBitInt B_ = A_ + 1;
 static_assert(B_ == 1, "");
 
+constexpr MaxBitInt BitIntZero{};
+static_assert(BitIntZero == 0, "");
+constexpr unsigned _BitInt(128) UBitIntZero{};
+static_assert(UBitIntZero == 0, "");
+
+constexpr _BitInt(2) BitIntZero2{};
+static_assert(BitIntZero2 == 0, "");
+constexpr unsigned _BitInt(1) UBitIntZero1{};
+static_assert(UBitIntZero1 == 0, "");
+
 
 #ifdef __SIZEOF_INT128__
 namespace i128 {
@@ -49,6 +59,11 @@ namespace i128 {
   constexpr uint128_t AllOnes = ~static_cast<uint128_t>(0);
   static_assert(AllOnes == UINT128_MAX, "");
 
+  constexpr uint128_t i128Zero{};
+  static_assert(i128Zero == 0, "");
+  constexpr uint128_t ui128Zero{};
+  static_assert(ui128Zero == 0, "");
+
 #if __cplusplus >= 201402L
   template <typename T>
   constexpr T CastFrom(__int128_t A) {



More information about the cfe-commits mailing list