Skip to content

Commit 51d0e40

Browse files
authored
[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.
1 parent 5b330a7 commit 51d0e40

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
@@ -3545,8 +3545,8 @@ bool Compiler<Emitter>::VisitConvertVectorExpr(const ConvertVectorExpr *E) {
35453545
QualType ElemType = VT->getElementType();
35463546
PrimType ElemT = classifyPrim(ElemType);
35473547
const Expr *Src = E->getSrcExpr();
3548-
PrimType SrcElemT =
3549-
classifyPrim(Src->getType()->castAs<VectorType>()->getElementType());
3548+
QualType SrcType = Src->getType();
3549+
PrimType SrcElemT = classifyVectorElementType(SrcType);
35503550

35513551
unsigned SrcOffset = this->allocateLocalPrimitive(Src, PT_Ptr, true, false);
35523552
if (!this->visit(Src))
@@ -3559,9 +3559,15 @@ bool Compiler<Emitter>::VisitConvertVectorExpr(const ConvertVectorExpr *E) {
35593559
return false;
35603560
if (!this->emitArrayElemPop(SrcElemT, I, E))
35613561
return false;
3562+
3563+
// Cast to the desired result element type.
35623564
if (SrcElemT != ElemT) {
35633565
if (!this->emitPrimCast(SrcElemT, ElemT, ElemType, E))
35643566
return false;
3567+
} else if (ElemType->isFloatingType() && SrcType != ElemType) {
3568+
const auto *TargetSemantics = &Ctx.getFloatSemantics(ElemType);
3569+
if (!this->emitCastFP(TargetSemantics, getRoundingMode(E), E))
3570+
return false;
35653571
}
35663572
if (!this->emitInitElem(ElemT, I, E))
35673573
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)