[PATCH] D140377: [clang][Interp] Compound assign operators for FP values
This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rGaf3a171dcffd: [clang][Interp] Compound assign operators for FP values (authored by tbaeder). Changed prior to commit: https://reviews.llvm.org/D140377?vs=484184=492104#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D140377/new/ https://reviews.llvm.org/D140377 Files: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/lib/AST/Interp/ByteCodeExprGen.h clang/test/AST/Interp/const-fpfeatures.cpp clang/test/AST/Interp/floats.cpp Index: clang/test/AST/Interp/floats.cpp === --- clang/test/AST/Interp/floats.cpp +++ clang/test/AST/Interp/floats.cpp @@ -54,3 +54,27 @@ // ref-note {{is outside the range of representable values}} \ // expected-error {{must be initialized by a constant expression}} \ // expected-note {{is outside the range of representable values}} + +namespace compound { + constexpr float f1() { +float f = 0; +f += 3.0; +f -= 3.0f; + +f += 1; +f /= 1; +f /= 1.0; +f *= f; + +f *= 2.0; +return f; + } + static_assert(f1() == 2, ""); + + constexpr float f2() { +float f = __FLT_MAX__; +f += 1.0; +return f; + } + static_assert(f2() == __FLT_MAX__, ""); +} Index: clang/test/AST/Interp/const-fpfeatures.cpp === --- clang/test/AST/Interp/const-fpfeatures.cpp +++ clang/test/AST/Interp/const-fpfeatures.cpp @@ -50,9 +50,6 @@ // CHECK: @V2 = {{.*}} float 0x3FF02000 -/// FIXME: The following tests need support for compound assign operators -/// with LHS and RHS of different semantics. -#if 0 constexpr float add_cast_round_down(float x, double y) { #pragma STDC FENV_ROUND FE_DOWNWARD float res = x; @@ -70,5 +67,5 @@ float V3 = add_cast_round_down(1.0F, 0x0.01p0F); float V4 = add_cast_round_up(1.0F, 0x0.01p0F); - -#endif +// CHECK: @V3 = {{.*}} float 1.00e+00 +// CHECK: @V4 = {{.*}} float 0x3FF02000 Index: clang/lib/AST/Interp/ByteCodeExprGen.h === --- clang/lib/AST/Interp/ByteCodeExprGen.h +++ clang/lib/AST/Interp/ByteCodeExprGen.h @@ -85,6 +85,7 @@ bool VisitStringLiteral(const StringLiteral *E); bool VisitCharacterLiteral(const CharacterLiteral *E); bool VisitCompoundAssignOperator(const CompoundAssignOperator *E); + bool VisitFloatCompoundAssignOperator(const CompoundAssignOperator *E); protected: bool visitExpr(const Expr *E) override; Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp === --- clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -550,9 +550,86 @@ return this->emitConst(E->getValue(), E); } +template +bool ByteCodeExprGen::VisitFloatCompoundAssignOperator( +const CompoundAssignOperator *E) { + assert(E->getType()->isFloatingType()); + + const Expr *LHS = E->getLHS(); + const Expr *RHS = E->getRHS(); + llvm::RoundingMode RM = getRoundingMode(E); + QualType LHSComputationType = E->getComputationLHSType(); + QualType ResultType = E->getComputationResultType(); + std::optional LT = classify(LHSComputationType); + std::optional RT = classify(ResultType); + + if (!LT || !RT) +return false; + + // First, visit LHS. + if (!visit(LHS)) +return false; + + if (!this->emitLoad(*LT, E)) +return false; + + // If necessary, convert LHS to its computation type. + if (LHS->getType() != LHSComputationType) { +const auto *TargetSemantics = +().getFloatTypeSemantics(LHSComputationType); + +if (!this->emitCastFP(TargetSemantics, RM, E)) + return false; + } + + // Now load RHS. + if (!visit(RHS)) +return false; + + switch (E->getOpcode()) { + case BO_AddAssign: +if (!this->emitAddf(RM, E)) + return false; +break; + case BO_SubAssign: +if (!this->emitSubf(RM, E)) + return false; +break; + case BO_MulAssign: +if (!this->emitMulf(RM, E)) + return false; +break; + case BO_DivAssign: +if (!this->emitDivf(RM, E)) + return false; +break; + default: +return false; + } + + // If necessary, convert result to LHS's type. + if (LHS->getType() != ResultType) { +const auto *TargetSemantics = +().getFloatTypeSemantics(LHS->getType()); + +if (!this->emitCastFP(TargetSemantics, RM, E)) + return false; + } + + if (DiscardResult) +return this->emitStorePop(*LT, E); + return this->emitStore(*LT, E); +} + template bool ByteCodeExprGen::VisitCompoundAssignOperator( const CompoundAssignOperator *E) { + + // Handle floating point operations separately here, since they + // require special
[PATCH] D140377: [clang][Interp] Compound assign operators for FP values
sepavloff accepted this revision. sepavloff added a comment. This revision is now accepted and ready to land. LGTM. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D140377/new/ https://reviews.llvm.org/D140377 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D140377: [clang][Interp] Compound assign operators for FP values
tbaeder added a comment. Ping Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D140377/new/ https://reviews.llvm.org/D140377 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D140377: [clang][Interp] Compound assign operators for FP values
tbaeder created this revision. tbaeder added reviewers: aaron.ballman, erichkeane, tahonermann, shafik, sepavloff. Herald added a project: All. tbaeder requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. I'm not quite sure I got the different computation values correct, so please review. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D140377 Files: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/lib/AST/Interp/ByteCodeExprGen.h clang/test/AST/Interp/const-fpfeatures.cpp clang/test/AST/Interp/floats.cpp Index: clang/test/AST/Interp/floats.cpp === --- clang/test/AST/Interp/floats.cpp +++ clang/test/AST/Interp/floats.cpp @@ -54,3 +54,27 @@ // ref-note {{is outside the range of representable values}} \ // expected-error {{must be initialized by a constant expression}} \ // expected-note {{is outside the range of representable values}} + +namespace compound { + constexpr float f1() { +float f = 0; +f += 3.0; +f -= 3.0f; + +f += 1; +f /= 1; +f /= 1.0; +f *= f; + +f *= 2.0; +return f; + } + static_assert(f1() == 2); + + constexpr float f2() { +float f = __FLT_MAX__; +f += 1.0; +return f; + } + static_assert(f2() == __FLT_MAX__); +} Index: clang/test/AST/Interp/const-fpfeatures.cpp === --- clang/test/AST/Interp/const-fpfeatures.cpp +++ clang/test/AST/Interp/const-fpfeatures.cpp @@ -50,9 +50,6 @@ // CHECK: @V2 = {{.*}} float 0x3FF02000 -/// FIXME: The following tests need support for compound assign operators -/// with LHS and RHS of different semantics. -#if 0 constexpr float add_cast_round_down(float x, double y) { #pragma STDC FENV_ROUND FE_DOWNWARD float res = x; @@ -70,5 +67,5 @@ float V3 = add_cast_round_down(1.0F, 0x0.01p0F); float V4 = add_cast_round_up(1.0F, 0x0.01p0F); - -#endif +// CHECK: @V3 = {{.*}} float 1.00e+00 +// CHECK: @V4 = {{.*}} float 0x3FF02000 Index: clang/lib/AST/Interp/ByteCodeExprGen.h === --- clang/lib/AST/Interp/ByteCodeExprGen.h +++ clang/lib/AST/Interp/ByteCodeExprGen.h @@ -88,6 +88,7 @@ bool VisitStringLiteral(const StringLiteral *E); bool VisitCharacterLiteral(const CharacterLiteral *E); bool VisitCompoundAssignOperator(const CompoundAssignOperator *E); + bool VisitFloatCompoundAssignOperator(const CompoundAssignOperator *E); bool VisitExprWithCleanups(const ExprWithCleanups *E); bool VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E); Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp === --- clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -593,9 +593,86 @@ return this->emitConst(E->getValue(), E); } +template +bool ByteCodeExprGen::VisitFloatCompoundAssignOperator( +const CompoundAssignOperator *E) { + assert(E->getType()->isFloatingType()); + + const Expr *LHS = E->getLHS(); + const Expr *RHS = E->getRHS(); + llvm::RoundingMode RM = getRoundingMode(E); + QualType LHSComputationType = E->getComputationLHSType(); + QualType ResultType = E->getComputationResultType(); + std::optional LT = classify(LHSComputationType); + std::optional RT = classify(ResultType); + + if (!LT || !RT) +return false; + + // First, visit LHS. + if (!visit(LHS)) +return false; + + if (!this->emitLoad(*LT, E)) +return false; + + // If necessary, convert LHS to its computation type. + if (LHS->getType() != LHSComputationType) { +const auto *TargetSemantics = +().getFloatTypeSemantics(LHSComputationType); + +if (!this->emitCastFP(TargetSemantics, RM, E)) + return false; + } + + // Now load RHS. + if (!visit(RHS)) +return false; + + switch (E->getOpcode()) { + case BO_AddAssign: +if (!this->emitAddf(RM, E)) + return false; +break; + case BO_SubAssign: +if (!this->emitSubf(RM, E)) + return false; +break; + case BO_MulAssign: +if (!this->emitMulf(RM, E)) + return false; +break; + case BO_DivAssign: +if (!this->emitDivf(RM, E)) + return false; +break; + default: +return false; + } + + // If necessary, convert result to LHS's type. + if (LHS->getType() != ResultType) { +const auto *TargetSemantics = +().getFloatTypeSemantics(LHS->getType()); + +if (!this->emitCastFP(TargetSemantics, RM, E)) + return false; + } + + if (DiscardResult) +return this->emitStorePop(*LT, E); + return this->emitStore(*LT, E); +} + template bool ByteCodeExprGen::VisitCompoundAssignOperator( const CompoundAssignOperator *E) { + + // Handle floating point operations separately here, since