[PATCH] D140377: [clang][Interp] Compound assign operators for FP values

2023-01-25 Thread Timm Bäder via Phabricator via cfe-commits
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

2023-01-17 Thread Serge Pavlov via Phabricator via cfe-commits
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

2023-01-16 Thread Timm Bäder via Phabricator via cfe-commits
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

2022-12-20 Thread Timm Bäder via Phabricator via cfe-commits
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