Skip to content

Commit 7c9ea06

Browse files
committed
[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.
1 parent 6a98c4a commit 7c9ea06

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3542,8 +3542,8 @@ bool Compiler<Emitter>::VisitConvertVectorExpr(const ConvertVectorExpr *E) {
35423542
QualType ElemType = VT->getElementType();
35433543
PrimType ElemT = classifyPrim(ElemType);
35443544
const Expr *Src = E->getSrcExpr();
3545-
PrimType SrcElemT =
3546-
classifyPrim(Src->getType()->castAs<VectorType>()->getElementType());
3545+
QualType SrcType = Src->getType();
3546+
PrimType SrcElemT = classifyVectorElementType(SrcType);
35473547

35483548
unsigned SrcOffset = this->allocateLocalPrimitive(Src, PT_Ptr, true, false);
35493549
if (!this->visit(Src))
@@ -3556,9 +3556,15 @@ bool Compiler<Emitter>::VisitConvertVectorExpr(const ConvertVectorExpr *E) {
35563556
return false;
35573557
if (!this->emitArrayElemPop(SrcElemT, I, E))
35583558
return false;
3559+
3560+
// Cast to the desired result element type.
35593561
if (SrcElemT != ElemT) {
35603562
if (!this->emitPrimCast(SrcElemT, ElemT, ElemType, E))
35613563
return false;
3564+
} else if (ElemType->isFloatingType() && SrcType != ElemType) {
3565+
const auto *TargetSemantics = &Ctx.getFloatSemantics(ElemType);
3566+
if (!this->emitCastFP(TargetSemantics, getRoundingMode(E), E))
3567+
return false;
35623568
}
35633569
if (!this->emitInitElem(ElemT, I, E))
35643570
return false;

clang/test/AST/ByteCode/vectors.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,21 @@ constexpr int a2() {
125125
}
126126

127127
static_assert(a2() == 0);
128+
129+
namespace {
130+
/// convertvector expr with a per-element floating-point cast
131+
132+
typedef float __m128 __attribute__((__vector_size__(16), __aligned__(16)));
133+
typedef double __m128d __attribute__((__vector_size__(16), __aligned__(16)));
134+
typedef float __v4sf __attribute__((__vector_size__(16)));
135+
typedef double __v2df __attribute__((__vector_size__(16)));
136+
137+
static inline constexpr __m128d
138+
_mm_cvtps_pd(__m128 __a) {
139+
return __builtin_convertvector(__builtin_shufflevector(__a, __a, 0, 1), __v2df);
140+
}
141+
142+
constexpr __m128 kf1 {-1.0f,+2.0f,-3.0f,+4.0f};
143+
constexpr __m128d v_mm_cvtps_pd = _mm_cvtps_pd(kf1);
144+
static_assert(v_mm_cvtps_pd[0] == -1.0 && v_mm_cvtps_pd[1] == +2.0);
145+
}

0 commit comments

Comments
 (0)