[clang] [clang][bytecode] Pass FPOptions to floating point ops (PR #107063)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 3 02:07:44 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Timm Baeder (tbaederr)
<details>
<summary>Changes</summary>
So we don't have to retrieve them from the InterpFrame, which is slow.
---
Patch is 22.64 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/107063.diff
5 Files Affected:
- (modified) clang/lib/AST/ByteCode/Compiler.cpp (+34-34)
- (modified) clang/lib/AST/ByteCode/Compiler.h (+4)
- (modified) clang/lib/AST/ByteCode/Interp.cpp (+5-5)
- (modified) clang/lib/AST/ByteCode/Interp.h (+44-35)
- (modified) clang/lib/AST/ByteCode/Opcodes.td (+5-5)
``````````diff
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..2580e81094b1c0 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,15 @@ 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) {
+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, FPO.getRoundingMode(), &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 +395,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, FPO.getRoundingMode(), &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 +414,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, FPO.getRoundingMode(), &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 +650,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, FPO.getRoundingMode(), &Result);
S.Stk.push<Floating>(Result);
- return CheckFloatResult(S, OpPC, Result, Status);
+ return CheckFloatResult(S, OpPC, Result, Status, FPO);
}
//===----------------------------------------------------------------------===//
@@ -822,54 +826,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, FPO.getRoundingMode(), &Result);
else
- Status = Floating::decrement(Value, RM, &Result);
+ Status = Floating::decrement(Value, FPO.getRoundingMode(), &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 +2131,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, FPO.getRoundingMode(), 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 +2169,14 @@ bool CastFloatingIntegral(InterpState &S, CodePtr OpPC) {
return false;
}
+ FPOptions F...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/107063
More information about the cfe-commits
mailing list