[clang] 6cbd8a3 - [clang][bytecode] Implement floating-to-fixed-point casts (#110361)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Sep 28 08:24:31 PDT 2024
Author: Timm Baeder
Date: 2024-09-28T17:24:28+02:00
New Revision: 6cbd8a309485329a4fbfe7abf7b85e0b8f154561
URL: https://github.com/llvm/llvm-project/commit/6cbd8a309485329a4fbfe7abf7b85e0b8f154561
DIFF: https://github.com/llvm/llvm-project/commit/6cbd8a309485329a4fbfe7abf7b85e0b8f154561.diff
LOG: [clang][bytecode] Implement floating-to-fixed-point casts (#110361)
Added:
Modified:
clang/lib/AST/ByteCode/Compiler.cpp
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 a80d973056db43..40cb1b2dd80f96 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -682,6 +682,15 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
return this->emitCastIntegralFixedPoint(classifyPrim(SubExpr->getType()), I,
CE);
}
+ case CK_FloatingToFixedPoint: {
+ if (!this->visit(SubExpr))
+ return false;
+
+ auto Sem = Ctx.getASTContext().getFixedPointSemantics(CE->getType());
+ uint32_t I;
+ std::memcpy(&I, &Sem, sizeof(Sem));
+ return this->emitCastFloatingFixedPoint(I, CE);
+ }
case CK_ToVoid:
return discard(SubExpr);
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index f88233ed0f8f0a..23405765d8de82 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -2321,7 +2321,7 @@ static inline bool CastIntegralFixedPoint(InterpState &S, CodePtr OpPC,
std::memcpy(&Sem, &FPS, sizeof(Sem));
bool Overflow;
- llvm::APFixedPoint IntResult =
+ llvm::APFixedPoint Result =
llvm::APFixedPoint::getFromIntValue(Int.toAPSInt(), Sem, &Overflow);
if (Overflow) {
@@ -2329,14 +2329,41 @@ static inline bool CastIntegralFixedPoint(InterpState &S, CodePtr OpPC,
if (S.checkingForUndefinedBehavior()) {
S.getASTContext().getDiagnostics().Report(
E->getExprLoc(), diag::warn_fixedpoint_constant_overflow)
- << IntResult.toString() << E->getType();
+ << Result.toString() << E->getType();
}
- S.CCEDiag(E, diag::note_constexpr_overflow) << IntResult << E->getType();
+ S.CCEDiag(E, diag::note_constexpr_overflow) << Result << E->getType();
if (!S.noteUndefinedBehavior())
return false;
}
- S.Stk.push<FixedPoint>(IntResult);
+ S.Stk.push<FixedPoint>(Result);
+ return true;
+}
+
+static inline bool CastFloatingFixedPoint(InterpState &S, CodePtr OpPC,
+ uint32_t FPS) {
+ const auto &Float = S.Stk.pop<Floating>();
+
+ FixedPointSemantics Sem(0, 0, false, false, false);
+ std::memcpy(&Sem, &FPS, sizeof(Sem));
+
+ bool Overflow;
+ llvm::APFixedPoint Result =
+ llvm::APFixedPoint::getFromFloatValue(Float.getAPFloat(), 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)
+ << Result.toString() << E->getType();
+ }
+ S.CCEDiag(E, diag::note_constexpr_overflow) << Result << E->getType();
+ if (!S.noteUndefinedBehavior())
+ return false;
+ }
+
+ S.Stk.push<FixedPoint>(Result);
return true;
}
diff --git a/clang/lib/AST/ByteCode/Opcodes.td b/clang/lib/AST/ByteCode/Opcodes.td
index 65eb82080a2194..240e00e59d97ec 100644
--- a/clang/lib/AST/ByteCode/Opcodes.td
+++ b/clang/lib/AST/ByteCode/Opcodes.td
@@ -679,6 +679,9 @@ def CastIntegralFixedPoint : Opcode {
let Args = [ArgUint32];
let HasGroup = 1;
}
+def CastFloatingFixedPoint : Opcode {
+ let Args = [ArgUint32];
+}
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 51ea166748730c..76da06a02e150c 100644
--- a/clang/test/AST/ByteCode/fixed-point.cpp
+++ b/clang/test/AST/ByteCode/fixed-point.cpp
@@ -25,3 +25,10 @@ namespace IntToFixedPointCast {
static_assert(sf == -1.0k);
static_assert(sf == -1);
}
+
+namespace FloatToFixedPointCast {
+ constexpr _Fract sf = 1.0; // both-error {{must be initialized by a constant expression}} \
+ // both-note {{outside the range of representable values of type 'const _Fract'}}
+
+ constexpr _Fract sf2 = 0.5;
+}
More information about the cfe-commits
mailing list