[clang] 641b4d5 - [clang][bytecode] Implement integral-to-fixed-point casts (#110350)

via cfe-commits cfe-commits at lists.llvm.org
Sat Sep 28 04:10:27 PDT 2024


Author: Timm Baeder
Date: 2024-09-28T13:10:23+02:00
New Revision: 641b4d5370f1ce2f5d448cf63519f391be1cf263

URL: https://github.com/llvm/llvm-project/commit/641b4d5370f1ce2f5d448cf63519f391be1cf263
DIFF: https://github.com/llvm/llvm-project/commit/641b4d5370f1ce2f5d448cf63519f391be1cf263.diff

LOG: [clang][bytecode] Implement integral-to-fixed-point casts (#110350)

Added: 
    

Modified: 
    clang/lib/AST/ByteCode/Compiler.cpp
    clang/lib/AST/ByteCode/FixedPoint.h
    clang/lib/AST/ByteCode/Interp.h
    clang/lib/AST/ByteCode/Opcodes.td
    clang/test/AST/ByteCode/fixed-point.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 2520fe30547b23..8875fc05d24bee 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -672,6 +672,17 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
                                ToSize, CE);
   };
 
+  case CK_IntegralToFixedPoint: {
+    if (!this->visit(SubExpr))
+      return false;
+
+    auto Sem = Ctx.getASTContext().getFixedPointSemantics(CE->getType());
+    uint32_t I;
+    std::memcpy(&I, &Sem, sizeof(Sem));
+    return this->emitCastIntegralFixedPoint(classifyPrim(SubExpr->getType()), I,
+                                            CE);
+  }
+
   case CK_ToVoid:
     return discard(SubExpr);
 

diff  --git a/clang/lib/AST/ByteCode/FixedPoint.h b/clang/lib/AST/ByteCode/FixedPoint.h
index 9dd300c3dbf6df..daa62945346aeb 100644
--- a/clang/lib/AST/ByteCode/FixedPoint.h
+++ b/clang/lib/AST/ByteCode/FixedPoint.h
@@ -23,9 +23,10 @@ using APSInt = llvm::APSInt;
 class FixedPoint final {
 private:
   llvm::APFixedPoint V;
-  FixedPoint(llvm::APFixedPoint &&V) : V(std::move(V)) {}
 
 public:
+  FixedPoint(llvm::APFixedPoint &&V) : V(std::move(V)) {}
+  FixedPoint(llvm::APFixedPoint &V) : V(V) {}
   FixedPoint(APInt V, llvm::FixedPointSemantics Sem) : V(V, Sem) {}
   // This needs to be default-constructible so llvm::endian::read works.
   FixedPoint()

diff  --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 79af426f8a913f..f88233ed0f8f0a 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -38,6 +38,7 @@ namespace clang {
 namespace interp {
 
 using APSInt = llvm::APSInt;
+using FixedPointSemantics = llvm::FixedPointSemantics;
 
 /// Convert a value to an APValue.
 template <typename T>
@@ -2311,6 +2312,34 @@ static inline bool CastPointerIntegralAPS(InterpState &S, CodePtr OpPC,
   return true;
 }
 
+template <PrimType Name, class T = typename PrimConv<Name>::T>
+static inline bool CastIntegralFixedPoint(InterpState &S, CodePtr OpPC,
+                                          uint32_t FPS) {
+  const T &Int = S.Stk.pop<T>();
+
+  FixedPointSemantics Sem(0, 0, false, false, false);
+  std::memcpy(&Sem, &FPS, sizeof(Sem));
+
+  bool Overflow;
+  llvm::APFixedPoint IntResult =
+      llvm::APFixedPoint::getFromIntValue(Int.toAPSInt(), 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)
+          << IntResult.toString() << E->getType();
+    }
+    S.CCEDiag(E, diag::note_constexpr_overflow) << IntResult << E->getType();
+    if (!S.noteUndefinedBehavior())
+      return false;
+  }
+
+  S.Stk.push<FixedPoint>(IntResult);
+  return true;
+}
+
 static inline bool PtrPtrCast(InterpState &S, CodePtr OpPC, bool SrcIsVoidPtr) {
   const auto &Ptr = S.Stk.peek<Pointer>();
 

diff  --git a/clang/lib/AST/ByteCode/Opcodes.td b/clang/lib/AST/ByteCode/Opcodes.td
index 5fdafd1bf81984..65eb82080a2194 100644
--- a/clang/lib/AST/ByteCode/Opcodes.td
+++ b/clang/lib/AST/ByteCode/Opcodes.td
@@ -674,6 +674,12 @@ def CastPointerIntegralAP : Opcode {
 def CastPointerIntegralAPS : Opcode {
   let Args = [ArgUint32];
 }
+def CastIntegralFixedPoint : Opcode {
+  let Types = [FixedSizeIntegralTypes];
+  let Args = [ArgUint32];
+  let HasGroup = 1;
+}
+
 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 bf1bd41783448f..77000c08918256 100644
--- a/clang/test/AST/ByteCode/fixed-point.cpp
+++ b/clang/test/AST/ByteCode/fixed-point.cpp
@@ -12,3 +12,11 @@ static_assert(-12.0k == -(-(-12.0k)));
 /// Zero-init.
 constexpr _Accum A{};
 static_assert(A == 0.0k);
+
+namespace IntToFixedPointCast {
+  constexpr _Accum B = 13;
+  static_assert(B == 13.0k);
+
+  constexpr _Fract sf = -1;
+  static_assert(sf == -1.0k);
+}


        


More information about the cfe-commits mailing list