Skip to content

Commit 0f5f440

Browse files
authored
[clang][bytecode] Pass FPOptions to floating point ops (#107063)
So we don't have to retrieve them from the InterpFrame, which is slow.
1 parent f77f604 commit 0f5f440

File tree

5 files changed

+99
-79
lines changed

5 files changed

+99
-79
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -298,8 +298,8 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
298298
return false;
299299

300300
const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->getType());
301-
llvm::RoundingMode RM = getRoundingMode(CE);
302-
return this->emitCastIntegralFloating(*FromT, TargetSemantics, RM, CE);
301+
return this->emitCastIntegralFloating(*FromT, TargetSemantics,
302+
getFPOptions(CE), CE);
303303
}
304304

305305
case CK_FloatingToBoolean:
@@ -317,12 +317,12 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
317317

318318
if (ToT == PT_IntAP)
319319
return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(CE->getType()),
320-
CE);
320+
getFPOptions(CE), CE);
321321
if (ToT == PT_IntAPS)
322322
return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(CE->getType()),
323-
CE);
323+
getFPOptions(CE), CE);
324324

325-
return this->emitCastFloatingIntegral(*ToT, CE);
325+
return this->emitCastFloatingIntegral(*ToT, getFPOptions(CE), CE);
326326
}
327327

328328
case CK_NullToPointer:
@@ -810,21 +810,21 @@ bool Compiler<Emitter>::VisitBinaryOperator(const BinaryOperator *BO) {
810810
return MaybeCastToBool(this->emitGE(*LT, BO));
811811
case BO_Sub:
812812
if (BO->getType()->isFloatingType())
813-
return Discard(this->emitSubf(getRoundingMode(BO), BO));
813+
return Discard(this->emitSubf(getFPOptions(BO), BO));
814814
return Discard(this->emitSub(*T, BO));
815815
case BO_Add:
816816
if (BO->getType()->isFloatingType())
817-
return Discard(this->emitAddf(getRoundingMode(BO), BO));
817+
return Discard(this->emitAddf(getFPOptions(BO), BO));
818818
return Discard(this->emitAdd(*T, BO));
819819
case BO_Mul:
820820
if (BO->getType()->isFloatingType())
821-
return Discard(this->emitMulf(getRoundingMode(BO), BO));
821+
return Discard(this->emitMulf(getFPOptions(BO), BO));
822822
return Discard(this->emitMul(*T, BO));
823823
case BO_Rem:
824824
return Discard(this->emitRem(*T, BO));
825825
case BO_Div:
826826
if (BO->getType()->isFloatingType())
827-
return Discard(this->emitDivf(getRoundingMode(BO), BO));
827+
return Discard(this->emitDivf(getFPOptions(BO), BO));
828828
return Discard(this->emitDiv(*T, BO));
829829
case BO_Assign:
830830
if (DiscardResult)
@@ -1153,7 +1153,7 @@ bool Compiler<Emitter>::VisitComplexBinOp(const BinaryOperator *E) {
11531153
if (!loadComplexValue(RHSIsComplex, true, ElemIndex, RHSOffset, RHS))
11541154
return false;
11551155
if (ResultElemT == PT_Float) {
1156-
if (!this->emitAddf(getRoundingMode(E), E))
1156+
if (!this->emitAddf(getFPOptions(E), E))
11571157
return false;
11581158
} else {
11591159
if (!this->emitAdd(ResultElemT, E))
@@ -1167,7 +1167,7 @@ bool Compiler<Emitter>::VisitComplexBinOp(const BinaryOperator *E) {
11671167
if (!loadComplexValue(RHSIsComplex, true, ElemIndex, RHSOffset, RHS))
11681168
return false;
11691169
if (ResultElemT == PT_Float) {
1170-
if (!this->emitSubf(getRoundingMode(E), E))
1170+
if (!this->emitSubf(getFPOptions(E), E))
11711171
return false;
11721172
} else {
11731173
if (!this->emitSub(ResultElemT, E))
@@ -1182,7 +1182,7 @@ bool Compiler<Emitter>::VisitComplexBinOp(const BinaryOperator *E) {
11821182
return false;
11831183

11841184
if (ResultElemT == PT_Float) {
1185-
if (!this->emitMulf(getRoundingMode(E), E))
1185+
if (!this->emitMulf(getFPOptions(E), E))
11861186
return false;
11871187
} else {
11881188
if (!this->emitMul(ResultElemT, E))
@@ -1198,7 +1198,7 @@ bool Compiler<Emitter>::VisitComplexBinOp(const BinaryOperator *E) {
11981198
return false;
11991199

12001200
if (ResultElemT == PT_Float) {
1201-
if (!this->emitDivf(getRoundingMode(E), E))
1201+
if (!this->emitDivf(getFPOptions(E), E))
12021202
return false;
12031203
} else {
12041204
if (!this->emitDiv(ResultElemT, E))
@@ -2063,22 +2063,21 @@ bool Compiler<Emitter>::VisitFloatCompoundAssignOperator(
20632063
if (!this->emitGetLocal(*RT, TempOffset, E))
20642064
return false;
20652065

2066-
llvm::RoundingMode RM = getRoundingMode(E);
20672066
switch (E->getOpcode()) {
20682067
case BO_AddAssign:
2069-
if (!this->emitAddf(RM, E))
2068+
if (!this->emitAddf(getFPOptions(E), E))
20702069
return false;
20712070
break;
20722071
case BO_SubAssign:
2073-
if (!this->emitSubf(RM, E))
2072+
if (!this->emitSubf(getFPOptions(E), E))
20742073
return false;
20752074
break;
20762075
case BO_MulAssign:
2077-
if (!this->emitMulf(RM, E))
2076+
if (!this->emitMulf(getFPOptions(E), E))
20782077
return false;
20792078
break;
20802079
case BO_DivAssign:
2081-
if (!this->emitDivf(RM, E))
2080+
if (!this->emitDivf(getFPOptions(E), E))
20822081
return false;
20832082
break;
20842083
default:
@@ -3325,7 +3324,7 @@ template <class Emitter> bool Compiler<Emitter>::visitBool(const Expr *E) {
33253324

33263325
// Or Floats.
33273326
if (T == PT_Float)
3328-
return this->emitCastFloatingIntegralBool(E);
3327+
return this->emitCastFloatingIntegralBool(getFPOptions(E), E);
33293328

33303329
// Or anything else we can.
33313330
return this->emitCast(*T, PT_Bool, E);
@@ -5005,8 +5004,8 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
50055004
}
50065005

50075006
if (T == PT_Float) {
5008-
return DiscardResult ? this->emitIncfPop(getRoundingMode(E), E)
5009-
: this->emitIncf(getRoundingMode(E), E);
5007+
return DiscardResult ? this->emitIncfPop(getFPOptions(E), E)
5008+
: this->emitIncf(getFPOptions(E), E);
50105009
}
50115010

50125011
return DiscardResult ? this->emitIncPop(*T, E) : this->emitInc(*T, E);
@@ -5028,8 +5027,8 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
50285027
}
50295028

50305029
if (T == PT_Float) {
5031-
return DiscardResult ? this->emitDecfPop(getRoundingMode(E), E)
5032-
: this->emitDecf(getRoundingMode(E), E);
5030+
return DiscardResult ? this->emitDecfPop(getFPOptions(E), E)
5031+
: this->emitDecf(getFPOptions(E), E);
50335032
}
50345033

50355034
return DiscardResult ? this->emitDecPop(*T, E) : this->emitDec(*T, E);
@@ -5056,7 +5055,7 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
50565055
// Post-inc and pre-inc are the same if the value is to be discarded.
50575056
if (DiscardResult) {
50585057
if (T == PT_Float)
5059-
return this->emitIncfPop(getRoundingMode(E), E);
5058+
return this->emitIncfPop(getFPOptions(E), E);
50605059
return this->emitIncPop(*T, E);
50615060
}
50625061

@@ -5066,7 +5065,7 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
50665065
return false;
50675066
if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E))
50685067
return false;
5069-
if (!this->emitAddf(getRoundingMode(E), E))
5068+
if (!this->emitAddf(getFPOptions(E), E))
50705069
return false;
50715070
if (!this->emitStoreFloat(E))
50725071
return false;
@@ -5105,7 +5104,7 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
51055104
// Post-dec and pre-dec are the same if the value is to be discarded.
51065105
if (DiscardResult) {
51075106
if (T == PT_Float)
5108-
return this->emitDecfPop(getRoundingMode(E), E);
5107+
return this->emitDecfPop(getFPOptions(E), E);
51095108
return this->emitDecPop(*T, E);
51105109
}
51115110

@@ -5115,7 +5114,7 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
51155114
return false;
51165115
if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E))
51175116
return false;
5118-
if (!this->emitSubf(getRoundingMode(E), E))
5117+
if (!this->emitSubf(getFPOptions(E), E))
51195118
return false;
51205119
if (!this->emitStoreFloat(E))
51215120
return false;
@@ -5579,13 +5578,15 @@ bool Compiler<Emitter>::emitPrimCast(PrimType FromT, PrimType ToT,
55795578
}
55805579

55815580
if (ToT == PT_IntAP)
5582-
return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT), E);
5581+
return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT),
5582+
getFPOptions(E), E);
55835583
if (ToT == PT_IntAPS)
5584-
return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT), E);
5584+
return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT),
5585+
getFPOptions(E), E);
55855586

55865587
// Float to integral.
55875588
if (isIntegralType(ToT) || ToT == PT_Bool)
5588-
return this->emitCastFloatingIntegral(ToT, E);
5589+
return this->emitCastFloatingIntegral(ToT, getFPOptions(E), E);
55895590
}
55905591

55915592
if (isIntegralType(FromT) || FromT == PT_Bool) {
@@ -5601,8 +5602,7 @@ bool Compiler<Emitter>::emitPrimCast(PrimType FromT, PrimType ToT,
56015602
if (ToT == PT_Float) {
56025603
// Integral to floating.
56035604
const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
5604-
return this->emitCastIntegralFloating(FromT, ToSem, getRoundingMode(E),
5605-
E);
5605+
return this->emitCastIntegralFloating(FromT, ToSem, getFPOptions(E), E);
56065606
}
56075607
}
56085608

@@ -5639,7 +5639,7 @@ bool Compiler<Emitter>::emitComplexBoolCast(const Expr *E) {
56395639
if (!this->emitArrayElem(ElemT, 0, E))
56405640
return false;
56415641
if (ElemT == PT_Float) {
5642-
if (!this->emitCastFloatingIntegral(PT_Bool, E))
5642+
if (!this->emitCastFloatingIntegral(PT_Bool, getFPOptions(E), E))
56435643
return false;
56445644
} else {
56455645
if (!this->emitCast(ElemT, PT_Bool, E))
@@ -5654,7 +5654,7 @@ bool Compiler<Emitter>::emitComplexBoolCast(const Expr *E) {
56545654
if (!this->emitArrayElemPop(ElemT, 1, E))
56555655
return false;
56565656
if (ElemT == PT_Float) {
5657-
if (!this->emitCastFloatingIntegral(PT_Bool, E))
5657+
if (!this->emitCastFloatingIntegral(PT_Bool, getFPOptions(E), E))
56585658
return false;
56595659
} else {
56605660
if (!this->emitCast(ElemT, PT_Bool, E))

clang/lib/AST/ByteCode/Compiler.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,10 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
341341
return FPO.getRoundingMode();
342342
}
343343

344+
uint32_t getFPOptions(const Expr *E) const {
345+
return E->getFPFeaturesInEffect(Ctx.getLangOpts()).getAsOpaqueInt();
346+
}
347+
344348
bool emitPrimCast(PrimType FromT, PrimType ToT, QualType ToQT, const Expr *E);
345349
PrimType classifyComplexElementType(QualType T) const {
346350
assert(T->isAnyComplexType());

clang/lib/AST/ByteCode/Interp.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -756,14 +756,13 @@ bool CheckPure(InterpState &S, CodePtr OpPC, const CXXMethodDecl *MD) {
756756
}
757757

758758
bool CheckFloatResult(InterpState &S, CodePtr OpPC, const Floating &Result,
759-
APFloat::opStatus Status) {
760-
const SourceInfo &E = S.Current->getSource(OpPC);
761-
759+
APFloat::opStatus Status, FPOptions FPO) {
762760
// [expr.pre]p4:
763761
// If during the evaluation of an expression, the result is not
764762
// mathematically defined [...], the behavior is undefined.
765763
// FIXME: C++ rules require us to not conform to IEEE 754 here.
766764
if (Result.isNan()) {
765+
const SourceInfo &E = S.Current->getSource(OpPC);
767766
S.CCEDiag(E, diag::note_constexpr_float_arithmetic)
768767
<< /*NaN=*/true << S.Current->getRange(OpPC);
769768
return S.noteUndefinedBehavior();
@@ -774,12 +773,11 @@ bool CheckFloatResult(InterpState &S, CodePtr OpPC, const Floating &Result,
774773
if (S.inConstantContext())
775774
return true;
776775

777-
FPOptions FPO = E.asExpr()->getFPFeaturesInEffect(S.Ctx.getLangOpts());
778-
779776
if ((Status & APFloat::opInexact) &&
780777
FPO.getRoundingMode() == llvm::RoundingMode::Dynamic) {
781778
// Inexact result means that it depends on rounding mode. If the requested
782779
// mode is dynamic, the evaluation cannot be made in compile time.
780+
const SourceInfo &E = S.Current->getSource(OpPC);
783781
S.FFDiag(E, diag::note_constexpr_dynamic_rounding);
784782
return false;
785783
}
@@ -788,12 +786,14 @@ bool CheckFloatResult(InterpState &S, CodePtr OpPC, const Floating &Result,
788786
(FPO.getRoundingMode() == llvm::RoundingMode::Dynamic ||
789787
FPO.getExceptionMode() != LangOptions::FPE_Ignore ||
790788
FPO.getAllowFEnvAccess())) {
789+
const SourceInfo &E = S.Current->getSource(OpPC);
791790
S.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
792791
return false;
793792
}
794793

795794
if ((Status & APFloat::opStatus::opInvalidOp) &&
796795
FPO.getExceptionMode() != LangOptions::FPE_Ignore) {
796+
const SourceInfo &E = S.Current->getSource(OpPC);
797797
// There is no usefully definable result.
798798
S.FFDiag(E);
799799
return false;

0 commit comments

Comments
 (0)