Skip to content

Commit

Permalink
[clang][bytecode] Fix __builtin_convertvector with float-cast
Browse files Browse the repository at this point in the history
Comparing their PrimTypes isn't enough in this case. We can have a
floating cast here as well.
  • Loading branch information
tbaederr committed Oct 14, 2024
1 parent 6a98c4a commit 7c9ea06
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 2 deletions.
10 changes: 8 additions & 2 deletions clang/lib/AST/ByteCode/Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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;
Expand Down
18 changes: 18 additions & 0 deletions clang/test/AST/ByteCode/vectors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

0 comments on commit 7c9ea06

Please sign in to comment.