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

None

>From 7583fed959318e8f0e01957d7e278998510d9b0e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com>
Date: Sat, 28 Sep 2024 15:50:04 +0200
Subject: [PATCH] [clang][bytecode] Implement floating-to-fixed-point casts

---
 clang/lib/AST/ByteCode/Compiler.cpp     |  9 +++++++
 clang/lib/AST/ByteCode/Interp.h         | 35 ++++++++++++++++++++++---
 clang/lib/AST/ByteCode/Opcodes.td       |  3 +++
 clang/test/AST/ByteCode/fixed-point.cpp |  7 +++++
 4 files changed, 50 insertions(+), 4 deletions(-)

diff --git a/clang/lib/AST/ByteCode/Compiler.cpp 
b/clang/lib/AST/ByteCode/Compiler.cpp
index a80d973056db43..40cb1b2dd80f96 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -682,6 +682,15 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
     return this->emitCastIntegralFixedPoint(classifyPrim(SubExpr->getType()), 
I,
                                             CE);
   }
+  case CK_FloatingToFixedPoint: {
+    if (!this->visit(SubExpr))
+      return false;
+
+    auto Sem = Ctx.getASTContext().getFixedPointSemantics(CE->getType());
+    uint32_t I;
+    std::memcpy(&I, &Sem, sizeof(Sem));
+    return this->emitCastFloatingFixedPoint(I, CE);
+  }
 
   case CK_ToVoid:
     return discard(SubExpr);
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index f88233ed0f8f0a..23405765d8de82 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -2321,7 +2321,7 @@ static inline bool CastIntegralFixedPoint(InterpState &S, 
CodePtr OpPC,
   std::memcpy(&Sem, &FPS, sizeof(Sem));
 
   bool Overflow;
-  llvm::APFixedPoint IntResult =
+  llvm::APFixedPoint Result =
       llvm::APFixedPoint::getFromIntValue(Int.toAPSInt(), Sem, &Overflow);
 
   if (Overflow) {
@@ -2329,14 +2329,41 @@ static inline bool CastIntegralFixedPoint(InterpState 
&S, CodePtr OpPC,
     if (S.checkingForUndefinedBehavior()) {
       S.getASTContext().getDiagnostics().Report(
           E->getExprLoc(), diag::warn_fixedpoint_constant_overflow)
-          << IntResult.toString() << E->getType();
+          << Result.toString() << E->getType();
     }
-    S.CCEDiag(E, diag::note_constexpr_overflow) << IntResult << E->getType();
+    S.CCEDiag(E, diag::note_constexpr_overflow) << Result << E->getType();
     if (!S.noteUndefinedBehavior())
       return false;
   }
 
-  S.Stk.push<FixedPoint>(IntResult);
+  S.Stk.push<FixedPoint>(Result);
+  return true;
+}
+
+static inline bool CastFloatingFixedPoint(InterpState &S, CodePtr OpPC,
+                                          uint32_t FPS) {
+  const auto &Float = S.Stk.pop<Floating>();
+
+  FixedPointSemantics Sem(0, 0, false, false, false);
+  std::memcpy(&Sem, &FPS, sizeof(Sem));
+
+  bool Overflow;
+  llvm::APFixedPoint Result =
+      llvm::APFixedPoint::getFromFloatValue(Float.getAPFloat(), Sem, 
&Overflow);
+
+  if (Overflow) {
+    const Expr *E = S.Current->getExpr(OpPC);
+    if (S.checkingForUndefinedBehavior()) {
+      S.getASTContext().getDiagnostics().Report(
+          E->getExprLoc(), diag::warn_fixedpoint_constant_overflow)
+          << Result.toString() << E->getType();
+    }
+    S.CCEDiag(E, diag::note_constexpr_overflow) << Result << E->getType();
+    if (!S.noteUndefinedBehavior())
+      return false;
+  }
+
+  S.Stk.push<FixedPoint>(Result);
   return true;
 }
 
diff --git a/clang/lib/AST/ByteCode/Opcodes.td 
b/clang/lib/AST/ByteCode/Opcodes.td
index 65eb82080a2194..240e00e59d97ec 100644
--- a/clang/lib/AST/ByteCode/Opcodes.td
+++ b/clang/lib/AST/ByteCode/Opcodes.td
@@ -679,6 +679,9 @@ def CastIntegralFixedPoint : Opcode {
   let Args = [ArgUint32];
   let HasGroup = 1;
 }
+def CastFloatingFixedPoint : Opcode {
+  let Args = [ArgUint32];
+}
 
 def PtrPtrCast : Opcode {
   let Args = [ArgBool];
diff --git a/clang/test/AST/ByteCode/fixed-point.cpp 
b/clang/test/AST/ByteCode/fixed-point.cpp
index 51ea166748730c..76da06a02e150c 100644
--- a/clang/test/AST/ByteCode/fixed-point.cpp
+++ b/clang/test/AST/ByteCode/fixed-point.cpp
@@ -25,3 +25,10 @@ namespace IntToFixedPointCast {
   static_assert(sf == -1.0k);
   static_assert(sf == -1);
 }
+
+namespace FloatToFixedPointCast {
+  constexpr _Fract sf = 1.0; // both-error {{must be initialized by a constant 
expression}} \
+                             // both-note {{outside the range of representable 
values of type 'const _Fract'}}
+
+  constexpr _Fract sf2 = 0.5;
+}

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to