https://github.com/ckoparkar updated https://github.com/llvm/llvm-project/pull/153572
>From 487266d5e53ff7d0aa57c26377c2443bc734b4fd Mon Sep 17 00:00:00 2001 From: Chaitanya Koparkar <ckopar...@gmail.com> Date: Wed, 13 Aug 2025 08:13:03 -0400 Subject: [PATCH 1/2] [Clang] Enable constexpr handling for builtin elementwise fshl/fshr --- clang/include/clang/Basic/Builtins.td | 4 +- clang/lib/AST/ByteCode/InterpBuiltin.cpp | 80 ++++++++++++++++++++ clang/lib/AST/ExprConstant.cpp | 56 ++++++++++++++ clang/test/Sema/constant-builtins-vector.cpp | 48 ++++++++++++ 4 files changed, 186 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 6d21c620bfc80..6f891f6761f1c 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -1528,13 +1528,13 @@ def ElementwiseSubSat : Builtin { def ElementwiseFshl : Builtin { let Spellings = ["__builtin_elementwise_fshl"]; - let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr]; let Prototype = "void(...)"; } def ElementwiseFshr : Builtin { let Spellings = ["__builtin_elementwise_fshr"]; - let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr]; let Prototype = "void(...)"; } diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index 2e28814abfddb..08948ca45c9a4 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -2813,7 +2813,83 @@ static bool interp__builtin_select(InterpState &S, CodePtr OpPC, } } Dst.initializeAllElements(); + return true; +} + +static bool interp__builtin_elementwise_fsh(InterpState &S, CodePtr OpPC, + const CallExpr *Call, + unsigned BuiltinID) { + assert(Call->getNumArgs() == 3); + + const QualType Arg1Type = Call->getArg(0)->getType(); + const QualType Arg2Type = Call->getArg(1)->getType(); + const QualType Arg3Type = Call->getArg(2)->getType(); + + // Non-vector integer types. + if (!Arg1Type->isVectorType()) { + assert(!Arg2Type->isVectorType()); + assert(!Arg3Type->isVectorType()); + + APSInt Shift = popToAPSInt( + S.Stk, *S.getContext().classify(Call->getArg(2)->getType())); + APSInt Lo = popToAPSInt( + S.Stk, *S.getContext().classify(Call->getArg(1)->getType())); + APSInt Hi = popToAPSInt( + S.Stk, *S.getContext().classify(Call->getArg(0)->getType())); + APSInt Result; + if (BuiltinID == Builtin::BI__builtin_elementwise_fshl) { + Result = APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned()); + } else if (BuiltinID == Builtin::BI__builtin_elementwise_fshr) { + Result = APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned()); + } else { + llvm_unreachable("Wrong builtin ID"); + } + pushInteger(S, Result, Call->getType()); + return true; + } + + // Vector type. + assert(Arg1Type->isVectorType() && + Arg2Type->isVectorType() && + Arg3Type->isVectorType()); + + const VectorType *VecT = Arg1Type->castAs<VectorType>(); + PrimType ElemT = *S.getContext().classify(VecT->getElementType()); + unsigned NumElems = VecT->getNumElements(); + + assert(VecT->getElementType() == + Arg2Type->castAs<VectorType>()->getElementType() && + VecT->getElementType() == + Arg3Type->castAs<VectorType>()->getElementType()); + assert(NumElems == Arg2Type->castAs<VectorType>()->getNumElements() && + NumElems == Arg3Type->castAs<VectorType>()->getNumElements()); + assert(VecT->getElementType()->isIntegralOrEnumerationType()); + const Pointer &VecShift = S.Stk.pop<Pointer>(); + const Pointer &VecLo = S.Stk.pop<Pointer>(); + const Pointer &VecHi = S.Stk.pop<Pointer>(); + const Pointer &Dst = S.Stk.peek<Pointer>(); + for (unsigned I = 0; I != NumElems; ++I) { + APSInt Hi; + APSInt Lo; + APSInt Shift; + INT_TYPE_SWITCH_NO_BOOL(ElemT, { + Hi = VecHi.elem<T>(I).toAPSInt(); + Lo = VecLo.elem<T>(I).toAPSInt(); + Shift = VecShift.elem<T>(I).toAPSInt(); + }); + APSInt Result; + if (BuiltinID == Builtin::BI__builtin_elementwise_fshl) { + Result = APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned()); + } else if (BuiltinID == Builtin::BI__builtin_elementwise_fshr) { + Result = APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned()); + } else { + llvm_unreachable("Wrong builtin ID"); + } + INT_TYPE_SWITCH_NO_BOOL(ElemT, + { Dst.elem<T>(I) = static_cast<T>(Result); }); + } + Dst.initializeAllElements(); return true; } @@ -3279,6 +3355,10 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call, case X86::BI__builtin_ia32_selectpd_512: return interp__builtin_select(S, OpPC, Call); + case Builtin::BI__builtin_elementwise_fshl: + case Builtin::BI__builtin_elementwise_fshr: + return interp__builtin_elementwise_fsh(S, OpPC, Call, BuiltinID); + default: S.FFDiag(S.Current->getLocation(OpPC), diag::note_invalid_subexpr_in_const_expr) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 9b934753bcc3c..6d268e97c38d2 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -11941,6 +11941,40 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) { } return Success(APValue(ResultElements.data(), ResultElements.size()), E); } + + case Builtin::BI__builtin_elementwise_fshl: + case Builtin::BI__builtin_elementwise_fshr: { + APValue SourceHi, SourceLo, SourceShift; + if (!EvaluateAsRValue(Info, E->getArg(0), SourceHi) || + !EvaluateAsRValue(Info, E->getArg(1), SourceLo) || + !EvaluateAsRValue(Info, E->getArg(2), SourceShift)) + return false; + + QualType DestEltTy = E->getType()->castAs<VectorType>()->getElementType(); + + if (!DestEltTy->isIntegerType()) + return false; + + unsigned SourceLen = SourceHi.getVectorLength(); + SmallVector<APValue> ResultElements; + ResultElements.reserve(SourceLen); + + for (unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) { + APSInt Hi = SourceHi.getVectorElt(EltNum).getInt(); + APSInt Lo = SourceLo.getVectorElt(EltNum).getInt(); + APSInt Shift = SourceShift.getVectorElt(EltNum).getInt(); + switch (E->getBuiltinCallee()) { + case Builtin::BI__builtin_elementwise_fshl: + ResultElements.push_back(APValue(APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned()))); + break; + case Builtin::BI__builtin_elementwise_fshr: + ResultElements.push_back(APValue(APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned()))); + break; + } + } + + return Success(APValue(ResultElements.data(), ResultElements.size()), E); + } } } @@ -13879,6 +13913,28 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, APInt Result = std::min(LHS, RHS); return Success(APSInt(Result, !LHS.isSigned()), E); } + case Builtin::BI__builtin_elementwise_fshl: + case Builtin::BI__builtin_elementwise_fshr: { + if (!E->getArg(0)->isPRValue() || + !E->getArg(1)->isPRValue() || + !E->getArg(2)->isPRValue()) + return false; + APSInt Hi, Lo, Shift; + if (!EvaluateInteger(E->getArg(0), Hi, Info) || + !EvaluateInteger(E->getArg(1), Lo, Info) || + !EvaluateInteger(E->getArg(2), Shift, Info)) + return false; + switch (BuiltinOp) { + case Builtin::BI__builtin_elementwise_fshl: { + APSInt Result(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned()); + return Success(Result, E); + } + case Builtin::BI__builtin_elementwise_fshr: { + APSInt Result(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned()); + return Success(Result, E); + } + } + } case Builtin::BIstrlen: case Builtin::BIwcslen: // A call to strlen is not a constant expression. diff --git a/clang/test/Sema/constant-builtins-vector.cpp b/clang/test/Sema/constant-builtins-vector.cpp index 17fa95871740d..a1822e2c3b59c 100644 --- a/clang/test/Sema/constant-builtins-vector.cpp +++ b/clang/test/Sema/constant-builtins-vector.cpp @@ -961,3 +961,51 @@ static_assert(fmaDouble1[3] == 26.0); constexpr float fmaArray[] = {2.0f, 2.0f, 2.0f, 2.0f}; constexpr float fmaResult = __builtin_elementwise_fma(fmaArray[1], fmaArray[2], fmaArray[3]); static_assert(fmaResult == 6.0f, ""); + +static_assert(__builtin_elementwise_fshl((unsigned char)255, (unsigned char)0, (unsigned char)8) == (unsigned char)255); +static_assert(__builtin_elementwise_fshl((char)127, (char)0, (char)8) == (char)127); +static_assert(__builtin_elementwise_fshl((unsigned char)0, (unsigned char)255, (unsigned char)8) == (unsigned char)0); +static_assert(__builtin_elementwise_fshl((char)0, (char)127, (char)8) == (char)0); +static_assert(__builtin_elementwise_fshr((unsigned char)255, (unsigned char)0, (unsigned char)8) == (unsigned char)0); +static_assert(__builtin_elementwise_fshr((char)127, (char)0, (char)8) == (char)0); +static_assert(__builtin_elementwise_fshr((unsigned char)0, (unsigned char)255, (unsigned char)8) == (unsigned char)255); +static_assert(__builtin_elementwise_fshr((char)0, (char)127, (char)8) == (char)127); +static_assert(__builtin_elementwise_fshl((unsigned int)4294967295, (unsigned int)0, (unsigned int)32) == (unsigned int)4294967295); +static_assert(__builtin_elementwise_fshl((int)2147483647, (int)0, (int)32) == (int)2147483647); +static_assert(__builtin_elementwise_fshl((unsigned int)0, (unsigned int)4294967295, (unsigned int)32) == (unsigned int)0); +static_assert(__builtin_elementwise_fshl((int)0, (int)2147483647, (int)32) == (int)0); +static_assert(__builtin_elementwise_fshr((unsigned int)4294967295, (unsigned int)0, (unsigned int)32) == (unsigned int)0); +static_assert(__builtin_elementwise_fshr((int)2147483647, (int)0, (int)32) == (int)0); +static_assert(__builtin_elementwise_fshr((unsigned int)0, (unsigned int)4294967295, (unsigned int)32) == (unsigned int)4294967295); +static_assert(__builtin_elementwise_fshr((int)0, (int)2147483647, (int)32) == (int)2147483647); +static_assert(__builtin_elementwise_fshl((unsigned long long)18446744073709551615ULL, (unsigned long long)0, (unsigned long long)64) == (unsigned long long)18446744073709551615ULL); +static_assert(__builtin_elementwise_fshl((long long)9223372036854775807, (long long)0, (long long)64) == (long long)9223372036854775807); +static_assert(__builtin_elementwise_fshl((unsigned long long)0, (unsigned long long)18446744073709551615ULL, (unsigned long long)64) == (unsigned long long)0); +static_assert(__builtin_elementwise_fshl((long long)0, (long long)9223372036854775807, (long long)64) == (long long)0); +static_assert(__builtin_elementwise_fshr((unsigned long long)18446744073709551615ULL, (unsigned long long)0, (unsigned long long)64) == (unsigned long long)0); +static_assert(__builtin_elementwise_fshr((long long)9223372036854775807, (long long)0, (long long)64) == (long long)0); +static_assert(__builtin_elementwise_fshr((unsigned long long)0, (unsigned long long)18446744073709551615ULL, (unsigned long long)64) == (unsigned long long)18446744073709551615ULL); +static_assert(__builtin_elementwise_fshr((long long)0, (long long)9223372036854775807, (long long)64) == (long long)9223372036854775807); +// +static_assert(__builtin_elementwise_fshl((short) 1, (short) 2, (short) 3) == (short)8); +static_assert(__builtin_elementwise_fshl((short) 2, (short) 1, (short) 3) == (short)16); +static_assert(__builtin_elementwise_fshl(1, 2 , 2) == 4); +static_assert(__builtin_elementwise_fshl(2L, 1L , 2L) == 8L); +static_assert(__builtin_elementwise_fshr((unsigned char)1, (unsigned char)2, (unsigned char)3) == (unsigned char)32); +// +constexpr vector4uchar v4s_fshl_var = + __builtin_elementwise_fshl((vector4uchar){255, 15, 0, 2}, + (vector4uchar){0, 15, 255, 1}, + (vector4uchar){15, 11, 8, 3}); +static_assert(v4s_fshl_var[0] == 128); +static_assert(v4s_fshl_var[1] == 120); +static_assert(v4s_fshl_var[2] == 0); +static_assert(v4s_fshl_var[3] == 16); +constexpr vector4uchar v4s_fshr_var = + __builtin_elementwise_fshr((vector4uchar){255, 15, 0, 1}, + (vector4uchar){0, 15, 255, 2}, + (vector4uchar){15, 11, 8, 3}); +static_assert(v4s_fshr_var[0] == 254); +static_assert(v4s_fshr_var[1] == 225); +static_assert(v4s_fshr_var[2] == 255); +static_assert(v4s_fshr_var[3] == 32); >From c8f71ad0f53205d4aaeb01e2ca4315c8ca7df863 Mon Sep 17 00:00:00 2001 From: Chaitanya Koparkar <ckopar...@gmail.com> Date: Fri, 22 Aug 2025 08:22:37 -0400 Subject: [PATCH 2/2] Edits --- clang/lib/AST/ByteCode/InterpBuiltin.cpp | 60 ++++++++++---------- clang/lib/AST/ExprConstant.cpp | 21 ++++--- clang/test/Sema/constant-builtins-vector.cpp | 4 +- 3 files changed, 42 insertions(+), 43 deletions(-) diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index 08948ca45c9a4..068e1f1284cc5 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -2813,6 +2813,7 @@ static bool interp__builtin_select(InterpState &S, CodePtr OpPC, } } Dst.initializeAllElements(); + return true; } @@ -2821,20 +2822,19 @@ static bool interp__builtin_elementwise_fsh(InterpState &S, CodePtr OpPC, unsigned BuiltinID) { assert(Call->getNumArgs() == 3); - const QualType Arg1Type = Call->getArg(0)->getType(); - const QualType Arg2Type = Call->getArg(1)->getType(); - const QualType Arg3Type = Call->getArg(2)->getType(); + const QualType &Arg1Type = Call->getArg(0)->getType(); + const QualType &Arg2Type = Call->getArg(1)->getType(); + const QualType &Arg3Type = Call->getArg(2)->getType(); // Non-vector integer types. if (!Arg1Type->isVectorType()) { assert(!Arg2Type->isVectorType()); assert(!Arg3Type->isVectorType()); - - APSInt Shift = popToAPSInt( + const APSInt &Shift = popToAPSInt( S.Stk, *S.getContext().classify(Call->getArg(2)->getType())); - APSInt Lo = popToAPSInt( + const APSInt &Lo = popToAPSInt( S.Stk, *S.getContext().classify(Call->getArg(1)->getType())); - APSInt Hi = popToAPSInt( + const APSInt &Hi = popToAPSInt( S.Stk, *S.getContext().classify(Call->getArg(0)->getType())); APSInt Result; if (BuiltinID == Builtin::BI__builtin_elementwise_fshl) { @@ -2849,18 +2849,17 @@ static bool interp__builtin_elementwise_fsh(InterpState &S, CodePtr OpPC, } // Vector type. - assert(Arg1Type->isVectorType() && - Arg2Type->isVectorType() && + assert(Arg1Type->isVectorType() && Arg2Type->isVectorType() && Arg3Type->isVectorType()); const VectorType *VecT = Arg1Type->castAs<VectorType>(); - PrimType ElemT = *S.getContext().classify(VecT->getElementType()); + const PrimType &ElemT = *S.getContext().classify(VecT->getElementType()); unsigned NumElems = VecT->getNumElements(); assert(VecT->getElementType() == - Arg2Type->castAs<VectorType>()->getElementType() && + Arg2Type->castAs<VectorType>()->getElementType() && VecT->getElementType() == - Arg3Type->castAs<VectorType>()->getElementType()); + Arg3Type->castAs<VectorType>()->getElementType()); assert(NumElems == Arg2Type->castAs<VectorType>()->getNumElements() && NumElems == Arg3Type->castAs<VectorType>()->getNumElements()); assert(VecT->getElementType()->isIntegralOrEnumerationType()); @@ -2870,26 +2869,27 @@ static bool interp__builtin_elementwise_fsh(InterpState &S, CodePtr OpPC, const Pointer &VecHi = S.Stk.pop<Pointer>(); const Pointer &Dst = S.Stk.peek<Pointer>(); for (unsigned I = 0; I != NumElems; ++I) { - APSInt Hi; - APSInt Lo; - APSInt Shift; - INT_TYPE_SWITCH_NO_BOOL(ElemT, { - Hi = VecHi.elem<T>(I).toAPSInt(); - Lo = VecLo.elem<T>(I).toAPSInt(); - Shift = VecShift.elem<T>(I).toAPSInt(); - }); - APSInt Result; - if (BuiltinID == Builtin::BI__builtin_elementwise_fshl) { - Result = APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned()); - } else if (BuiltinID == Builtin::BI__builtin_elementwise_fshr) { - Result = APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned()); - } else { - llvm_unreachable("Wrong builtin ID"); - } - INT_TYPE_SWITCH_NO_BOOL(ElemT, - { Dst.elem<T>(I) = static_cast<T>(Result); }); + APSInt Hi; + APSInt Lo; + APSInt Shift; + INT_TYPE_SWITCH_NO_BOOL(ElemT, { + Hi = VecHi.elem<T>(I).toAPSInt(); + Lo = VecLo.elem<T>(I).toAPSInt(); + Shift = VecShift.elem<T>(I).toAPSInt(); + }); + APSInt Result; + if (BuiltinID == Builtin::BI__builtin_elementwise_fshl) { + Result = APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned()); + } else if (BuiltinID == Builtin::BI__builtin_elementwise_fshr) { + Result = APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned()); + } else { + llvm_unreachable("Wrong builtin ID"); + } + INT_TYPE_SWITCH_NO_BOOL(ElemT, + { Dst.elem<T>(I) = static_cast<T>(Result); }); } Dst.initializeAllElements(); + return true; } diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 6d268e97c38d2..3612cf53c84d7 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -11950,7 +11950,8 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) { !EvaluateAsRValue(Info, E->getArg(2), SourceShift)) return false; - QualType DestEltTy = E->getType()->castAs<VectorType>()->getElementType(); + const QualType &DestEltTy = + E->getType()->castAs<VectorType>()->getElementType(); if (!DestEltTy->isIntegerType()) return false; @@ -11958,17 +11959,18 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) { unsigned SourceLen = SourceHi.getVectorLength(); SmallVector<APValue> ResultElements; ResultElements.reserve(SourceLen); - for (unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) { - APSInt Hi = SourceHi.getVectorElt(EltNum).getInt(); - APSInt Lo = SourceLo.getVectorElt(EltNum).getInt(); - APSInt Shift = SourceShift.getVectorElt(EltNum).getInt(); + const APSInt &Hi = SourceHi.getVectorElt(EltNum).getInt(); + const APSInt &Lo = SourceLo.getVectorElt(EltNum).getInt(); + const APSInt &Shift = SourceShift.getVectorElt(EltNum).getInt(); switch (E->getBuiltinCallee()) { case Builtin::BI__builtin_elementwise_fshl: - ResultElements.push_back(APValue(APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned()))); + ResultElements.push_back(APValue( + APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned()))); break; case Builtin::BI__builtin_elementwise_fshr: - ResultElements.push_back(APValue(APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned()))); + ResultElements.push_back(APValue( + APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned()))); break; } } @@ -13915,15 +13917,12 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, } case Builtin::BI__builtin_elementwise_fshl: case Builtin::BI__builtin_elementwise_fshr: { - if (!E->getArg(0)->isPRValue() || - !E->getArg(1)->isPRValue() || - !E->getArg(2)->isPRValue()) - return false; APSInt Hi, Lo, Shift; if (!EvaluateInteger(E->getArg(0), Hi, Info) || !EvaluateInteger(E->getArg(1), Lo, Info) || !EvaluateInteger(E->getArg(2), Shift, Info)) return false; + switch (BuiltinOp) { case Builtin::BI__builtin_elementwise_fshl: { APSInt Result(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned()); diff --git a/clang/test/Sema/constant-builtins-vector.cpp b/clang/test/Sema/constant-builtins-vector.cpp index a1822e2c3b59c..714a7fb753214 100644 --- a/clang/test/Sema/constant-builtins-vector.cpp +++ b/clang/test/Sema/constant-builtins-vector.cpp @@ -986,13 +986,11 @@ static_assert(__builtin_elementwise_fshr((unsigned long long)1844674407370955161 static_assert(__builtin_elementwise_fshr((long long)9223372036854775807, (long long)0, (long long)64) == (long long)0); static_assert(__builtin_elementwise_fshr((unsigned long long)0, (unsigned long long)18446744073709551615ULL, (unsigned long long)64) == (unsigned long long)18446744073709551615ULL); static_assert(__builtin_elementwise_fshr((long long)0, (long long)9223372036854775807, (long long)64) == (long long)9223372036854775807); -// static_assert(__builtin_elementwise_fshl((short) 1, (short) 2, (short) 3) == (short)8); static_assert(__builtin_elementwise_fshl((short) 2, (short) 1, (short) 3) == (short)16); static_assert(__builtin_elementwise_fshl(1, 2 , 2) == 4); static_assert(__builtin_elementwise_fshl(2L, 1L , 2L) == 8L); static_assert(__builtin_elementwise_fshr((unsigned char)1, (unsigned char)2, (unsigned char)3) == (unsigned char)32); -// constexpr vector4uchar v4s_fshl_var = __builtin_elementwise_fshl((vector4uchar){255, 15, 0, 2}, (vector4uchar){0, 15, 255, 1}, @@ -1009,3 +1007,5 @@ static_assert(v4s_fshr_var[0] == 254); static_assert(v4s_fshr_var[1] == 225); static_assert(v4s_fshr_var[2] == 255); static_assert(v4s_fshr_var[3] == 32); +static_assert(__builtin_elementwise_fshl(v4s_fshl_var[0], v4s_fshl_var[1], v4s_fshl_var[2]) == 128); +static_assert(__builtin_elementwise_fshr(v4s_fshr_var[0], v4s_fshr_var[1], v4s_fshr_var[2]) == 253); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits