[clang] [clang][bytcode] Convert Fixed Point values to target semantics... (PR #110411)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Sun Sep 29 00:04:19 PDT 2024


https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/110411

... after a binary operation. The Result of the operation is in the common semantics of RHS and LHS, so we need to convert that to the semantics of the BinaryOperator expression.

>From 14e89ad5254e9457b01fc0c62d698fc431e1aea0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Sun, 29 Sep 2024 09:00:16 +0200
Subject: [PATCH] [clang][bytcode] Convert Fixed Point values to target
 semantics...

... after a binary operation. The Result of the operation is in the
common semantics of RHS and LHS, so we need to convert that to the
semantics of the BinaryOperator expression.
---
 clang/lib/AST/ByteCode/Compiler.cpp     | 26 ++++++++++++++++++++-----
 clang/lib/AST/ByteCode/Interp.h         |  3 ++-
 clang/test/AST/ByteCode/fixed-point.cpp |  6 ++----
 3 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 3a3ee3b577c29c..44195a3dc33de4 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -1502,25 +1502,41 @@ bool Compiler<Emitter>::VisitFixedPointBinOp(const BinaryOperator *E) {
   assert(LHS->getType()->isFixedPointType() ||
          RHS->getType()->isFixedPointType());
 
+  auto LHSSema = Ctx.getASTContext().getFixedPointSemantics(LHS->getType());
+  auto RHSSema = Ctx.getASTContext().getFixedPointSemantics(RHS->getType());
+
   if (!this->visit(LHS))
     return false;
   if (!LHS->getType()->isFixedPointType()) {
-    auto Sem = Ctx.getASTContext().getFixedPointSemantics(LHS->getType());
     uint32_t I;
-    std::memcpy(&I, &Sem, sizeof(Sem));
+    std::memcpy(&I, &LHSSema, sizeof(llvm::FixedPointSemantics));
     if (!this->emitCastIntegralFixedPoint(classifyPrim(LHS->getType()), I, E))
       return false;
   }
+
   if (!this->visit(RHS))
     return false;
   if (!RHS->getType()->isFixedPointType()) {
-    auto Sem = Ctx.getASTContext().getFixedPointSemantics(RHS->getType());
     uint32_t I;
-    std::memcpy(&I, &Sem, sizeof(Sem));
+    std::memcpy(&I, &RHSSema, sizeof(llvm::FixedPointSemantics));
     if (!this->emitCastIntegralFixedPoint(classifyPrim(RHS->getType()), I, E))
       return false;
   }
 
+  // Convert the result to the target semantics.
+  auto ConvertResult = [&](bool R) -> bool {
+    if (!R)
+      return false;
+    auto ResultSema = Ctx.getASTContext().getFixedPointSemantics(E->getType());
+    auto CommonSema = LHSSema.getCommonSemantics(RHSSema);
+    if (ResultSema != CommonSema) {
+      uint32_t I;
+      std::memcpy(&I, &ResultSema, sizeof(ResultSema));
+      return this->emitCastFixedPoint(I, E);
+    }
+    return true;
+  };
+
   switch (E->getOpcode()) {
   case BO_EQ:
     return this->emitEQFixedPoint(E);
@@ -1537,7 +1553,7 @@ bool Compiler<Emitter>::VisitFixedPointBinOp(const BinaryOperator *E) {
     return this->emitGEFixedPoint(E);
 #endif
   case BO_Add:
-    return this->emitAddFixedPoint(E);
+    return ConvertResult(this->emitAddFixedPoint(E));
 
   default:
     return this->emitInvalid(E);
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index fd09deb87d4c51..89635f9c61e932 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -2177,7 +2177,8 @@ inline bool CastFixedPoint(InterpState &S, CodePtr OpPC, uint32_t FPS) {
           E->getExprLoc(), diag::warn_fixedpoint_constant_overflow)
           << Result.toDiagnosticString(S.getASTContext()) << E->getType();
     }
-    S.CCEDiag(E, diag::note_constexpr_overflow) << Result << E->getType();
+    S.CCEDiag(E, diag::note_constexpr_overflow)
+        << Result.toDiagnosticString(S.getASTContext()) << E->getType();
     if (!S.noteUndefinedBehavior())
       return false;
   }
diff --git a/clang/test/AST/ByteCode/fixed-point.cpp b/clang/test/AST/ByteCode/fixed-point.cpp
index dd360382e7ca21..d515b7fe1594a9 100644
--- a/clang/test/AST/ByteCode/fixed-point.cpp
+++ b/clang/test/AST/ByteCode/fixed-point.cpp
@@ -42,10 +42,8 @@ namespace BinOps {
   static_assert(1 + A == 14.0k);
   static_assert((A + A) == 26);
 
-  /// FIXME: Conversion between fixed point semantics.
-  static_assert(A + 100000 == 14.0k); // expected-error {{static assertion failed}} \
-                                      // ref-error {{is not an integral constant expression}} \
-                                      // ref-note {{is outside the range of representable values}}
+  static_assert(A + 100000 == 14.0k); // both-error {{is not an integral constant expression}} \
+                                      // both-note {{is outside the range of representable values}}
 }
 
 namespace FixedPointCasts {



More information about the cfe-commits mailing list