From: Craig Topper Date: Fri, 23 Sep 2016 04:48:31 +0000 (+0000) Subject: [AVX-512] Add initial support for checking rounding mode arguments of builtins. X-Git-Tag: llvmorg-4.0.0-rc1~9089 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a7e253e8fb064596d0d1ac43ff315652afe043ca;p=platform%2Fupstream%2Fllvm.git [AVX-512] Add initial support for checking rounding mode arguments of builtins. The backend can't encode all possible values of the argument and will fail isel. Checking in the frontend presents a friendlier experience to the user. I started with builtins that can only take _MM_CUR_DIRECTION or _MM_NO_EXC. More builtins coming in the future. llvm-svn: 282228 --- diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 6090fc705361..a317c65eb77a 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -7722,6 +7722,8 @@ def err_ppc_builtin_only_on_pwr7 : Error< "this builtin is only valid on POWER7 or later CPUs">; def err_x86_builtin_32_bit_tgt : Error< "this builtin is only available on x86-64 targets">; +def err_x86_builtin_invalid_rounding : Error< + "invalid rounding argument">; def err_builtin_longjmp_unsupported : Error< "__builtin_longjmp is not supported for the current target">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 9c2030b58601..1ae2004a6fe9 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -9482,6 +9482,7 @@ private: bool CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckX86BuiltinRoundingOrSAE(unsigned BuiltinID, CallExpr *TheCall); bool CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckPPCBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 437c77908a2d..7ea34f989085 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -1642,6 +1642,102 @@ static bool isX86_64Builtin(unsigned BuiltinID) { return false; } +// Check if the rounding mode is legal. +bool Sema::CheckX86BuiltinRoundingOrSAE(unsigned BuiltinID, CallExpr *TheCall) { + // Indicates if this instruction has rounding control or just SAE. + bool HasRC = false; + + unsigned ArgNum = 0; + switch (BuiltinID) { + default: + return false; + case X86::BI__builtin_ia32_vcvttsd2si32: + case X86::BI__builtin_ia32_vcvttsd2si64: + case X86::BI__builtin_ia32_vcvttsd2usi32: + case X86::BI__builtin_ia32_vcvttsd2usi64: + case X86::BI__builtin_ia32_vcvttss2si32: + case X86::BI__builtin_ia32_vcvttss2si64: + case X86::BI__builtin_ia32_vcvttss2usi32: + case X86::BI__builtin_ia32_vcvttss2usi64: + ArgNum = 1; + break; + case X86::BI__builtin_ia32_cvtps2pd512_mask: + case X86::BI__builtin_ia32_cvttpd2dq512_mask: + case X86::BI__builtin_ia32_cvttpd2qq512_mask: + case X86::BI__builtin_ia32_cvttpd2udq512_mask: + case X86::BI__builtin_ia32_cvttpd2uqq512_mask: + case X86::BI__builtin_ia32_cvttps2dq512_mask: + case X86::BI__builtin_ia32_cvttps2qq512_mask: + case X86::BI__builtin_ia32_cvttps2udq512_mask: + case X86::BI__builtin_ia32_cvttps2uqq512_mask: + case X86::BI__builtin_ia32_exp2pd_mask: + case X86::BI__builtin_ia32_exp2ps_mask: + case X86::BI__builtin_ia32_getexppd512_mask: + case X86::BI__builtin_ia32_getexpps512_mask: + case X86::BI__builtin_ia32_rcp28pd_mask: + case X86::BI__builtin_ia32_rcp28ps_mask: + case X86::BI__builtin_ia32_rsqrt28pd_mask: + case X86::BI__builtin_ia32_rsqrt28ps_mask: + case X86::BI__builtin_ia32_vcomisd: + case X86::BI__builtin_ia32_vcomiss: + case X86::BI__builtin_ia32_vcvtph2ps512_mask: + ArgNum = 3; + break; + case X86::BI__builtin_ia32_cmppd512_mask: + case X86::BI__builtin_ia32_cmpps512_mask: + case X86::BI__builtin_ia32_cmpsd_mask: + case X86::BI__builtin_ia32_cmpss_mask: + case X86::BI__builtin_ia32_getexpsd128_round_mask: + case X86::BI__builtin_ia32_getexpss128_round_mask: + case X86::BI__builtin_ia32_rcp28sd_round_mask: + case X86::BI__builtin_ia32_rcp28ss_round_mask: + case X86::BI__builtin_ia32_reducepd512_mask: + case X86::BI__builtin_ia32_reduceps512_mask: + case X86::BI__builtin_ia32_rndscalepd_mask: + case X86::BI__builtin_ia32_rndscaleps_mask: + case X86::BI__builtin_ia32_rsqrt28sd_round_mask: + case X86::BI__builtin_ia32_rsqrt28ss_round_mask: + ArgNum = 4; + break; + case X86::BI__builtin_ia32_fixupimmpd512_mask: + case X86::BI__builtin_ia32_fixupimmps512_mask: + case X86::BI__builtin_ia32_fixupimmsd_mask: + case X86::BI__builtin_ia32_fixupimmss_mask: + case X86::BI__builtin_ia32_rangepd512_mask: + case X86::BI__builtin_ia32_rangeps512_mask: + case X86::BI__builtin_ia32_rangesd128_round_mask: + case X86::BI__builtin_ia32_rangess128_round_mask: + case X86::BI__builtin_ia32_reducesd_mask: + case X86::BI__builtin_ia32_reducess_mask: + case X86::BI__builtin_ia32_rndscalesd_round_mask: + case X86::BI__builtin_ia32_rndscaless_round_mask: + ArgNum = 5; + break; + } + + llvm::APSInt Result; + + // We can't check the value of a dependent argument. + Expr *Arg = TheCall->getArg(ArgNum); + if (Arg->isTypeDependent() || Arg->isValueDependent()) + return false; + + // Check constant-ness first. + if (SemaBuiltinConstantArg(TheCall, ArgNum, Result)) + return true; + + // Make sure rounding mode is either ROUND_CUR_DIRECTION or ROUND_NO_EXC bit + // is set. If the intrinsic has rounding control(bits 1:0), make sure its only + // combined with ROUND_NO_EXC. + if (Result == 4/*ROUND_CUR_DIRECTION*/ || + Result == 8/*ROUND_NO_EXC*/ || + (HasRC && Result.getZExtValue() >= 8 && Result.getZExtValue() <= 11)) + return false; + + return Diag(TheCall->getLocStart(), diag::err_x86_builtin_invalid_rounding) + << Arg->getSourceRange(); +} + bool Sema::CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { if (BuiltinID == X86::BI__builtin_cpu_supports) return SemaBuiltinCpuSupports(*this, TheCall); @@ -1655,6 +1751,10 @@ bool Sema::CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return Diag(TheCall->getCallee()->getLocStart(), diag::err_x86_builtin_32_bit_tgt); + // If the intrinsic has rounding or SAE make sure its valid. + if (CheckX86BuiltinRoundingOrSAE(BuiltinID, TheCall)) + return true; + // For intrinsics which take an immediate value as part of the instruction, // range check them here. int i = 0, l = 0, u = 0; diff --git a/clang/test/Sema/builtins-x86.c b/clang/test/Sema/builtins-x86.c index 4cd5c28f436d..6929dcc65090 100644 --- a/clang/test/Sema/builtins-x86.c +++ b/clang/test/Sema/builtins-x86.c @@ -65,3 +65,7 @@ __m128i test__builtin_ia32_vpcomd(__m128i __a, __m128i __b) { __m128i test__builtin_ia32_vpcomq(__m128i __a, __m128i __b) { __builtin_ia32_vpcomuq(__a, __b, 8); // expected-error {{argument should be a value from 0 to 7}} } + +__mmask16 test__builtin_ia32_cmpps512_mask_rounding(__m512 __a, __m512 __b, __mmask16 __u) { + __builtin_ia32_cmpps512_mask(__a, __b, 0, __u, 0); // expected-error {{invalid rounding argument}} +}