Author: Timm Baeder Date: 2024-09-03T14:24:11+02:00 New Revision: 0f5f440f24bc2af4e8ab481a99e03de438b12987
URL: https://github.com/llvm/llvm-project/commit/0f5f440f24bc2af4e8ab481a99e03de438b12987 DIFF: https://github.com/llvm/llvm-project/commit/0f5f440f24bc2af4e8ab481a99e03de438b12987.diff LOG: [clang][bytecode] Pass FPOptions to floating point ops (#107063) So we don't have to retrieve them from the InterpFrame, which is slow. Added: Modified: clang/lib/AST/ByteCode/Compiler.cpp clang/lib/AST/ByteCode/Compiler.h clang/lib/AST/ByteCode/Interp.cpp clang/lib/AST/ByteCode/Interp.h clang/lib/AST/ByteCode/Opcodes.td Removed: ################################################################################ diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 554e23e272e41c..a831f196abdcb5 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -298,8 +298,8 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) { return false; const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->getType()); - llvm::RoundingMode RM = getRoundingMode(CE); - return this->emitCastIntegralFloating(*FromT, TargetSemantics, RM, CE); + return this->emitCastIntegralFloating(*FromT, TargetSemantics, + getFPOptions(CE), CE); } case CK_FloatingToBoolean: @@ -317,12 +317,12 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) { if (ToT == PT_IntAP) return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(CE->getType()), - CE); + getFPOptions(CE), CE); if (ToT == PT_IntAPS) return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(CE->getType()), - CE); + getFPOptions(CE), CE); - return this->emitCastFloatingIntegral(*ToT, CE); + return this->emitCastFloatingIntegral(*ToT, getFPOptions(CE), CE); } case CK_NullToPointer: @@ -810,21 +810,21 @@ bool Compiler<Emitter>::VisitBinaryOperator(const BinaryOperator *BO) { return MaybeCastToBool(this->emitGE(*LT, BO)); case BO_Sub: if (BO->getType()->isFloatingType()) - return Discard(this->emitSubf(getRoundingMode(BO), BO)); + return Discard(this->emitSubf(getFPOptions(BO), BO)); return Discard(this->emitSub(*T, BO)); case BO_Add: if (BO->getType()->isFloatingType()) - return Discard(this->emitAddf(getRoundingMode(BO), BO)); + return Discard(this->emitAddf(getFPOptions(BO), BO)); return Discard(this->emitAdd(*T, BO)); case BO_Mul: if (BO->getType()->isFloatingType()) - return Discard(this->emitMulf(getRoundingMode(BO), BO)); + return Discard(this->emitMulf(getFPOptions(BO), BO)); return Discard(this->emitMul(*T, BO)); case BO_Rem: return Discard(this->emitRem(*T, BO)); case BO_Div: if (BO->getType()->isFloatingType()) - return Discard(this->emitDivf(getRoundingMode(BO), BO)); + return Discard(this->emitDivf(getFPOptions(BO), BO)); return Discard(this->emitDiv(*T, BO)); case BO_Assign: if (DiscardResult) @@ -1153,7 +1153,7 @@ bool Compiler<Emitter>::VisitComplexBinOp(const BinaryOperator *E) { if (!loadComplexValue(RHSIsComplex, true, ElemIndex, RHSOffset, RHS)) return false; if (ResultElemT == PT_Float) { - if (!this->emitAddf(getRoundingMode(E), E)) + if (!this->emitAddf(getFPOptions(E), E)) return false; } else { if (!this->emitAdd(ResultElemT, E)) @@ -1167,7 +1167,7 @@ bool Compiler<Emitter>::VisitComplexBinOp(const BinaryOperator *E) { if (!loadComplexValue(RHSIsComplex, true, ElemIndex, RHSOffset, RHS)) return false; if (ResultElemT == PT_Float) { - if (!this->emitSubf(getRoundingMode(E), E)) + if (!this->emitSubf(getFPOptions(E), E)) return false; } else { if (!this->emitSub(ResultElemT, E)) @@ -1182,7 +1182,7 @@ bool Compiler<Emitter>::VisitComplexBinOp(const BinaryOperator *E) { return false; if (ResultElemT == PT_Float) { - if (!this->emitMulf(getRoundingMode(E), E)) + if (!this->emitMulf(getFPOptions(E), E)) return false; } else { if (!this->emitMul(ResultElemT, E)) @@ -1198,7 +1198,7 @@ bool Compiler<Emitter>::VisitComplexBinOp(const BinaryOperator *E) { return false; if (ResultElemT == PT_Float) { - if (!this->emitDivf(getRoundingMode(E), E)) + if (!this->emitDivf(getFPOptions(E), E)) return false; } else { if (!this->emitDiv(ResultElemT, E)) @@ -2063,22 +2063,21 @@ bool Compiler<Emitter>::VisitFloatCompoundAssignOperator( if (!this->emitGetLocal(*RT, TempOffset, E)) return false; - llvm::RoundingMode RM = getRoundingMode(E); switch (E->getOpcode()) { case BO_AddAssign: - if (!this->emitAddf(RM, E)) + if (!this->emitAddf(getFPOptions(E), E)) return false; break; case BO_SubAssign: - if (!this->emitSubf(RM, E)) + if (!this->emitSubf(getFPOptions(E), E)) return false; break; case BO_MulAssign: - if (!this->emitMulf(RM, E)) + if (!this->emitMulf(getFPOptions(E), E)) return false; break; case BO_DivAssign: - if (!this->emitDivf(RM, E)) + if (!this->emitDivf(getFPOptions(E), E)) return false; break; default: @@ -3325,7 +3324,7 @@ template <class Emitter> bool Compiler<Emitter>::visitBool(const Expr *E) { // Or Floats. if (T == PT_Float) - return this->emitCastFloatingIntegralBool(E); + return this->emitCastFloatingIntegralBool(getFPOptions(E), E); // Or anything else we can. return this->emitCast(*T, PT_Bool, E); @@ -5005,8 +5004,8 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) { } if (T == PT_Float) { - return DiscardResult ? this->emitIncfPop(getRoundingMode(E), E) - : this->emitIncf(getRoundingMode(E), E); + return DiscardResult ? this->emitIncfPop(getFPOptions(E), E) + : this->emitIncf(getFPOptions(E), E); } return DiscardResult ? this->emitIncPop(*T, E) : this->emitInc(*T, E); @@ -5028,8 +5027,8 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) { } if (T == PT_Float) { - return DiscardResult ? this->emitDecfPop(getRoundingMode(E), E) - : this->emitDecf(getRoundingMode(E), E); + return DiscardResult ? this->emitDecfPop(getFPOptions(E), E) + : this->emitDecf(getFPOptions(E), E); } return DiscardResult ? this->emitDecPop(*T, E) : this->emitDec(*T, E); @@ -5056,7 +5055,7 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) { // Post-inc and pre-inc are the same if the value is to be discarded. if (DiscardResult) { if (T == PT_Float) - return this->emitIncfPop(getRoundingMode(E), E); + return this->emitIncfPop(getFPOptions(E), E); return this->emitIncPop(*T, E); } @@ -5066,7 +5065,7 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) { return false; if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E)) return false; - if (!this->emitAddf(getRoundingMode(E), E)) + if (!this->emitAddf(getFPOptions(E), E)) return false; if (!this->emitStoreFloat(E)) return false; @@ -5105,7 +5104,7 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) { // Post-dec and pre-dec are the same if the value is to be discarded. if (DiscardResult) { if (T == PT_Float) - return this->emitDecfPop(getRoundingMode(E), E); + return this->emitDecfPop(getFPOptions(E), E); return this->emitDecPop(*T, E); } @@ -5115,7 +5114,7 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) { return false; if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E)) return false; - if (!this->emitSubf(getRoundingMode(E), E)) + if (!this->emitSubf(getFPOptions(E), E)) return false; if (!this->emitStoreFloat(E)) return false; @@ -5579,13 +5578,15 @@ bool Compiler<Emitter>::emitPrimCast(PrimType FromT, PrimType ToT, } if (ToT == PT_IntAP) - return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT), E); + return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT), + getFPOptions(E), E); if (ToT == PT_IntAPS) - return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT), E); + return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT), + getFPOptions(E), E); // Float to integral. if (isIntegralType(ToT) || ToT == PT_Bool) - return this->emitCastFloatingIntegral(ToT, E); + return this->emitCastFloatingIntegral(ToT, getFPOptions(E), E); } if (isIntegralType(FromT) || FromT == PT_Bool) { @@ -5601,8 +5602,7 @@ bool Compiler<Emitter>::emitPrimCast(PrimType FromT, PrimType ToT, if (ToT == PT_Float) { // Integral to floating. const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT); - return this->emitCastIntegralFloating(FromT, ToSem, getRoundingMode(E), - E); + return this->emitCastIntegralFloating(FromT, ToSem, getFPOptions(E), E); } } @@ -5639,7 +5639,7 @@ bool Compiler<Emitter>::emitComplexBoolCast(const Expr *E) { if (!this->emitArrayElem(ElemT, 0, E)) return false; if (ElemT == PT_Float) { - if (!this->emitCastFloatingIntegral(PT_Bool, E)) + if (!this->emitCastFloatingIntegral(PT_Bool, getFPOptions(E), E)) return false; } else { if (!this->emitCast(ElemT, PT_Bool, E)) @@ -5654,7 +5654,7 @@ bool Compiler<Emitter>::emitComplexBoolCast(const Expr *E) { if (!this->emitArrayElemPop(ElemT, 1, E)) return false; if (ElemT == PT_Float) { - if (!this->emitCastFloatingIntegral(PT_Bool, E)) + if (!this->emitCastFloatingIntegral(PT_Bool, getFPOptions(E), E)) return false; } else { if (!this->emitCast(ElemT, PT_Bool, E)) diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h index 939cc0dae3546f..b18afacdb2e491 100644 --- a/clang/lib/AST/ByteCode/Compiler.h +++ b/clang/lib/AST/ByteCode/Compiler.h @@ -341,6 +341,10 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>, return FPO.getRoundingMode(); } + uint32_t getFPOptions(const Expr *E) const { + return E->getFPFeaturesInEffect(Ctx.getLangOpts()).getAsOpaqueInt(); + } + bool emitPrimCast(PrimType FromT, PrimType ToT, QualType ToQT, const Expr *E); PrimType classifyComplexElementType(QualType T) const { assert(T->isAnyComplexType()); diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index 30ccceb42eb374..8f57afcb4dc120 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -756,14 +756,13 @@ bool CheckPure(InterpState &S, CodePtr OpPC, const CXXMethodDecl *MD) { } bool CheckFloatResult(InterpState &S, CodePtr OpPC, const Floating &Result, - APFloat::opStatus Status) { - const SourceInfo &E = S.Current->getSource(OpPC); - + APFloat::opStatus Status, FPOptions FPO) { // [expr.pre]p4: // If during the evaluation of an expression, the result is not // mathematically defined [...], the behavior is undefined. // FIXME: C++ rules require us to not conform to IEEE 754 here. if (Result.isNan()) { + const SourceInfo &E = S.Current->getSource(OpPC); S.CCEDiag(E, diag::note_constexpr_float_arithmetic) << /*NaN=*/true << S.Current->getRange(OpPC); return S.noteUndefinedBehavior(); @@ -774,12 +773,11 @@ bool CheckFloatResult(InterpState &S, CodePtr OpPC, const Floating &Result, if (S.inConstantContext()) return true; - FPOptions FPO = E.asExpr()->getFPFeaturesInEffect(S.Ctx.getLangOpts()); - if ((Status & APFloat::opInexact) && FPO.getRoundingMode() == llvm::RoundingMode::Dynamic) { // Inexact result means that it depends on rounding mode. If the requested // mode is dynamic, the evaluation cannot be made in compile time. + const SourceInfo &E = S.Current->getSource(OpPC); S.FFDiag(E, diag::note_constexpr_dynamic_rounding); return false; } @@ -788,12 +786,14 @@ bool CheckFloatResult(InterpState &S, CodePtr OpPC, const Floating &Result, (FPO.getRoundingMode() == llvm::RoundingMode::Dynamic || FPO.getExceptionMode() != LangOptions::FPE_Ignore || FPO.getAllowFEnvAccess())) { + const SourceInfo &E = S.Current->getSource(OpPC); S.FFDiag(E, diag::note_constexpr_float_arithmetic_strict); return false; } if ((Status & APFloat::opStatus::opInvalidOp) && FPO.getExceptionMode() != LangOptions::FPE_Ignore) { + const SourceInfo &E = S.Current->getSource(OpPC); // There is no usefully definable result. S.FFDiag(E); return false; diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index c1423a060bcb97..e1d880060a0bac 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -246,7 +246,7 @@ bool CheckArraySize(InterpState &S, CodePtr OpPC, SizeT *NumElements, /// Checks if the result of a floating-point operation is valid /// in the current context. bool CheckFloatResult(InterpState &S, CodePtr OpPC, const Floating &Result, - APFloat::opStatus Status); + APFloat::opStatus Status, FPOptions FPO); /// Checks why the given DeclRefExpr is invalid. bool CheckDeclRef(InterpState &S, CodePtr OpPC, const DeclRefExpr *DR); @@ -376,14 +376,22 @@ bool Add(InterpState &S, CodePtr OpPC) { return AddSubMulHelper<T, T::add, std::plus>(S, OpPC, Bits, LHS, RHS); } -inline bool Addf(InterpState &S, CodePtr OpPC, llvm::RoundingMode RM) { +static inline llvm::RoundingMode getRoundingMode(FPOptions FPO) { + auto RM = FPO.getRoundingMode(); + if (RM == llvm::RoundingMode::Dynamic) + return llvm::RoundingMode::NearestTiesToEven; + return RM; +} + +inline bool Addf(InterpState &S, CodePtr OpPC, uint32_t FPOI) { const Floating &RHS = S.Stk.pop<Floating>(); const Floating &LHS = S.Stk.pop<Floating>(); + FPOptions FPO = FPOptions::getFromOpaqueInt(FPOI); Floating Result; - auto Status = Floating::add(LHS, RHS, RM, &Result); + auto Status = Floating::add(LHS, RHS, getRoundingMode(FPO), &Result); S.Stk.push<Floating>(Result); - return CheckFloatResult(S, OpPC, Result, Status); + return CheckFloatResult(S, OpPC, Result, Status, FPO); } template <PrimType Name, class T = typename PrimConv<Name>::T> @@ -394,14 +402,15 @@ bool Sub(InterpState &S, CodePtr OpPC) { return AddSubMulHelper<T, T::sub, std::minus>(S, OpPC, Bits, LHS, RHS); } -inline bool Subf(InterpState &S, CodePtr OpPC, llvm::RoundingMode RM) { +inline bool Subf(InterpState &S, CodePtr OpPC, uint32_t FPOI) { const Floating &RHS = S.Stk.pop<Floating>(); const Floating &LHS = S.Stk.pop<Floating>(); + FPOptions FPO = FPOptions::getFromOpaqueInt(FPOI); Floating Result; - auto Status = Floating::sub(LHS, RHS, RM, &Result); + auto Status = Floating::sub(LHS, RHS, getRoundingMode(FPO), &Result); S.Stk.push<Floating>(Result); - return CheckFloatResult(S, OpPC, Result, Status); + return CheckFloatResult(S, OpPC, Result, Status, FPO); } template <PrimType Name, class T = typename PrimConv<Name>::T> @@ -412,14 +421,15 @@ bool Mul(InterpState &S, CodePtr OpPC) { return AddSubMulHelper<T, T::mul, std::multiplies>(S, OpPC, Bits, LHS, RHS); } -inline bool Mulf(InterpState &S, CodePtr OpPC, llvm::RoundingMode RM) { +inline bool Mulf(InterpState &S, CodePtr OpPC, uint32_t FPOI) { const Floating &RHS = S.Stk.pop<Floating>(); const Floating &LHS = S.Stk.pop<Floating>(); + FPOptions FPO = FPOptions::getFromOpaqueInt(FPOI); Floating Result; - auto Status = Floating::mul(LHS, RHS, RM, &Result); + auto Status = Floating::mul(LHS, RHS, getRoundingMode(FPO), &Result); S.Stk.push<Floating>(Result); - return CheckFloatResult(S, OpPC, Result, Status); + return CheckFloatResult(S, OpPC, Result, Status, FPO); } template <PrimType Name, class T = typename PrimConv<Name>::T> @@ -647,17 +657,18 @@ bool Div(InterpState &S, CodePtr OpPC) { return false; } -inline bool Divf(InterpState &S, CodePtr OpPC, llvm::RoundingMode RM) { +inline bool Divf(InterpState &S, CodePtr OpPC, uint32_t FPOI) { const Floating &RHS = S.Stk.pop<Floating>(); const Floating &LHS = S.Stk.pop<Floating>(); if (!CheckDivRem(S, OpPC, LHS, RHS)) return false; + FPOptions FPO = FPOptions::getFromOpaqueInt(FPOI); Floating Result; - auto Status = Floating::div(LHS, RHS, RM, &Result); + auto Status = Floating::div(LHS, RHS, getRoundingMode(FPO), &Result); S.Stk.push<Floating>(Result); - return CheckFloatResult(S, OpPC, Result, Status); + return CheckFloatResult(S, OpPC, Result, Status, FPO); } //===----------------------------------------------------------------------===// @@ -822,54 +833,55 @@ bool DecPop(InterpState &S, CodePtr OpPC) { template <IncDecOp Op, PushVal DoPush> bool IncDecFloatHelper(InterpState &S, CodePtr OpPC, const Pointer &Ptr, - llvm::RoundingMode RM) { + uint32_t FPOI) { Floating Value = Ptr.deref<Floating>(); Floating Result; if constexpr (DoPush == PushVal::Yes) S.Stk.push<Floating>(Value); + FPOptions FPO = FPOptions::getFromOpaqueInt(FPOI); llvm::APFloat::opStatus Status; if constexpr (Op == IncDecOp::Inc) - Status = Floating::increment(Value, RM, &Result); + Status = Floating::increment(Value, getRoundingMode(FPO), &Result); else - Status = Floating::decrement(Value, RM, &Result); + Status = Floating::decrement(Value, getRoundingMode(FPO), &Result); Ptr.deref<Floating>() = Result; - return CheckFloatResult(S, OpPC, Result, Status); + return CheckFloatResult(S, OpPC, Result, Status, FPO); } -inline bool Incf(InterpState &S, CodePtr OpPC, llvm::RoundingMode RM) { +inline bool Incf(InterpState &S, CodePtr OpPC, uint32_t FPOI) { const Pointer &Ptr = S.Stk.pop<Pointer>(); if (!CheckLoad(S, OpPC, Ptr, AK_Increment)) return false; - return IncDecFloatHelper<IncDecOp::Inc, PushVal::Yes>(S, OpPC, Ptr, RM); + return IncDecFloatHelper<IncDecOp::Inc, PushVal::Yes>(S, OpPC, Ptr, FPOI); } -inline bool IncfPop(InterpState &S, CodePtr OpPC, llvm::RoundingMode RM) { +inline bool IncfPop(InterpState &S, CodePtr OpPC, uint32_t FPOI) { const Pointer &Ptr = S.Stk.pop<Pointer>(); if (!CheckLoad(S, OpPC, Ptr, AK_Increment)) return false; - return IncDecFloatHelper<IncDecOp::Inc, PushVal::No>(S, OpPC, Ptr, RM); + return IncDecFloatHelper<IncDecOp::Inc, PushVal::No>(S, OpPC, Ptr, FPOI); } -inline bool Decf(InterpState &S, CodePtr OpPC, llvm::RoundingMode RM) { +inline bool Decf(InterpState &S, CodePtr OpPC, uint32_t FPOI) { const Pointer &Ptr = S.Stk.pop<Pointer>(); if (!CheckLoad(S, OpPC, Ptr, AK_Decrement)) return false; - return IncDecFloatHelper<IncDecOp::Dec, PushVal::Yes>(S, OpPC, Ptr, RM); + return IncDecFloatHelper<IncDecOp::Dec, PushVal::Yes>(S, OpPC, Ptr, FPOI); } -inline bool DecfPop(InterpState &S, CodePtr OpPC, llvm::RoundingMode RM) { +inline bool DecfPop(InterpState &S, CodePtr OpPC, uint32_t FPOI) { const Pointer &Ptr = S.Stk.pop<Pointer>(); if (!CheckLoad(S, OpPC, Ptr, AK_Decrement)) return false; - return IncDecFloatHelper<IncDecOp::Dec, PushVal::No>(S, OpPC, Ptr, RM); + return IncDecFloatHelper<IncDecOp::Dec, PushVal::No>(S, OpPC, Ptr, FPOI); } /// 1) Pops the value from the stack. @@ -2126,20 +2138,21 @@ bool CastAPS(InterpState &S, CodePtr OpPC, uint32_t BitWidth) { template <PrimType Name, class T = typename PrimConv<Name>::T> bool CastIntegralFloating(InterpState &S, CodePtr OpPC, - const llvm::fltSemantics *Sem, - llvm::RoundingMode RM) { + const llvm::fltSemantics *Sem, uint32_t FPOI) { const T &From = S.Stk.pop<T>(); APSInt FromAP = From.toAPSInt(); Floating Result; - auto Status = Floating::fromIntegral(FromAP, *Sem, RM, Result); + FPOptions FPO = FPOptions::getFromOpaqueInt(FPOI); + auto Status = + Floating::fromIntegral(FromAP, *Sem, getRoundingMode(FPO), Result); S.Stk.push<Floating>(Result); - return CheckFloatResult(S, OpPC, Result, Status); + return CheckFloatResult(S, OpPC, Result, Status, FPO); } template <PrimType Name, class T = typename PrimConv<Name>::T> -bool CastFloatingIntegral(InterpState &S, CodePtr OpPC) { +bool CastFloatingIntegral(InterpState &S, CodePtr OpPC, uint32_t FPOI) { const Floating &F = S.Stk.pop<Floating>(); if constexpr (std::is_same_v<T, Boolean>) { @@ -2163,13 +2176,14 @@ bool CastFloatingIntegral(InterpState &S, CodePtr OpPC) { return false; } + FPOptions FPO = FPOptions::getFromOpaqueInt(FPOI); S.Stk.push<T>(T(Result)); - return CheckFloatResult(S, OpPC, F, Status); + return CheckFloatResult(S, OpPC, F, Status, FPO); } } static inline bool CastFloatingIntegralAP(InterpState &S, CodePtr OpPC, - uint32_t BitWidth) { + uint32_t BitWidth, uint32_t FPOI) { const Floating &F = S.Stk.pop<Floating>(); APSInt Result(BitWidth, /*IsUnsigned=*/true); @@ -2184,12 +2198,13 @@ static inline bool CastFloatingIntegralAP(InterpState &S, CodePtr OpPC, return S.noteUndefinedBehavior(); } + FPOptions FPO = FPOptions::getFromOpaqueInt(FPOI); S.Stk.push<IntegralAP<true>>(IntegralAP<true>(Result)); - return CheckFloatResult(S, OpPC, F, Status); + return CheckFloatResult(S, OpPC, F, Status, FPO); } static inline bool CastFloatingIntegralAPS(InterpState &S, CodePtr OpPC, - uint32_t BitWidth) { + uint32_t BitWidth, uint32_t FPOI) { const Floating &F = S.Stk.pop<Floating>(); APSInt Result(BitWidth, /*IsUnsigned=*/false); @@ -2204,8 +2219,9 @@ static inline bool CastFloatingIntegralAPS(InterpState &S, CodePtr OpPC, return S.noteUndefinedBehavior(); } + FPOptions FPO = FPOptions::getFromOpaqueInt(FPOI); S.Stk.push<IntegralAP<true>>(IntegralAP<true>(Result)); - return CheckFloatResult(S, OpPC, F, Status); + return CheckFloatResult(S, OpPC, F, Status, FPO); } 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 46247688d4ef85..67350abe5401e1 100644 --- a/clang/lib/AST/ByteCode/Opcodes.td +++ b/clang/lib/AST/ByteCode/Opcodes.td @@ -140,7 +140,7 @@ class AluOpcode : Opcode { } class FloatOpcode : Opcode { - let Args = [ArgRoundingMode]; + let Args = [ArgUint32]; } class IntegerOpcode : Opcode { @@ -642,23 +642,23 @@ def CastAPS : Opcode { // Cast an integer to a floating type def CastIntegralFloating : Opcode { let Types = [AluTypeClass]; - let Args = [ArgFltSemantics, ArgRoundingMode]; + let Args = [ArgFltSemantics, ArgUint32]; let HasGroup = 1; } // Cast a floating to an integer type def CastFloatingIntegral : Opcode { let Types = [FixedSizeIntegralTypes]; - let Args = []; + let Args = [ArgUint32]; let HasGroup = 1; } def CastFloatingIntegralAP : Opcode { - let Args = [ArgUint32]; + let Args = [ArgUint32, ArgUint32]; } def CastFloatingIntegralAPS : Opcode { - let Args = [ArgUint32]; + let Args = [ArgUint32, ArgUint32]; } def CastPointerIntegral : Opcode { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits