[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