diff --git a/clang/include/clang/Basic/BuiltinsX86.td b/clang/include/clang/Basic/BuiltinsX86.td index 044c755d4d7cf..29bb5e89ee516 100644 --- a/clang/include/clang/Basic/BuiltinsX86.td +++ b/clang/include/clang/Basic/BuiltinsX86.td @@ -318,10 +318,8 @@ let Features = "sse4.1", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] def roundsd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2, double>, _Constant int)">; def roundpd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Constant int)">; def dpps : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<4, float>, _Constant char)">; - def dppd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2, double>, _Constant char)">; - def ptestz128 : X86Builtin<"int(_Vector<2, long long int>, _Vector<2, long long int>)">; - def ptestc128 : X86Builtin<"int(_Vector<2, long long int>, _Vector<2, long long int>)">; - def ptestnzc128 : X86Builtin<"int(_Vector<2, long long int>, _Vector<2, long long int>)">; + def dppd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, " + "_Vector<2,double>, _Constant char)">; def mpsadbw128 : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Vector<16, char>, _Constant char)">; def phminposuw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>)">; def vec_ext_v16qi : X86Builtin<"char(_Vector<16, char>, _Constant int)">; @@ -329,6 +327,16 @@ let Features = "sse4.1", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] def vec_set_v4si : X86Builtin<"_Vector<4, int>(_Vector<4, int>, int, _Constant int)">; } +let Features = "sse4.1", + Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { + def ptestz128 + : X86Builtin<"int(_Vector<2, long long int>, _Vector<2, long long int>)">; + def ptestc128 + : X86Builtin<"int(_Vector<2, long long int>, _Vector<2, long long int>)">; + def ptestnzc128 + : X86Builtin<"int(_Vector<2, long long int>, _Vector<2, long long int>)">; +} + let Features = "sse4.1", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { def pblendw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>, _Constant int)">; def blendpd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2, double>, _Constant int)">; @@ -513,8 +521,8 @@ let Features = "avx", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in def roundps256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Constant int)">; } - -let Features = "avx", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { +let Features = "avx", + Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { def vtestzpd : X86Builtin<"int(_Vector<2, double>, _Vector<2, double>)">; def vtestcpd : X86Builtin<"int(_Vector<2, double>, _Vector<2, double>)">; def vtestnzcpd : X86Builtin<"int(_Vector<2, double>, _Vector<2, double>)">; @@ -523,7 +531,8 @@ let Features = "avx", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in def vtestnzcps : X86Builtin<"int(_Vector<4, float>, _Vector<4, float>)">; } -let Features = "avx", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { +let Features = "avx", + Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { def vtestzpd256 : X86Builtin<"int(_Vector<4, double>, _Vector<4, double>)">; def vtestcpd256 : X86Builtin<"int(_Vector<4, double>, _Vector<4, double>)">; def vtestnzcpd256 : X86Builtin<"int(_Vector<4, double>, _Vector<4, double>)">; @@ -533,6 +542,10 @@ let Features = "avx", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in def ptestz256 : X86Builtin<"int(_Vector<4, long long int>, _Vector<4, long long int>)">; def ptestc256 : X86Builtin<"int(_Vector<4, long long int>, _Vector<4, long long int>)">; def ptestnzc256 : X86Builtin<"int(_Vector<4, long long int>, _Vector<4, long long int>)">; +} + +let Features = "avx", + Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { def movmskpd256 : X86Builtin<"int(_Vector<4, double>)">; def movmskps256 : X86Builtin<"int(_Vector<8, float>)">; } diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index 64962ee13d6b0..8de8e935fea70 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -2851,6 +2851,39 @@ static bool interp__builtin_blend(InterpState &S, CodePtr OpPC, return true; } +static bool interp__builtin_ptestz(InterpState &S, CodePtr OpPC, + const CallExpr *Call) { + const Pointer &LHS = S.Stk.pop(); + const Pointer &RHS = S.Stk.pop(); + + assert(LHS.getNumElems() == RHS.getNumElems()); + assert(LHS.getFieldDesc()->isPrimitiveArray() && + RHS.getFieldDesc()->isPrimitiveArray()); + + if (!S.getASTContext().hasSameUnqualifiedType(getElemType(LHS), + getElemType(RHS))) + return false; + + unsigned SourceLen = LHS.getNumElems(); + const QualType ElemQT = getElemType(LHS); + const OptPrimType ElemPT = S.getContext().classify(ElemQT); + + bool Flag = true; + INT_TYPE_SWITCH_NO_BOOL(*ElemPT, { + for (unsigned I = 0; I < SourceLen; ++I) { + const APSInt A = LHS.elem(I).toAPSInt(); + const APSInt B = RHS.elem(I).toAPSInt(); + if ((A & B) != 0) { + Flag = false; + break; + } + } + }); + + pushInteger(S, Flag ? 1 : 0, Call->getType()); + return true; +} + static bool interp__builtin_elementwise_triop( InterpState &S, CodePtr OpPC, const CallExpr *Call, llvm::function_ref @@ -3581,6 +3614,35 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call, return ((APInt)C).isNegative() ? T : F; }); + case X86::BI__builtin_ia32_ptestz128: + return interp__builtin_ptestz(S, OpPC, Call); + + // case X86::BI__builtin_ia32_ptestz256: + + // case X86::BI__builtin_ia32_ptestc128: + // case X86::BI__builtin_ia32_ptestc256: + + // case X86::BI__builtin_ia32_ptestnzc128: + // case X86::BI__builtin_ia32_ptestnzc256: + + // case X86::BI__builtin_ia32_vtestzps: + // case X86::BI__builtin_ia32_vtestzps256: + + // case X86::BI__builtin_ia32_vtestcps: + // case X86::BI__builtin_ia32_vtestcps256: + + // case X86::BI__builtin_ia32_vtestnzcps: + // case X86::BI__builtin_ia32_vtestnzcps256: + + // case X86::BI__builtin_ia32_vtestzpd: + // case X86::BI__builtin_ia32_vtestzpd256: + + // case X86::BI__builtin_ia32_vtestcpd: + // case X86::BI__builtin_ia32_vtestcpd256: + + // case X86::BI__builtin_ia32_vtestnzcpd: + // case X86::BI__builtin_ia32_vtestnzcpd256: + case X86::BI__builtin_ia32_selectb_128: case X86::BI__builtin_ia32_selectb_256: case X86::BI__builtin_ia32_selectb_512: diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 30ae3f8802f14..66280b65d7578 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -12025,6 +12025,56 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) { return Success(APValue(ResultElements.data(), ResultElements.size()), E); } + case X86::BI__builtin_ia32_ptestz128: { + APValue SourceLHS, SourceRHS; + if (!EvaluateAsRValue(Info, E->getArg(0), SourceLHS) || + !EvaluateAsRValue(Info, E->getArg(1), SourceRHS)) + return false; + + unsigned SourceLen = SourceLHS.getVectorLength(); + bool Flag = true; + for (unsigned I = 0; I < SourceLen; ++I) { + const APInt &A = SourceLHS.getVectorElt(I).getInt(); + const APInt &B = SourceRHS.getVectorElt(I).getInt(); + if ((A & B) != 0) { + Flag = false; + break; + } + } + + QualType ResultType = E->getType(); + unsigned BitWidth = Info.Ctx.getIntWidth(ResultType); + bool ResultSigned = ResultType->isUnsignedIntegerOrEnumerationType(); + APSInt Result(APInt(BitWidth, Flag), ResultSigned); + return Success(APValue(Result), E); + } + + // case X86::BI__builtin_ia32_ptestz256: + + // case X86::BI__builtin_ia32_ptestc128: + // case X86::BI__builtin_ia32_ptestc256: + + // case X86::BI__builtin_ia32_ptestnzc128: + // case X86::BI__builtin_ia32_ptestnzc256: + + // case X86::BI__builtin_ia32_vtestzps: + // case X86::BI__builtin_ia32_vtestzps256: + + // case X86::BI__builtin_ia32_vtestcps: + // case X86::BI__builtin_ia32_vtestcps256: + + // case X86::BI__builtin_ia32_vtestnzcps: + // case X86::BI__builtin_ia32_vtestnzcps256: + + // case X86::BI__builtin_ia32_vtestzpd: + // case X86::BI__builtin_ia32_vtestzpd256: + + // case X86::BI__builtin_ia32_vtestcpd: + // case X86::BI__builtin_ia32_vtestcpd256: + + // case X86::BI__builtin_ia32_vtestnzcpd: + // case X86::BI__builtin_ia32_vtestnzcpd256: + case Builtin::BI__builtin_elementwise_ctlz: case Builtin::BI__builtin_elementwise_cttz: { APValue SourceLHS; diff --git a/clang/lib/Headers/avxintrin.h b/clang/lib/Headers/avxintrin.h index a7f70994be9db..b37149709c962 100644 --- a/clang/lib/Headers/avxintrin.h +++ b/clang/lib/Headers/avxintrin.h @@ -2542,9 +2542,8 @@ _mm256_unpacklo_ps(__m256 __a, __m256 __b) { /// \param __b /// A 128-bit vector of [2 x double]. /// \returns the ZF flag in the EFLAGS register. -static __inline int __DEFAULT_FN_ATTRS128 -_mm_testz_pd(__m128d __a, __m128d __b) -{ +static __inline int __DEFAULT_FN_ATTRS128_CONSTEXPR _mm_testz_pd(__m128d __a, + __m128d __b) { return __builtin_ia32_vtestzpd((__v2df)__a, (__v2df)__b); } @@ -2571,9 +2570,8 @@ _mm_testz_pd(__m128d __a, __m128d __b) /// \param __b /// A 128-bit vector of [2 x double]. /// \returns the CF flag in the EFLAGS register. -static __inline int __DEFAULT_FN_ATTRS128 -_mm_testc_pd(__m128d __a, __m128d __b) -{ +static __inline int __DEFAULT_FN_ATTRS128_CONSTEXPR _mm_testc_pd(__m128d __a, + __m128d __b) { return __builtin_ia32_vtestcpd((__v2df)__a, (__v2df)__b); } @@ -2601,9 +2599,8 @@ _mm_testc_pd(__m128d __a, __m128d __b) /// \param __b /// A 128-bit vector of [2 x double]. /// \returns 1 if both the ZF and CF flags are set to 0, otherwise returns 0. -static __inline int __DEFAULT_FN_ATTRS128 -_mm_testnzc_pd(__m128d __a, __m128d __b) -{ +static __inline int __DEFAULT_FN_ATTRS128_CONSTEXPR +_mm_testnzc_pd(__m128d __a, __m128d __b) { return __builtin_ia32_vtestnzcpd((__v2df)__a, (__v2df)__b); } @@ -2630,9 +2627,8 @@ _mm_testnzc_pd(__m128d __a, __m128d __b) /// \param __b /// A 128-bit vector of [4 x float]. /// \returns the ZF flag. -static __inline int __DEFAULT_FN_ATTRS128 -_mm_testz_ps(__m128 __a, __m128 __b) -{ +static __inline int __DEFAULT_FN_ATTRS128_CONSTEXPR _mm_testz_ps(__m128 __a, + __m128 __b) { return __builtin_ia32_vtestzps((__v4sf)__a, (__v4sf)__b); } @@ -2659,9 +2655,8 @@ _mm_testz_ps(__m128 __a, __m128 __b) /// \param __b /// A 128-bit vector of [4 x float]. /// \returns the CF flag. -static __inline int __DEFAULT_FN_ATTRS128 -_mm_testc_ps(__m128 __a, __m128 __b) -{ +static __inline int __DEFAULT_FN_ATTRS128_CONSTEXPR _mm_testc_ps(__m128 __a, + __m128 __b) { return __builtin_ia32_vtestcps((__v4sf)__a, (__v4sf)__b); } @@ -2689,9 +2684,8 @@ _mm_testc_ps(__m128 __a, __m128 __b) /// \param __b /// A 128-bit vector of [4 x float]. /// \returns 1 if both the ZF and CF flags are set to 0, otherwise returns 0. -static __inline int __DEFAULT_FN_ATTRS128 -_mm_testnzc_ps(__m128 __a, __m128 __b) -{ +static __inline int __DEFAULT_FN_ATTRS128_CONSTEXPR _mm_testnzc_ps(__m128 __a, + __m128 __b) { return __builtin_ia32_vtestnzcps((__v4sf)__a, (__v4sf)__b); } @@ -2718,9 +2712,8 @@ _mm_testnzc_ps(__m128 __a, __m128 __b) /// \param __b /// A 256-bit vector of [4 x double]. /// \returns the ZF flag. -static __inline int __DEFAULT_FN_ATTRS -_mm256_testz_pd(__m256d __a, __m256d __b) -{ +static __inline int __DEFAULT_FN_ATTRS_CONSTEXPR _mm256_testz_pd(__m256d __a, + __m256d __b) { return __builtin_ia32_vtestzpd256((__v4df)__a, (__v4df)__b); } @@ -2747,9 +2740,8 @@ _mm256_testz_pd(__m256d __a, __m256d __b) /// \param __b /// A 256-bit vector of [4 x double]. /// \returns the CF flag. -static __inline int __DEFAULT_FN_ATTRS -_mm256_testc_pd(__m256d __a, __m256d __b) -{ +static __inline int __DEFAULT_FN_ATTRS_CONSTEXPR _mm256_testc_pd(__m256d __a, + __m256d __b) { return __builtin_ia32_vtestcpd256((__v4df)__a, (__v4df)__b); } @@ -2777,9 +2769,8 @@ _mm256_testc_pd(__m256d __a, __m256d __b) /// \param __b /// A 256-bit vector of [4 x double]. /// \returns 1 if both the ZF and CF flags are set to 0, otherwise returns 0. -static __inline int __DEFAULT_FN_ATTRS -_mm256_testnzc_pd(__m256d __a, __m256d __b) -{ +static __inline int __DEFAULT_FN_ATTRS_CONSTEXPR +_mm256_testnzc_pd(__m256d __a, __m256d __b) { return __builtin_ia32_vtestnzcpd256((__v4df)__a, (__v4df)__b); } @@ -2806,9 +2797,8 @@ _mm256_testnzc_pd(__m256d __a, __m256d __b) /// \param __b /// A 256-bit vector of [8 x float]. /// \returns the ZF flag. -static __inline int __DEFAULT_FN_ATTRS -_mm256_testz_ps(__m256 __a, __m256 __b) -{ +static __inline int __DEFAULT_FN_ATTRS_CONSTEXPR _mm256_testz_ps(__m256 __a, + __m256 __b) { return __builtin_ia32_vtestzps256((__v8sf)__a, (__v8sf)__b); } @@ -2835,9 +2825,8 @@ _mm256_testz_ps(__m256 __a, __m256 __b) /// \param __b /// A 256-bit vector of [8 x float]. /// \returns the CF flag. -static __inline int __DEFAULT_FN_ATTRS -_mm256_testc_ps(__m256 __a, __m256 __b) -{ +static __inline int __DEFAULT_FN_ATTRS_CONSTEXPR _mm256_testc_ps(__m256 __a, + __m256 __b) { return __builtin_ia32_vtestcps256((__v8sf)__a, (__v8sf)__b); } @@ -2865,9 +2854,8 @@ _mm256_testc_ps(__m256 __a, __m256 __b) /// \param __b /// A 256-bit vector of [8 x float]. /// \returns 1 if both the ZF and CF flags are set to 0, otherwise returns 0. -static __inline int __DEFAULT_FN_ATTRS -_mm256_testnzc_ps(__m256 __a, __m256 __b) -{ +static __inline int __DEFAULT_FN_ATTRS_CONSTEXPR _mm256_testnzc_ps(__m256 __a, + __m256 __b) { return __builtin_ia32_vtestnzcps256((__v8sf)__a, (__v8sf)__b); } @@ -2891,9 +2879,8 @@ _mm256_testnzc_ps(__m256 __a, __m256 __b) /// \param __b /// A 256-bit integer vector. /// \returns the ZF flag. -static __inline int __DEFAULT_FN_ATTRS -_mm256_testz_si256(__m256i __a, __m256i __b) -{ +static __inline int __DEFAULT_FN_ATTRS_CONSTEXPR +_mm256_testz_si256(__m256i __a, __m256i __b) { return __builtin_ia32_ptestz256((__v4di)__a, (__v4di)__b); } @@ -2917,9 +2904,8 @@ _mm256_testz_si256(__m256i __a, __m256i __b) /// \param __b /// A 256-bit integer vector. /// \returns the CF flag. -static __inline int __DEFAULT_FN_ATTRS -_mm256_testc_si256(__m256i __a, __m256i __b) -{ +static __inline int __DEFAULT_FN_ATTRS_CONSTEXPR +_mm256_testc_si256(__m256i __a, __m256i __b) { return __builtin_ia32_ptestc256((__v4di)__a, (__v4di)__b); } @@ -2944,9 +2930,8 @@ _mm256_testc_si256(__m256i __a, __m256i __b) /// \param __b /// A 256-bit integer vector. /// \returns 1 if both the ZF and CF flags are set to 0, otherwise returns 0. -static __inline int __DEFAULT_FN_ATTRS -_mm256_testnzc_si256(__m256i __a, __m256i __b) -{ +static __inline int __DEFAULT_FN_ATTRS_CONSTEXPR +_mm256_testnzc_si256(__m256i __a, __m256i __b) { return __builtin_ia32_ptestnzc256((__v4di)__a, (__v4di)__b); } diff --git a/clang/lib/Headers/smmintrin.h b/clang/lib/Headers/smmintrin.h index 6319fdbbeb8f0..062e831259c7f 100644 --- a/clang/lib/Headers/smmintrin.h +++ b/clang/lib/Headers/smmintrin.h @@ -1093,8 +1093,8 @@ _mm_max_epu32(__m128i __V1, __m128i __V2) { /// \param __V /// A 128-bit integer vector selecting which bits to test in operand \a __M. /// \returns TRUE if the specified bits are all zeros; FALSE otherwise. -static __inline__ int __DEFAULT_FN_ATTRS _mm_testz_si128(__m128i __M, - __m128i __V) { +static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR +_mm_testz_si128(__m128i __M, __m128i __V) { return __builtin_ia32_ptestz128((__v2di)__M, (__v2di)__V); } @@ -1110,8 +1110,8 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_testz_si128(__m128i __M, /// \param __V /// A 128-bit integer vector selecting which bits to test in operand \a __M. /// \returns TRUE if the specified bits are all ones; FALSE otherwise. -static __inline__ int __DEFAULT_FN_ATTRS _mm_testc_si128(__m128i __M, - __m128i __V) { +static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR +_mm_testc_si128(__m128i __M, __m128i __V) { return __builtin_ia32_ptestc128((__v2di)__M, (__v2di)__V); } @@ -1128,8 +1128,8 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_testc_si128(__m128i __M, /// A 128-bit integer vector selecting which bits to test in operand \a __M. /// \returns TRUE if the specified bits are neither all zeros nor all ones; /// FALSE otherwise. -static __inline__ int __DEFAULT_FN_ATTRS _mm_testnzc_si128(__m128i __M, - __m128i __V) { +static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR +_mm_testnzc_si128(__m128i __M, __m128i __V) { return __builtin_ia32_ptestnzc128((__v2di)__M, (__v2di)__V); } diff --git a/clang/test/CodeGen/X86/sse41-builtins.c b/clang/test/CodeGen/X86/sse41-builtins.c index c7265b188d572..0073a474c9b85 100644 --- a/clang/test/CodeGen/X86/sse41-builtins.c +++ b/clang/test/CodeGen/X86/sse41-builtins.c @@ -471,3 +471,4 @@ int test_mm_testz_si128(__m128i x, __m128i y) { // CHECK: call {{.*}}i32 @llvm.x86.sse41.ptestz(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) return _mm_testz_si128(x, y); } +TEST_CONSTEXPR(_mm_testz_si128((__m128i)(__v2di){0,0}, (__m128i)(__v2di){0,0}) == 1);