[clang] [clang][Interp] Support AddOffset with 128bit offsets (PR #68679)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 12 00:29:45 PDT 2023


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

>From 5fff64e74c885472abcd2a320d6db9005cc7c4fd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Tue, 10 Oct 2023 08:52:43 +0200
Subject: [PATCH] [clang][Interp] Support AddOffset with 128bit offsets

---
 clang/lib/AST/Interp/Integral.h   |  3 +++
 clang/lib/AST/Interp/IntegralAP.h |  3 +++
 clang/lib/AST/Interp/Interp.h     |  4 ++--
 clang/lib/AST/Interp/Opcodes.td   | 13 +++++++++----
 clang/test/AST/Interp/intap.cpp   |  9 +++++++++
 5 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/clang/lib/AST/Interp/Integral.h b/clang/lib/AST/Interp/Integral.h
index 4dbe9c9bcb14b43..cc1cab8f39fb1e5 100644
--- a/clang/lib/AST/Interp/Integral.h
+++ b/clang/lib/AST/Interp/Integral.h
@@ -88,6 +88,9 @@ template <unsigned Bits, bool Signed> class Integral final {
   }
 
   Integral operator-() const { return Integral(-V); }
+  Integral operator-(const Integral &Other) const {
+    return Integral(V - Other.V);
+  }
   Integral operator~() const { return Integral(~V); }
 
   template <unsigned DstBits, bool DstSign>
diff --git a/clang/lib/AST/Interp/IntegralAP.h b/clang/lib/AST/Interp/IntegralAP.h
index a8df431bef11784..f7e69da5689df4e 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -55,6 +55,9 @@ template <bool Signed> class IntegralAP final {
   IntegralAP() : V(APSInt::getMaxValue(1024, Signed)) {}
 
   IntegralAP operator-() const { return IntegralAP(-V); }
+  IntegralAP operator-(const IntegralAP &Other) const {
+    return IntegralAP(V - Other.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; }
diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 47dc1d08c9c4d8b..b730ed9fcc445a4 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1421,7 +1421,7 @@ bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset,
   // Get a version of the index comparable to the type.
   T Index = T::from(Ptr.getIndex(), Offset.bitWidth());
   // Compute the largest index into the array.
-  unsigned MaxIndex = Ptr.getNumElems();
+  T MaxIndex = T::from(Ptr.getNumElems(), Offset.bitWidth());
 
   // Helper to report an invalid offset, computed as APSInt.
   auto InvalidOffset = [&]() {
@@ -1437,7 +1437,7 @@ bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset,
     return false;
   };
 
-  unsigned MaxOffset = MaxIndex - Ptr.getIndex();
+  T MaxOffset = T::from(MaxIndex - Index, Offset.bitWidth());
   if constexpr (Op == ArithOp::Add) {
     // If the new offset would be negative, bail out.
     if (Offset.isNegative() && (Offset.isMin() || -Offset > Index))
diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td
index 50b6c0ac154de30..54f0a2bc43a845a 100644
--- a/clang/lib/AST/Interp/Opcodes.td
+++ b/clang/lib/AST/Interp/Opcodes.td
@@ -128,6 +128,11 @@ class AluOpcode : Opcode {
   let HasGroup = 1;
 }
 
+class OffsetOpcode : Opcode {
+  let Types = [IntegerTypeClass];
+  let HasGroup = 1;
+}
+
 class FloatOpcode : Opcode {
   let Types = [];
   let Args = [ArgRoundingMode];
@@ -338,8 +343,8 @@ def NarrowPtr : Opcode;
 // [Pointer] -> [Pointer]
 def ExpandPtr : Opcode;
 // [Pointer, Offset] -> [Pointer]
-def ArrayElemPtr : AluOpcode;
-def ArrayElemPtrPop : AluOpcode;
+def ArrayElemPtr : OffsetOpcode;
+def ArrayElemPtrPop : OffsetOpcode;
 
 //===----------------------------------------------------------------------===//
 // Direct field accessors
@@ -465,9 +470,9 @@ def InitElemPop : Opcode {
 //===----------------------------------------------------------------------===//
 
 // [Pointer, Integral] -> [Pointer]
-def AddOffset : AluOpcode;
+def AddOffset : OffsetOpcode;
 // [Pointer, Integral] -> [Pointer]
-def SubOffset : AluOpcode;
+def SubOffset : OffsetOpcode;
 
 // [Pointer, Pointer] -> [Integral]
 def SubPtr : Opcode {
diff --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp
index b3f02d2b769531d..e9e68438bb597aa 100644
--- a/clang/test/AST/Interp/intap.cpp
+++ b/clang/test/AST/Interp/intap.cpp
@@ -76,6 +76,15 @@ namespace i128 {
                                            // expected-note {{is outside the range of representable values of type}}
 }
 
+namespace AddSubOffset {
+  constexpr __int128 A = 1;
+  constexpr int arr[] = {1,2,3};
+  constexpr const int *P = arr + A;
+  static_assert(*P == 2, "");
+  constexpr const int *P2 = P - A;
+  static_assert(*P2 == 1,"");
+}
+
 #else
 /// No int128 support, so no expected directives.
 



More information about the cfe-commits mailing list