Skip to content

Commit 641b4d5

Browse files
authored
[clang][bytecode] Implement integral-to-fixed-point casts (#110350)
1 parent 44478ba commit 641b4d5

File tree

5 files changed

+56
-1
lines changed

5 files changed

+56
-1
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,17 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
672672
ToSize, CE);
673673
};
674674

675+
case CK_IntegralToFixedPoint: {
676+
if (!this->visit(SubExpr))
677+
return false;
678+
679+
auto Sem = Ctx.getASTContext().getFixedPointSemantics(CE->getType());
680+
uint32_t I;
681+
std::memcpy(&I, &Sem, sizeof(Sem));
682+
return this->emitCastIntegralFixedPoint(classifyPrim(SubExpr->getType()), I,
683+
CE);
684+
}
685+
675686
case CK_ToVoid:
676687
return discard(SubExpr);
677688

clang/lib/AST/ByteCode/FixedPoint.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@ using APSInt = llvm::APSInt;
2323
class FixedPoint final {
2424
private:
2525
llvm::APFixedPoint V;
26-
FixedPoint(llvm::APFixedPoint &&V) : V(std::move(V)) {}
2726

2827
public:
28+
FixedPoint(llvm::APFixedPoint &&V) : V(std::move(V)) {}
29+
FixedPoint(llvm::APFixedPoint &V) : V(V) {}
2930
FixedPoint(APInt V, llvm::FixedPointSemantics Sem) : V(V, Sem) {}
3031
// This needs to be default-constructible so llvm::endian::read works.
3132
FixedPoint()

clang/lib/AST/ByteCode/Interp.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ namespace clang {
3838
namespace interp {
3939

4040
using APSInt = llvm::APSInt;
41+
using FixedPointSemantics = llvm::FixedPointSemantics;
4142

4243
/// Convert a value to an APValue.
4344
template <typename T>
@@ -2311,6 +2312,34 @@ static inline bool CastPointerIntegralAPS(InterpState &S, CodePtr OpPC,
23112312
return true;
23122313
}
23132314

2315+
template <PrimType Name, class T = typename PrimConv<Name>::T>
2316+
static inline bool CastIntegralFixedPoint(InterpState &S, CodePtr OpPC,
2317+
uint32_t FPS) {
2318+
const T &Int = S.Stk.pop<T>();
2319+
2320+
FixedPointSemantics Sem(0, 0, false, false, false);
2321+
std::memcpy(&Sem, &FPS, sizeof(Sem));
2322+
2323+
bool Overflow;
2324+
llvm::APFixedPoint IntResult =
2325+
llvm::APFixedPoint::getFromIntValue(Int.toAPSInt(), Sem, &Overflow);
2326+
2327+
if (Overflow) {
2328+
const Expr *E = S.Current->getExpr(OpPC);
2329+
if (S.checkingForUndefinedBehavior()) {
2330+
S.getASTContext().getDiagnostics().Report(
2331+
E->getExprLoc(), diag::warn_fixedpoint_constant_overflow)
2332+
<< IntResult.toString() << E->getType();
2333+
}
2334+
S.CCEDiag(E, diag::note_constexpr_overflow) << IntResult << E->getType();
2335+
if (!S.noteUndefinedBehavior())
2336+
return false;
2337+
}
2338+
2339+
S.Stk.push<FixedPoint>(IntResult);
2340+
return true;
2341+
}
2342+
23142343
static inline bool PtrPtrCast(InterpState &S, CodePtr OpPC, bool SrcIsVoidPtr) {
23152344
const auto &Ptr = S.Stk.peek<Pointer>();
23162345

clang/lib/AST/ByteCode/Opcodes.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,12 @@ def CastPointerIntegralAP : Opcode {
674674
def CastPointerIntegralAPS : Opcode {
675675
let Args = [ArgUint32];
676676
}
677+
def CastIntegralFixedPoint : Opcode {
678+
let Types = [FixedSizeIntegralTypes];
679+
let Args = [ArgUint32];
680+
let HasGroup = 1;
681+
}
682+
677683
def PtrPtrCast : Opcode {
678684
let Args = [ArgBool];
679685

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,11 @@ static_assert(-12.0k == -(-(-12.0k)));
1212
/// Zero-init.
1313
constexpr _Accum A{};
1414
static_assert(A == 0.0k);
15+
16+
namespace IntToFixedPointCast {
17+
constexpr _Accum B = 13;
18+
static_assert(B == 13.0k);
19+
20+
constexpr _Fract sf = -1;
21+
static_assert(sf == -1.0k);
22+
}

0 commit comments

Comments
 (0)