Skip to content

Commit 6cbd8a3

Browse files
authored
[clang][bytecode] Implement floating-to-fixed-point casts (#110361)
1 parent 29d0a84 commit 6cbd8a3

File tree

4 files changed

+50
-4
lines changed

4 files changed

+50
-4
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,15 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
682682
return this->emitCastIntegralFixedPoint(classifyPrim(SubExpr->getType()), I,
683683
CE);
684684
}
685+
case CK_FloatingToFixedPoint: {
686+
if (!this->visit(SubExpr))
687+
return false;
688+
689+
auto Sem = Ctx.getASTContext().getFixedPointSemantics(CE->getType());
690+
uint32_t I;
691+
std::memcpy(&I, &Sem, sizeof(Sem));
692+
return this->emitCastFloatingFixedPoint(I, CE);
693+
}
685694

686695
case CK_ToVoid:
687696
return discard(SubExpr);

clang/lib/AST/ByteCode/Interp.h

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2321,22 +2321,49 @@ static inline bool CastIntegralFixedPoint(InterpState &S, CodePtr OpPC,
23212321
std::memcpy(&Sem, &FPS, sizeof(Sem));
23222322

23232323
bool Overflow;
2324-
llvm::APFixedPoint IntResult =
2324+
llvm::APFixedPoint Result =
23252325
llvm::APFixedPoint::getFromIntValue(Int.toAPSInt(), Sem, &Overflow);
23262326

23272327
if (Overflow) {
23282328
const Expr *E = S.Current->getExpr(OpPC);
23292329
if (S.checkingForUndefinedBehavior()) {
23302330
S.getASTContext().getDiagnostics().Report(
23312331
E->getExprLoc(), diag::warn_fixedpoint_constant_overflow)
2332-
<< IntResult.toString() << E->getType();
2332+
<< Result.toString() << E->getType();
23332333
}
2334-
S.CCEDiag(E, diag::note_constexpr_overflow) << IntResult << E->getType();
2334+
S.CCEDiag(E, diag::note_constexpr_overflow) << Result << E->getType();
23352335
if (!S.noteUndefinedBehavior())
23362336
return false;
23372337
}
23382338

2339-
S.Stk.push<FixedPoint>(IntResult);
2339+
S.Stk.push<FixedPoint>(Result);
2340+
return true;
2341+
}
2342+
2343+
static inline bool CastFloatingFixedPoint(InterpState &S, CodePtr OpPC,
2344+
uint32_t FPS) {
2345+
const auto &Float = S.Stk.pop<Floating>();
2346+
2347+
FixedPointSemantics Sem(0, 0, false, false, false);
2348+
std::memcpy(&Sem, &FPS, sizeof(Sem));
2349+
2350+
bool Overflow;
2351+
llvm::APFixedPoint Result =
2352+
llvm::APFixedPoint::getFromFloatValue(Float.getAPFloat(), Sem, &Overflow);
2353+
2354+
if (Overflow) {
2355+
const Expr *E = S.Current->getExpr(OpPC);
2356+
if (S.checkingForUndefinedBehavior()) {
2357+
S.getASTContext().getDiagnostics().Report(
2358+
E->getExprLoc(), diag::warn_fixedpoint_constant_overflow)
2359+
<< Result.toString() << E->getType();
2360+
}
2361+
S.CCEDiag(E, diag::note_constexpr_overflow) << Result << E->getType();
2362+
if (!S.noteUndefinedBehavior())
2363+
return false;
2364+
}
2365+
2366+
S.Stk.push<FixedPoint>(Result);
23402367
return true;
23412368
}
23422369

clang/lib/AST/ByteCode/Opcodes.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,9 @@ def CastIntegralFixedPoint : Opcode {
679679
let Args = [ArgUint32];
680680
let HasGroup = 1;
681681
}
682+
def CastFloatingFixedPoint : Opcode {
683+
let Args = [ArgUint32];
684+
}
682685

683686
def PtrPtrCast : Opcode {
684687
let Args = [ArgBool];

clang/test/AST/ByteCode/fixed-point.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,10 @@ namespace IntToFixedPointCast {
2525
static_assert(sf == -1.0k);
2626
static_assert(sf == -1);
2727
}
28+
29+
namespace FloatToFixedPointCast {
30+
constexpr _Fract sf = 1.0; // both-error {{must be initialized by a constant expression}} \
31+
// both-note {{outside the range of representable values of type 'const _Fract'}}
32+
33+
constexpr _Fract sf2 = 0.5;
34+
}

0 commit comments

Comments
 (0)