[clang] c2a37e4 - [clang][bytecode] Implement fixed point casts (#110409)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Sep 28 23:58:24 PDT 2024
Author: Timm Baeder
Date: 2024-09-29T08:58:21+02:00
New Revision: c2a37e41b9f9f5e28339674dbdc656bc8a0bf708
URL: https://github.com/llvm/llvm-project/commit/c2a37e41b9f9f5e28339674dbdc656bc8a0bf708
DIFF: https://github.com/llvm/llvm-project/commit/c2a37e41b9f9f5e28339674dbdc656bc8a0bf708.diff
LOG: [clang][bytecode] Implement fixed point casts (#110409)
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 ef058e8da44b34..3a3ee3b577c29c 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -697,6 +697,14 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->getType());
return this->emitCastFixedPointFloating(TargetSemantics, CE);
}
+ case CK_FixedPointCast: {
+ if (!this->visit(SubExpr))
+ return false;
+ auto Sem = Ctx.getASTContext().getFixedPointSemantics(CE->getType());
+ uint32_t I;
+ std::memcpy(&I, &Sem, sizeof(Sem));
+ return this->emitCastFixedPoint(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 0a808e13eda4eb..0fb4576c721266 100644
--- a/clang/lib/AST/ByteCode/FixedPoint.h
+++ b/clang/lib/AST/ByteCode/FixedPoint.h
@@ -61,6 +61,11 @@ class FixedPoint final {
FixedPoint truncate(unsigned BitWidth) const { return *this; }
+ FixedPoint toSemantics(const llvm::FixedPointSemantics &Sem,
+ bool *Overflow) const {
+ return FixedPoint(V.convert(Sem, Overflow));
+ }
+
llvm::APFloat toFloat(const llvm::fltSemantics *Sem) const {
return V.convertToFloat(*Sem);
}
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 0a99d9440ff844..fd09deb87d4c51 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -2161,6 +2161,31 @@ inline bool CastFP(InterpState &S, CodePtr OpPC, const llvm::fltSemantics *Sem,
return true;
}
+inline bool CastFixedPoint(InterpState &S, CodePtr OpPC, uint32_t FPS) {
+ FixedPointSemantics TargetSemantics(0, 0, false, false, false);
+ std::memcpy(&TargetSemantics, &FPS, sizeof(TargetSemantics));
+
+ const auto &Source = S.Stk.pop<FixedPoint>();
+
+ bool Overflow;
+ FixedPoint Result = Source.toSemantics(TargetSemantics, &Overflow);
+
+ if (Overflow) {
+ const Expr *E = S.Current->getExpr(OpPC);
+ if (S.checkingForUndefinedBehavior()) {
+ S.getASTContext().getDiagnostics().Report(
+ E->getExprLoc(), diag::warn_fixedpoint_constant_overflow)
+ << Result.toDiagnosticString(S.getASTContext()) << E->getType();
+ }
+ S.CCEDiag(E, diag::note_constexpr_overflow) << Result << E->getType();
+ if (!S.noteUndefinedBehavior())
+ return false;
+ }
+
+ S.Stk.push<FixedPoint>(Result);
+ return true;
+}
+
/// Like Cast(), but we cast to an arbitrary-bitwidth integral, so we need
/// to know what bitwidth the result should be.
template <PrimType Name, class T = typename PrimConv<Name>::T>
diff --git a/clang/lib/AST/ByteCode/Opcodes.td b/clang/lib/AST/ByteCode/Opcodes.td
index ceea2accc22eff..2955bc5cf8084c 100644
--- a/clang/lib/AST/ByteCode/Opcodes.td
+++ b/clang/lib/AST/ByteCode/Opcodes.td
@@ -626,6 +626,10 @@ def CastFP : Opcode {
let Args = [ArgFltSemantics, ArgRoundingMode];
}
+def CastFixedPoint : Opcode {
+ let Args = [ArgUint32];
+}
+
def FixedSizeIntegralTypes : TypeClass {
let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool];
}
diff --git a/clang/test/AST/ByteCode/fixed-point.cpp b/clang/test/AST/ByteCode/fixed-point.cpp
index 03324c79fc9cae..dd360382e7ca21 100644
--- a/clang/test/AST/ByteCode/fixed-point.cpp
+++ b/clang/test/AST/ByteCode/fixed-point.cpp
@@ -47,3 +47,9 @@ namespace BinOps {
// ref-error {{is not an integral constant expression}} \
// ref-note {{is outside the range of representable values}}
}
+
+namespace FixedPointCasts {
+ constexpr _Fract B = 0.3;
+ constexpr _Accum A = B;
+ constexpr _Fract C = A;
+}
More information about the cfe-commits
mailing list