[clang] [clang][bytecode] Fix __builtin_convertvector with float-cast (PR #112238)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 14 10:58:23 PDT 2024


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

Comparing their PrimTypes isn't enough in this case. We can have a floating cast here as well.

>From 7c9ea06f6bda11c3c41477028fd39453acfd8954 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Mon, 14 Oct 2024 19:56:51 +0200
Subject: [PATCH] [clang][bytecode] Fix __builtin_convertvector with float-cast

Comparing their PrimTypes isn't enough in this case. We can have a
floating cast here as well.
---
 clang/lib/AST/ByteCode/Compiler.cpp | 10 ++++++++--
 clang/test/AST/ByteCode/vectors.cpp | 18 ++++++++++++++++++
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index b2663714340b93..5647963e884b7d 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -3542,8 +3542,8 @@ bool Compiler<Emitter>::VisitConvertVectorExpr(const ConvertVectorExpr *E) {
   QualType ElemType = VT->getElementType();
   PrimType ElemT = classifyPrim(ElemType);
   const Expr *Src = E->getSrcExpr();
-  PrimType SrcElemT =
-      classifyPrim(Src->getType()->castAs<VectorType>()->getElementType());
+  QualType SrcType = Src->getType();
+  PrimType SrcElemT = classifyVectorElementType(SrcType);
 
   unsigned SrcOffset = this->allocateLocalPrimitive(Src, PT_Ptr, true, false);
   if (!this->visit(Src))
@@ -3556,9 +3556,15 @@ bool Compiler<Emitter>::VisitConvertVectorExpr(const ConvertVectorExpr *E) {
       return false;
     if (!this->emitArrayElemPop(SrcElemT, I, E))
       return false;
+
+    // Cast to the desired result element type.
     if (SrcElemT != ElemT) {
       if (!this->emitPrimCast(SrcElemT, ElemT, ElemType, E))
         return false;
+    } else if (ElemType->isFloatingType() && SrcType != ElemType) {
+      const auto *TargetSemantics = &Ctx.getFloatSemantics(ElemType);
+      if (!this->emitCastFP(TargetSemantics, getRoundingMode(E), E))
+        return false;
     }
     if (!this->emitInitElem(ElemT, I, E))
       return false;
diff --git a/clang/test/AST/ByteCode/vectors.cpp b/clang/test/AST/ByteCode/vectors.cpp
index 7662abeeb7f596..a0aace44f3c981 100644
--- a/clang/test/AST/ByteCode/vectors.cpp
+++ b/clang/test/AST/ByteCode/vectors.cpp
@@ -125,3 +125,21 @@ constexpr int a2() {
 }
 
 static_assert(a2() == 0);
+
+namespace {
+  /// convertvector expr with a per-element floating-point cast
+
+  typedef float __m128 __attribute__((__vector_size__(16), __aligned__(16)));
+  typedef double __m128d __attribute__((__vector_size__(16), __aligned__(16)));
+  typedef float __v4sf __attribute__((__vector_size__(16)));
+  typedef double __v2df __attribute__((__vector_size__(16)));
+
+  static inline constexpr __m128d
+  _mm_cvtps_pd(__m128 __a) {
+    return __builtin_convertvector(__builtin_shufflevector(__a, __a, 0, 1), __v2df);
+  }
+
+  constexpr __m128 kf1 {-1.0f,+2.0f,-3.0f,+4.0f};
+  constexpr __m128d v_mm_cvtps_pd = _mm_cvtps_pd(kf1);
+  static_assert(v_mm_cvtps_pd[0] == -1.0 && v_mm_cvtps_pd[1] == +2.0);
+}



More information about the cfe-commits mailing list