[clang] [clang][bytecode] Implement (N)EQ between fixed point and integral (PR #110358)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Sat Sep 28 04:14:55 PDT 2024


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

Convert the non-fixed-point side to a fixed-point type before doing the comparison.

>From a00e1ed99bd3f02af5131e2cf32c665608650a0c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Sat, 28 Sep 2024 13:12:10 +0200
Subject: [PATCH] [clang][bytecode] Implement (N)EQ between fixed point and
 integral

Convert the non-fixed-point side to a fixed-point type before doing the
comparison.
---
 clang/lib/AST/ByteCode/Compiler.cpp     | 51 +++++++++++++++++++++++++
 clang/lib/AST/ByteCode/Compiler.h       |  1 +
 clang/test/AST/ByteCode/fixed-point.cpp |  5 +++
 3 files changed, 57 insertions(+)

diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 8875fc05d24bee..a80d973056db43 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -773,6 +773,8 @@ bool Compiler<Emitter>::VisitBinaryOperator(const BinaryOperator *BO) {
        RHS->getType()->isAnyComplexType()) &&
       BO->isComparisonOp())
     return this->emitComplexComparison(LHS, RHS, BO);
+  if (LHS->getType()->isFixedPointType() || RHS->getType()->isFixedPointType())
+    return this->VisitFixedPointBinOp(BO);
 
   if (BO->isPtrMemOp()) {
     if (!this->visit(LHS))
@@ -1469,6 +1471,55 @@ bool Compiler<Emitter>::VisitVectorBinOp(const BinaryOperator *E) {
   return true;
 }
 
+template <class Emitter>
+bool Compiler<Emitter>::VisitFixedPointBinOp(const BinaryOperator *E) {
+  const Expr *LHS = E->getLHS();
+  const Expr *RHS = E->getRHS();
+
+  assert(LHS->getType()->isFixedPointType() ||
+         RHS->getType()->isFixedPointType());
+
+  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));
+    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));
+    if (!this->emitCastIntegralFixedPoint(classifyPrim(RHS->getType()), I, E))
+      return false;
+  }
+
+  switch (E->getOpcode()) {
+  case BO_EQ:
+    return this->emitEQFixedPoint(E);
+  case BO_NE:
+    return this->emitNEFixedPoint(E);
+#if 0
+  case BO_LT:
+    return this->emitLTFixedPoint(E);
+  case BO_LE:
+    return this->emitLEFixedPoint(E);
+  case BO_GT:
+    return this->emitGTFixedPoint(E);
+  case BO_GE:
+    return this->emitGEFixedPoint(E);
+#endif
+  default:
+    return this->emitInvalid(E);
+  }
+
+  llvm_unreachable("unhandled binop opcode");
+}
+
 template <class Emitter>
 bool Compiler<Emitter>::VisitImplicitValueInitExpr(
     const ImplicitValueInitExpr *E) {
diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h
index d1911f11603a08..5349b184572b6e 100644
--- a/clang/lib/AST/ByteCode/Compiler.h
+++ b/clang/lib/AST/ByteCode/Compiler.h
@@ -132,6 +132,7 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
   bool VisitPointerArithBinOp(const BinaryOperator *E);
   bool VisitComplexBinOp(const BinaryOperator *E);
   bool VisitVectorBinOp(const BinaryOperator *E);
+  bool VisitFixedPointBinOp(const BinaryOperator *E);
   bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E);
   bool VisitCallExpr(const CallExpr *E);
   bool VisitBuiltinCallExpr(const CallExpr *E, unsigned BuiltinID);
diff --git a/clang/test/AST/ByteCode/fixed-point.cpp b/clang/test/AST/ByteCode/fixed-point.cpp
index 77000c08918256..51ea166748730c 100644
--- a/clang/test/AST/ByteCode/fixed-point.cpp
+++ b/clang/test/AST/ByteCode/fixed-point.cpp
@@ -6,17 +6,22 @@ static_assert(!((bool)0.0k));
 static_assert((bool)0.0k); // both-error {{static assertion failed}}
 
 static_assert(1.0k == 1.0k);
+static_assert(1.0k == 1);
 static_assert(1.0k != 1.0k); // both-error {{failed due to requirement '1.0k != 1.0k'}}
+static_assert(1.0k != 1); // both-error {{failed due to requirement '1.0k != 1'}}
 static_assert(-12.0k == -(-(-12.0k)));
 
 /// Zero-init.
 constexpr _Accum A{};
 static_assert(A == 0.0k);
+static_assert(A == 0);
 
 namespace IntToFixedPointCast {
   constexpr _Accum B = 13;
   static_assert(B == 13.0k);
+  static_assert(B == 13);
 
   constexpr _Fract sf = -1;
   static_assert(sf == -1.0k);
+  static_assert(sf == -1);
 }



More information about the cfe-commits mailing list