[clang] [clang][Interp] Implement inc/dec for IntegralAP (PR #69597)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 2 02:23:22 PDT 2023


Timm =?utf-8?q?Bäder?= <tbaeder at redhat.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/69597 at github.com>


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

>From 26780a13123c14763467c1b9de6b0cef3d92ff1c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Wed, 18 Oct 2023 15:36:13 +0200
Subject: [PATCH 1/2] [clang][Interp] Implement inc/dec for IntegralAP

---
 clang/lib/AST/Interp/IntegralAP.h | 23 ++++++------
 clang/test/AST/Interp/intap.cpp   | 62 +++++++++++++++++++++++++++----
 2 files changed, 67 insertions(+), 18 deletions(-)

diff --git a/clang/lib/AST/Interp/IntegralAP.h b/clang/lib/AST/Interp/IntegralAP.h
index 9aefea6d0c47ed9..234cfd74af452c7 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -119,8 +119,10 @@ template <bool Signed> class IntegralAP final {
 
   constexpr unsigned bitWidth() const { return V.getBitWidth(); }
 
-  APSInt toAPSInt(unsigned Bits = 0) const { return APSInt(V, Signed); }
-  APValue toAPValue() const { return APValue(APSInt(V, Signed)); }
+  APSInt toAPSInt(unsigned Bits = 0) const {
+    return APSInt(V, !Signed).extend((Bits > 0) ? Bits : bitWidth());
+  }
+  APValue toAPValue() const { return APValue(toAPSInt()); }
 
   bool isZero() const { return V.isZero(); }
   bool isPositive() const { return V.isNonNegative(); }
@@ -170,17 +172,13 @@ template <bool Signed> class IntegralAP final {
   }
 
   static bool increment(IntegralAP A, IntegralAP *R) {
-    // FIXME: Implement.
-    assert(false);
-    *R = IntegralAP(A.V - 1);
-    return false;
+    IntegralAP<Signed> One(1, A.bitWidth());
+    return add(A, One, A.bitWidth() + 1, R);
   }
 
   static bool decrement(IntegralAP A, IntegralAP *R) {
-    // FIXME: Implement.
-    assert(false);
-    *R = IntegralAP(A.V - 1);
-    return false;
+    IntegralAP<Signed> One(1, A.bitWidth());
+    return sub(A, One, A.bitWidth() + 1, R);
   }
 
   static bool add(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) {
@@ -249,7 +247,10 @@ template <bool Signed> class IntegralAP final {
 
   static void shiftRight(const IntegralAP A, const IntegralAP B,
                          unsigned OpBits, IntegralAP *R) {
-    *R = IntegralAP(A.V.ashr(B.V.getZExtValue()));
+    if constexpr (Signed)
+      *R = IntegralAP(A.V.ashr(B.V.getZExtValue()));
+    else
+      *R = IntegralAP(A.V.lshr(B.V.getZExtValue()));
   }
 
 private:
diff --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp
index 02a860eb0986c15..dbb9ff95193adbc 100644
--- a/clang/test/AST/Interp/intap.cpp
+++ b/clang/test/AST/Interp/intap.cpp
@@ -32,9 +32,17 @@ static_assert(BI1 == 3, "");
 
 
 #ifdef __SIZEOF_INT128__
+typedef __int128 int128_t;
+typedef unsigned __int128 uint128_t;
+static const __uint128_t UINT128_MAX =__uint128_t(__int128_t(-1L));
+static_assert(UINT128_MAX == -1, "");
+
+static const __int128_t INT128_MAX = UINT128_MAX >> (__int128_t)1;
+static_assert(INT128_MAX != 0, "");
+static const __int128_t INT128_MIN = -INT128_MAX - 1;
+
 namespace i128 {
-  typedef __int128 int128_t;
-  typedef unsigned __int128 uint128_t;
+
   constexpr int128_t I128_1 = 12;
   static_assert(I128_1 == 12, "");
   static_assert(I128_1 != 10, "");
@@ -43,12 +51,7 @@ namespace i128 {
                                    // expected-note{{evaluates to}} \
                                    // ref-note{{evaluates to}}
 
-  static const __uint128_t UINT128_MAX =__uint128_t(__int128_t(-1L));
-  static_assert(UINT128_MAX == -1, "");
 
-  static const __int128_t INT128_MAX = UINT128_MAX >> (__int128_t)1;
-  static_assert(INT128_MAX != 0, "");
-  static const __int128_t INT128_MIN = -INT128_MAX - 1;
   constexpr __int128 A = INT128_MAX + 1; // expected-error {{must be initialized by a constant expression}} \
                                          // expected-note {{outside the range}} \
                                          // ref-error {{must be initialized by a constant expression}} \
@@ -121,4 +124,49 @@ namespace AddSubOffset {
   static_assert(*P2 == 1,"");
 }
 
+namespace IncDec {
+#if 0
+  constexpr int128_t maxPlus1(bool Pre) {
+    int128_t a = INT128_MAX;
+
+    if (Pre)
+      ++a; // ref-note {{value 170141183460469231731687303715884105728 is outside the range}} \
+           // expected-note {{value 170141183460469231731687303715884105728 is outside the range}}
+    else
+      a++;
+    return a;
+  }
+  static_assert(maxPlus1(true) == 0, ""); // ref-error {{not an integral constant expression}} \
+                                          // ref-note in call to}} \
+                                          // expected-error {{not an integral constant expression}} \
+                                          // expected-note in call to}}
+  static_assert(maxPlus1(false) == 0, ""); // ref-error {{not an integral constant expression}} \
+                                           // ref-note in call to}} \
+                                           // expected-error {{not an integral constant expression}} \
+                                           // expected-note in call to}}
+
+  constexpr int128_t inc1(bool Pre) {
+    int128_t A = 0;
+    if (Pre)
+      ++A;
+    else
+      A++;
+    return A;
+  }
+  static_assert(inc1(true) == 1, "");
+  static_assert(inc1(false) == 1, "");
+
+  constexpr int128_t dec1(bool Pre) {
+    int128_t A = 2;
+    if (Pre)
+      --A;
+    else
+      A--;
+    return A;
+  }
+  static_assert(dec1(true) == 1, "");
+  static_assert(dec1(false) == 1, "");
+#endif
+}
+
 #endif

>From 1859ab4a987846af9b99d5d94a4462add1069029 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Thu, 2 Nov 2023 10:22:00 +0100
Subject: [PATCH 2/2] Fix up tests

---
 clang/test/AST/Interp/intap.cpp | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp
index dbb9ff95193adbc..fb742a6324fea8b 100644
--- a/clang/test/AST/Interp/intap.cpp
+++ b/clang/test/AST/Interp/intap.cpp
@@ -125,7 +125,7 @@ namespace AddSubOffset {
 }
 
 namespace IncDec {
-#if 0
+#if __cplusplus >= 201402L
   constexpr int128_t maxPlus1(bool Pre) {
     int128_t a = INT128_MAX;
 
@@ -133,17 +133,18 @@ namespace IncDec {
       ++a; // ref-note {{value 170141183460469231731687303715884105728 is outside the range}} \
            // expected-note {{value 170141183460469231731687303715884105728 is outside the range}}
     else
-      a++;
+      a++; // ref-note {{value 170141183460469231731687303715884105728 is outside the range}} \
+           // expected-note {{value 170141183460469231731687303715884105728 is outside the range}}
     return a;
   }
   static_assert(maxPlus1(true) == 0, ""); // ref-error {{not an integral constant expression}} \
-                                          // ref-note in call to}} \
+                                          // ref-note {{in call to}} \
                                           // expected-error {{not an integral constant expression}} \
-                                          // expected-note in call to}}
+                                          // expected-note {{in call to}}
   static_assert(maxPlus1(false) == 0, ""); // ref-error {{not an integral constant expression}} \
-                                           // ref-note in call to}} \
+                                           // ref-note {{in call to}} \
                                            // expected-error {{not an integral constant expression}} \
-                                           // expected-note in call to}}
+                                           // expected-note {{in call to}}
 
   constexpr int128_t inc1(bool Pre) {
     int128_t A = 0;



More information about the cfe-commits mailing list