[clang] 641b4d5 - [clang][bytecode] Implement integral-to-fixed-point casts (#110350)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Sep 28 04:10:27 PDT 2024
Author: Timm Baeder
Date: 2024-09-28T13:10:23+02:00
New Revision: 641b4d5370f1ce2f5d448cf63519f391be1cf263
URL: https://github.com/llvm/llvm-project/commit/641b4d5370f1ce2f5d448cf63519f391be1cf263
DIFF: https://github.com/llvm/llvm-project/commit/641b4d5370f1ce2f5d448cf63519f391be1cf263.diff
LOG: [clang][bytecode] Implement integral-to-fixed-point casts (#110350)
Added:
Modified:
clang/lib/AST/ByteCode/Compiler.cpp
clang/lib/AST/ByteCode/FixedPoint.h
clang/lib/AST/ByteCode/Interp.h
clang/lib/AST/ByteCode/Opcodes.td
clang/test/AST/ByteCode/fixed-point.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 2520fe30547b23..8875fc05d24bee 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -672,6 +672,17 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
ToSize, CE);
};
+ case CK_IntegralToFixedPoint: {
+ if (!this->visit(SubExpr))
+ return false;
+
+ auto Sem = Ctx.getASTContext().getFixedPointSemantics(CE->getType());
+ uint32_t I;
+ std::memcpy(&I, &Sem, sizeof(Sem));
+ return this->emitCastIntegralFixedPoint(classifyPrim(SubExpr->getType()), I,
+ CE);
+ }
+
case CK_ToVoid:
return discard(SubExpr);
diff --git a/clang/lib/AST/ByteCode/FixedPoint.h b/clang/lib/AST/ByteCode/FixedPoint.h
index 9dd300c3dbf6df..daa62945346aeb 100644
--- a/clang/lib/AST/ByteCode/FixedPoint.h
+++ b/clang/lib/AST/ByteCode/FixedPoint.h
@@ -23,9 +23,10 @@ using APSInt = llvm::APSInt;
class FixedPoint final {
private:
llvm::APFixedPoint V;
- FixedPoint(llvm::APFixedPoint &&V) : V(std::move(V)) {}
public:
+ FixedPoint(llvm::APFixedPoint &&V) : V(std::move(V)) {}
+ FixedPoint(llvm::APFixedPoint &V) : V(V) {}
FixedPoint(APInt V, llvm::FixedPointSemantics Sem) : V(V, Sem) {}
// This needs to be default-constructible so llvm::endian::read works.
FixedPoint()
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 79af426f8a913f..f88233ed0f8f0a 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -38,6 +38,7 @@ namespace clang {
namespace interp {
using APSInt = llvm::APSInt;
+using FixedPointSemantics = llvm::FixedPointSemantics;
/// Convert a value to an APValue.
template <typename T>
@@ -2311,6 +2312,34 @@ static inline bool CastPointerIntegralAPS(InterpState &S, CodePtr OpPC,
return true;
}
+template <PrimType Name, class T = typename PrimConv<Name>::T>
+static inline bool CastIntegralFixedPoint(InterpState &S, CodePtr OpPC,
+ uint32_t FPS) {
+ const T &Int = S.Stk.pop<T>();
+
+ FixedPointSemantics Sem(0, 0, false, false, false);
+ std::memcpy(&Sem, &FPS, sizeof(Sem));
+
+ bool Overflow;
+ llvm::APFixedPoint IntResult =
+ llvm::APFixedPoint::getFromIntValue(Int.toAPSInt(), Sem, &Overflow);
+
+ if (Overflow) {
+ const Expr *E = S.Current->getExpr(OpPC);
+ if (S.checkingForUndefinedBehavior()) {
+ S.getASTContext().getDiagnostics().Report(
+ E->getExprLoc(), diag::warn_fixedpoint_constant_overflow)
+ << IntResult.toString() << E->getType();
+ }
+ S.CCEDiag(E, diag::note_constexpr_overflow) << IntResult << E->getType();
+ if (!S.noteUndefinedBehavior())
+ return false;
+ }
+
+ S.Stk.push<FixedPoint>(IntResult);
+ return true;
+}
+
static inline bool PtrPtrCast(InterpState &S, CodePtr OpPC, bool SrcIsVoidPtr) {
const auto &Ptr = S.Stk.peek<Pointer>();
diff --git a/clang/lib/AST/ByteCode/Opcodes.td b/clang/lib/AST/ByteCode/Opcodes.td
index 5fdafd1bf81984..65eb82080a2194 100644
--- a/clang/lib/AST/ByteCode/Opcodes.td
+++ b/clang/lib/AST/ByteCode/Opcodes.td
@@ -674,6 +674,12 @@ def CastPointerIntegralAP : Opcode {
def CastPointerIntegralAPS : Opcode {
let Args = [ArgUint32];
}
+def CastIntegralFixedPoint : Opcode {
+ let Types = [FixedSizeIntegralTypes];
+ let Args = [ArgUint32];
+ let HasGroup = 1;
+}
+
def PtrPtrCast : Opcode {
let Args = [ArgBool];
diff --git a/clang/test/AST/ByteCode/fixed-point.cpp b/clang/test/AST/ByteCode/fixed-point.cpp
index bf1bd41783448f..77000c08918256 100644
--- a/clang/test/AST/ByteCode/fixed-point.cpp
+++ b/clang/test/AST/ByteCode/fixed-point.cpp
@@ -12,3 +12,11 @@ static_assert(-12.0k == -(-(-12.0k)));
/// Zero-init.
constexpr _Accum A{};
static_assert(A == 0.0k);
+
+namespace IntToFixedPointCast {
+ constexpr _Accum B = 13;
+ static_assert(B == 13.0k);
+
+ constexpr _Fract sf = -1;
+ static_assert(sf == -1.0k);
+}
More information about the cfe-commits
mailing list