Author: Timm Baeder
Date: 2024-10-15T07:49:55+02:00
New Revision: 51d0e40c2ee1ab25f408f22e82ef4e16d6fb3103

URL: 
https://github.com/llvm/llvm-project/commit/51d0e40c2ee1ab25f408f22e82ef4e16d6fb3103
DIFF: 
https://github.com/llvm/llvm-project/commit/51d0e40c2ee1ab25f408f22e82ef4e16d6fb3103.diff

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

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

Added: 
    

Modified: 
    clang/lib/AST/ByteCode/Compiler.cpp
    clang/test/AST/ByteCode/vectors.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ByteCode/Compiler.cpp 
b/clang/lib/AST/ByteCode/Compiler.cpp
index 51115907629d67..8ca63bf64aa0ef 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -3545,8 +3545,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))
@@ -3559,9 +3559,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);
+}


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

Reply via email to