| //===------ SemaX86.cpp ---------- X86 target-specific routines -----------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file implements semantic analysis functions specific to X86. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "clang/Sema/SemaX86.h" |
| #include "clang/Basic/DiagnosticSema.h" |
| #include "clang/Basic/TargetBuiltins.h" |
| #include "clang/Basic/TargetInfo.h" |
| #include "clang/Sema/Attr.h" |
| #include "clang/Sema/ParsedAttr.h" |
| #include "clang/Sema/Sema.h" |
| #include "llvm/ADT/APSInt.h" |
| #include "llvm/TargetParser/Triple.h" |
| #include <bitset> |
| |
| namespace clang { |
| |
| SemaX86::SemaX86(Sema &S) : SemaBase(S) {} |
| |
| // Check if the rounding mode is legal. |
| bool SemaX86::CheckBuiltinRoundingOrSAE(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: |
| case X86::BI__builtin_ia32_vcvttsh2si32: |
| case X86::BI__builtin_ia32_vcvttsh2si64: |
| case X86::BI__builtin_ia32_vcvttsh2usi32: |
| case X86::BI__builtin_ia32_vcvttsh2usi64: |
| case X86::BI__builtin_ia32_vcvttsd2sis32: |
| case X86::BI__builtin_ia32_vcvttsd2usis32: |
| case X86::BI__builtin_ia32_vcvttss2sis32: |
| case X86::BI__builtin_ia32_vcvttss2usis32: |
| case X86::BI__builtin_ia32_vcvttsd2sis64: |
| case X86::BI__builtin_ia32_vcvttsd2usis64: |
| case X86::BI__builtin_ia32_vcvttss2sis64: |
| case X86::BI__builtin_ia32_vcvttss2usis64: |
| ArgNum = 1; |
| break; |
| case X86::BI__builtin_ia32_maxpd512: |
| case X86::BI__builtin_ia32_maxps512: |
| case X86::BI__builtin_ia32_minpd512: |
| case X86::BI__builtin_ia32_minps512: |
| case X86::BI__builtin_ia32_maxph512: |
| case X86::BI__builtin_ia32_minph512: |
| case X86::BI__builtin_ia32_vmaxpd256_round: |
| case X86::BI__builtin_ia32_vmaxps256_round: |
| case X86::BI__builtin_ia32_vminpd256_round: |
| case X86::BI__builtin_ia32_vminps256_round: |
| case X86::BI__builtin_ia32_vmaxph256_round: |
| case X86::BI__builtin_ia32_vminph256_round: |
| ArgNum = 2; |
| break; |
| case X86::BI__builtin_ia32_vcvtph2pd512_mask: |
| case X86::BI__builtin_ia32_vcvtph2psx512_mask: |
| 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_vcvttph2w512_mask: |
| case X86::BI__builtin_ia32_vcvttph2uw512_mask: |
| case X86::BI__builtin_ia32_vcvttph2dq512_mask: |
| case X86::BI__builtin_ia32_vcvttph2udq512_mask: |
| case X86::BI__builtin_ia32_vcvttph2qq512_mask: |
| case X86::BI__builtin_ia32_vcvttph2uqq512_mask: |
| case X86::BI__builtin_ia32_getexppd512_mask: |
| case X86::BI__builtin_ia32_getexpps512_mask: |
| case X86::BI__builtin_ia32_getexpph512_mask: |
| case X86::BI__builtin_ia32_vcomisd: |
| case X86::BI__builtin_ia32_vcomiss: |
| case X86::BI__builtin_ia32_vcomish: |
| case X86::BI__builtin_ia32_vcvtph2ps512_mask: |
| case X86::BI__builtin_ia32_vgetexppd256_round_mask: |
| case X86::BI__builtin_ia32_vgetexpps256_round_mask: |
| case X86::BI__builtin_ia32_vgetexpph256_round_mask: |
| case X86::BI__builtin_ia32_vcvttph2ibs256_mask: |
| case X86::BI__builtin_ia32_vcvttph2iubs256_mask: |
| case X86::BI__builtin_ia32_vcvttps2ibs256_mask: |
| case X86::BI__builtin_ia32_vcvttps2iubs256_mask: |
| case X86::BI__builtin_ia32_vcvttph2ibs512_mask: |
| case X86::BI__builtin_ia32_vcvttph2iubs512_mask: |
| case X86::BI__builtin_ia32_vcvttps2ibs512_mask: |
| case X86::BI__builtin_ia32_vcvttps2iubs512_mask: |
| ArgNum = 3; |
| break; |
| case X86::BI__builtin_ia32_cmppd512_mask: |
| case X86::BI__builtin_ia32_cmpps512_mask: |
| case X86::BI__builtin_ia32_cmpph512_mask: |
| case X86::BI__builtin_ia32_vcmppd256_round_mask: |
| case X86::BI__builtin_ia32_vcmpps256_round_mask: |
| case X86::BI__builtin_ia32_vcmpph256_round_mask: |
| case X86::BI__builtin_ia32_cmpsd_mask: |
| case X86::BI__builtin_ia32_cmpss_mask: |
| case X86::BI__builtin_ia32_cmpsh_mask: |
| case X86::BI__builtin_ia32_vcvtsh2sd_round_mask: |
| case X86::BI__builtin_ia32_vcvtsh2ss_round_mask: |
| case X86::BI__builtin_ia32_cvtss2sd_round_mask: |
| case X86::BI__builtin_ia32_getexpsd128_round_mask: |
| case X86::BI__builtin_ia32_getexpss128_round_mask: |
| case X86::BI__builtin_ia32_getexpsh128_round_mask: |
| case X86::BI__builtin_ia32_getmantpd512_mask: |
| case X86::BI__builtin_ia32_getmantps512_mask: |
| case X86::BI__builtin_ia32_getmantph512_mask: |
| case X86::BI__builtin_ia32_vgetmantpd256_round_mask: |
| case X86::BI__builtin_ia32_vgetmantps256_round_mask: |
| case X86::BI__builtin_ia32_vgetmantph256_round_mask: |
| case X86::BI__builtin_ia32_maxsd_round_mask: |
| case X86::BI__builtin_ia32_maxss_round_mask: |
| case X86::BI__builtin_ia32_maxsh_round_mask: |
| case X86::BI__builtin_ia32_minsd_round_mask: |
| case X86::BI__builtin_ia32_minss_round_mask: |
| case X86::BI__builtin_ia32_minsh_round_mask: |
| case X86::BI__builtin_ia32_reducepd512_mask: |
| case X86::BI__builtin_ia32_reduceps512_mask: |
| case X86::BI__builtin_ia32_reduceph512_mask: |
| case X86::BI__builtin_ia32_rndscalepd_mask: |
| case X86::BI__builtin_ia32_rndscaleps_mask: |
| case X86::BI__builtin_ia32_rndscaleph_mask: |
| case X86::BI__builtin_ia32_vreducepd256_round_mask: |
| case X86::BI__builtin_ia32_vreduceps256_round_mask: |
| case X86::BI__builtin_ia32_vreduceph256_round_mask: |
| case X86::BI__builtin_ia32_vrndscalepd256_round_mask: |
| case X86::BI__builtin_ia32_vrndscaleps256_round_mask: |
| case X86::BI__builtin_ia32_vrndscaleph256_round_mask: |
| ArgNum = 4; |
| break; |
| case X86::BI__builtin_ia32_fixupimmpd512_mask: |
| case X86::BI__builtin_ia32_fixupimmpd512_maskz: |
| case X86::BI__builtin_ia32_fixupimmps512_mask: |
| case X86::BI__builtin_ia32_fixupimmps512_maskz: |
| case X86::BI__builtin_ia32_vfixupimmpd256_round_mask: |
| case X86::BI__builtin_ia32_vfixupimmpd256_round_maskz: |
| case X86::BI__builtin_ia32_vfixupimmps256_round_mask: |
| case X86::BI__builtin_ia32_vfixupimmps256_round_maskz: |
| case X86::BI__builtin_ia32_fixupimmsd_mask: |
| case X86::BI__builtin_ia32_fixupimmsd_maskz: |
| case X86::BI__builtin_ia32_fixupimmss_mask: |
| case X86::BI__builtin_ia32_fixupimmss_maskz: |
| case X86::BI__builtin_ia32_getmantsd_round_mask: |
| case X86::BI__builtin_ia32_getmantss_round_mask: |
| case X86::BI__builtin_ia32_getmantsh_round_mask: |
| case X86::BI__builtin_ia32_rangepd512_mask: |
| case X86::BI__builtin_ia32_rangeps512_mask: |
| case X86::BI__builtin_ia32_vrangepd256_round_mask: |
| case X86::BI__builtin_ia32_vrangeps256_round_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_reducesh_mask: |
| case X86::BI__builtin_ia32_rndscalesd_round_mask: |
| case X86::BI__builtin_ia32_rndscaless_round_mask: |
| case X86::BI__builtin_ia32_rndscalesh_round_mask: |
| case X86::BI__builtin_ia32_vminmaxpd256_round_mask: |
| case X86::BI__builtin_ia32_vminmaxps256_round_mask: |
| case X86::BI__builtin_ia32_vminmaxph256_round_mask: |
| case X86::BI__builtin_ia32_vminmaxpd512_round_mask: |
| case X86::BI__builtin_ia32_vminmaxps512_round_mask: |
| case X86::BI__builtin_ia32_vminmaxph512_round_mask: |
| case X86::BI__builtin_ia32_vminmaxsd_round_mask: |
| case X86::BI__builtin_ia32_vminmaxsh_round_mask: |
| case X86::BI__builtin_ia32_vminmaxss_round_mask: |
| ArgNum = 5; |
| break; |
| case X86::BI__builtin_ia32_vcvtsd2si64: |
| case X86::BI__builtin_ia32_vcvtsd2si32: |
| case X86::BI__builtin_ia32_vcvtsd2usi32: |
| case X86::BI__builtin_ia32_vcvtsd2usi64: |
| case X86::BI__builtin_ia32_vcvtss2si32: |
| case X86::BI__builtin_ia32_vcvtss2si64: |
| case X86::BI__builtin_ia32_vcvtss2usi32: |
| case X86::BI__builtin_ia32_vcvtss2usi64: |
| case X86::BI__builtin_ia32_vcvtsh2si32: |
| case X86::BI__builtin_ia32_vcvtsh2si64: |
| case X86::BI__builtin_ia32_vcvtsh2usi32: |
| case X86::BI__builtin_ia32_vcvtsh2usi64: |
| case X86::BI__builtin_ia32_sqrtpd512: |
| case X86::BI__builtin_ia32_sqrtps512: |
| case X86::BI__builtin_ia32_sqrtph512: |
| case X86::BI__builtin_ia32_vsqrtpd256_round: |
| case X86::BI__builtin_ia32_vsqrtps256_round: |
| case X86::BI__builtin_ia32_vsqrtph256_round: |
| ArgNum = 1; |
| HasRC = true; |
| break; |
| case X86::BI__builtin_ia32_addph512: |
| case X86::BI__builtin_ia32_divph512: |
| case X86::BI__builtin_ia32_mulph512: |
| case X86::BI__builtin_ia32_subph512: |
| case X86::BI__builtin_ia32_addpd512: |
| case X86::BI__builtin_ia32_addps512: |
| case X86::BI__builtin_ia32_divpd512: |
| case X86::BI__builtin_ia32_divps512: |
| case X86::BI__builtin_ia32_mulpd512: |
| case X86::BI__builtin_ia32_mulps512: |
| case X86::BI__builtin_ia32_subpd512: |
| case X86::BI__builtin_ia32_subps512: |
| case X86::BI__builtin_ia32_vaddpd256_round: |
| case X86::BI__builtin_ia32_vaddph256_round: |
| case X86::BI__builtin_ia32_vaddps256_round: |
| case X86::BI__builtin_ia32_vdivpd256_round: |
| case X86::BI__builtin_ia32_vdivph256_round: |
| case X86::BI__builtin_ia32_vdivps256_round: |
| case X86::BI__builtin_ia32_vmulpd256_round: |
| case X86::BI__builtin_ia32_vmulph256_round: |
| case X86::BI__builtin_ia32_vmulps256_round: |
| case X86::BI__builtin_ia32_vsubpd256_round: |
| case X86::BI__builtin_ia32_vsubph256_round: |
| case X86::BI__builtin_ia32_vsubps256_round: |
| case X86::BI__builtin_ia32_cvtsi2sd64: |
| case X86::BI__builtin_ia32_cvtsi2ss32: |
| case X86::BI__builtin_ia32_cvtsi2ss64: |
| case X86::BI__builtin_ia32_cvtusi2sd64: |
| case X86::BI__builtin_ia32_cvtusi2ss32: |
| case X86::BI__builtin_ia32_cvtusi2ss64: |
| case X86::BI__builtin_ia32_vcvtusi2sh: |
| case X86::BI__builtin_ia32_vcvtusi642sh: |
| case X86::BI__builtin_ia32_vcvtsi2sh: |
| case X86::BI__builtin_ia32_vcvtsi642sh: |
| ArgNum = 2; |
| HasRC = true; |
| break; |
| case X86::BI__builtin_ia32_cvtdq2ps512_mask: |
| case X86::BI__builtin_ia32_cvtudq2ps512_mask: |
| case X86::BI__builtin_ia32_vcvtpd2ph512_mask: |
| case X86::BI__builtin_ia32_vcvtps2phx512_mask: |
| case X86::BI__builtin_ia32_cvtpd2ps512_mask: |
| case X86::BI__builtin_ia32_cvtpd2dq512_mask: |
| case X86::BI__builtin_ia32_cvtpd2qq512_mask: |
| case X86::BI__builtin_ia32_cvtpd2udq512_mask: |
| case X86::BI__builtin_ia32_cvtpd2uqq512_mask: |
| case X86::BI__builtin_ia32_cvtps2dq512_mask: |
| case X86::BI__builtin_ia32_cvtps2qq512_mask: |
| case X86::BI__builtin_ia32_cvtps2udq512_mask: |
| case X86::BI__builtin_ia32_cvtps2uqq512_mask: |
| case X86::BI__builtin_ia32_cvtqq2pd512_mask: |
| case X86::BI__builtin_ia32_cvtqq2ps512_mask: |
| case X86::BI__builtin_ia32_cvtuqq2pd512_mask: |
| case X86::BI__builtin_ia32_cvtuqq2ps512_mask: |
| case X86::BI__builtin_ia32_vcvtdq2ph512_mask: |
| case X86::BI__builtin_ia32_vcvtudq2ph512_mask: |
| case X86::BI__builtin_ia32_vcvtw2ph512_mask: |
| case X86::BI__builtin_ia32_vcvtuw2ph512_mask: |
| case X86::BI__builtin_ia32_vcvtph2w512_mask: |
| case X86::BI__builtin_ia32_vcvtph2uw512_mask: |
| case X86::BI__builtin_ia32_vcvtph2dq512_mask: |
| case X86::BI__builtin_ia32_vcvtph2udq512_mask: |
| case X86::BI__builtin_ia32_vcvtph2qq512_mask: |
| case X86::BI__builtin_ia32_vcvtph2uqq512_mask: |
| case X86::BI__builtin_ia32_vcvtqq2ph512_mask: |
| case X86::BI__builtin_ia32_vcvtuqq2ph512_mask: |
| case X86::BI__builtin_ia32_vcvtph2pd256_round_mask: |
| case X86::BI__builtin_ia32_vcvtph2psx256_round_mask: |
| case X86::BI__builtin_ia32_vcvtps2pd256_round_mask: |
| case X86::BI__builtin_ia32_vcvttpd2dq256_round_mask: |
| case X86::BI__builtin_ia32_vcvttpd2qq256_round_mask: |
| case X86::BI__builtin_ia32_vcvttpd2udq256_round_mask: |
| case X86::BI__builtin_ia32_vcvttpd2uqq256_round_mask: |
| case X86::BI__builtin_ia32_vcvttps2dq256_round_mask: |
| case X86::BI__builtin_ia32_vcvttps2qq256_round_mask: |
| case X86::BI__builtin_ia32_vcvttps2udq256_round_mask: |
| case X86::BI__builtin_ia32_vcvttps2uqq256_round_mask: |
| case X86::BI__builtin_ia32_vcvttph2w256_round_mask: |
| case X86::BI__builtin_ia32_vcvttph2uw256_round_mask: |
| case X86::BI__builtin_ia32_vcvttph2dq256_round_mask: |
| case X86::BI__builtin_ia32_vcvttph2udq256_round_mask: |
| case X86::BI__builtin_ia32_vcvttph2qq256_round_mask: |
| case X86::BI__builtin_ia32_vcvttph2uqq256_round_mask: |
| case X86::BI__builtin_ia32_vcvtdq2ps256_round_mask: |
| case X86::BI__builtin_ia32_vcvtudq2ps256_round_mask: |
| case X86::BI__builtin_ia32_vcvtpd2ph256_round_mask: |
| case X86::BI__builtin_ia32_vcvtps2phx256_round_mask: |
| case X86::BI__builtin_ia32_vcvtpd2ps256_round_mask: |
| case X86::BI__builtin_ia32_vcvtpd2dq256_round_mask: |
| case X86::BI__builtin_ia32_vcvtpd2qq256_round_mask: |
| case X86::BI__builtin_ia32_vcvtpd2udq256_round_mask: |
| case X86::BI__builtin_ia32_vcvtpd2uqq256_round_mask: |
| case X86::BI__builtin_ia32_vcvtps2dq256_round_mask: |
| case X86::BI__builtin_ia32_vcvtps2qq256_round_mask: |
| case X86::BI__builtin_ia32_vcvtps2udq256_round_mask: |
| case X86::BI__builtin_ia32_vcvtps2uqq256_round_mask: |
| case X86::BI__builtin_ia32_vcvtqq2pd256_round_mask: |
| case X86::BI__builtin_ia32_vcvtqq2ps256_round_mask: |
| case X86::BI__builtin_ia32_vcvtuqq2pd256_round_mask: |
| case X86::BI__builtin_ia32_vcvtuqq2ps256_round_mask: |
| case X86::BI__builtin_ia32_vcvtdq2ph256_round_mask: |
| case X86::BI__builtin_ia32_vcvtudq2ph256_round_mask: |
| case X86::BI__builtin_ia32_vcvtw2ph256_round_mask: |
| case X86::BI__builtin_ia32_vcvtuw2ph256_round_mask: |
| case X86::BI__builtin_ia32_vcvtph2w256_round_mask: |
| case X86::BI__builtin_ia32_vcvtph2uw256_round_mask: |
| case X86::BI__builtin_ia32_vcvtph2dq256_round_mask: |
| case X86::BI__builtin_ia32_vcvtph2udq256_round_mask: |
| case X86::BI__builtin_ia32_vcvtph2qq256_round_mask: |
| case X86::BI__builtin_ia32_vcvtph2uqq256_round_mask: |
| case X86::BI__builtin_ia32_vcvtqq2ph256_round_mask: |
| case X86::BI__builtin_ia32_vcvtuqq2ph256_round_mask: |
| case X86::BI__builtin_ia32_vcvtph2ibs256_mask: |
| case X86::BI__builtin_ia32_vcvtph2iubs256_mask: |
| case X86::BI__builtin_ia32_vcvtps2ibs256_mask: |
| case X86::BI__builtin_ia32_vcvtps2iubs256_mask: |
| case X86::BI__builtin_ia32_vcvtph2ibs512_mask: |
| case X86::BI__builtin_ia32_vcvtph2iubs512_mask: |
| case X86::BI__builtin_ia32_vcvtps2ibs512_mask: |
| case X86::BI__builtin_ia32_vcvtps2iubs512_mask: |
| ArgNum = 3; |
| HasRC = true; |
| break; |
| case X86::BI__builtin_ia32_addsh_round_mask: |
| case X86::BI__builtin_ia32_addss_round_mask: |
| case X86::BI__builtin_ia32_addsd_round_mask: |
| case X86::BI__builtin_ia32_divsh_round_mask: |
| case X86::BI__builtin_ia32_divss_round_mask: |
| case X86::BI__builtin_ia32_divsd_round_mask: |
| case X86::BI__builtin_ia32_mulsh_round_mask: |
| case X86::BI__builtin_ia32_mulss_round_mask: |
| case X86::BI__builtin_ia32_mulsd_round_mask: |
| case X86::BI__builtin_ia32_subsh_round_mask: |
| case X86::BI__builtin_ia32_subss_round_mask: |
| case X86::BI__builtin_ia32_subsd_round_mask: |
| case X86::BI__builtin_ia32_scalefph512_mask: |
| case X86::BI__builtin_ia32_scalefpd512_mask: |
| case X86::BI__builtin_ia32_scalefps512_mask: |
| case X86::BI__builtin_ia32_vscalefph256_round_mask: |
| case X86::BI__builtin_ia32_vscalefpd256_round_mask: |
| case X86::BI__builtin_ia32_vscalefps256_round_mask: |
| case X86::BI__builtin_ia32_scalefsd_round_mask: |
| case X86::BI__builtin_ia32_scalefss_round_mask: |
| case X86::BI__builtin_ia32_scalefsh_round_mask: |
| case X86::BI__builtin_ia32_cvtsd2ss_round_mask: |
| case X86::BI__builtin_ia32_vcvtss2sh_round_mask: |
| case X86::BI__builtin_ia32_vcvtsd2sh_round_mask: |
| case X86::BI__builtin_ia32_sqrtsd_round_mask: |
| case X86::BI__builtin_ia32_sqrtss_round_mask: |
| case X86::BI__builtin_ia32_sqrtsh_round_mask: |
| case X86::BI__builtin_ia32_vfmaddsd3_mask: |
| case X86::BI__builtin_ia32_vfmaddsd3_maskz: |
| case X86::BI__builtin_ia32_vfmaddsd3_mask3: |
| case X86::BI__builtin_ia32_vfmaddss3_mask: |
| case X86::BI__builtin_ia32_vfmaddss3_maskz: |
| case X86::BI__builtin_ia32_vfmaddss3_mask3: |
| case X86::BI__builtin_ia32_vfmaddsh3_mask: |
| case X86::BI__builtin_ia32_vfmaddsh3_maskz: |
| case X86::BI__builtin_ia32_vfmaddsh3_mask3: |
| case X86::BI__builtin_ia32_vfmaddpd512_mask: |
| case X86::BI__builtin_ia32_vfmaddpd512_maskz: |
| case X86::BI__builtin_ia32_vfmaddpd512_mask3: |
| case X86::BI__builtin_ia32_vfmsubpd512_mask3: |
| case X86::BI__builtin_ia32_vfmaddps512_mask: |
| case X86::BI__builtin_ia32_vfmaddps512_maskz: |
| case X86::BI__builtin_ia32_vfmaddps512_mask3: |
| case X86::BI__builtin_ia32_vfmsubps512_mask3: |
| case X86::BI__builtin_ia32_vfmaddph512_mask: |
| case X86::BI__builtin_ia32_vfmaddph512_maskz: |
| case X86::BI__builtin_ia32_vfmaddph512_mask3: |
| case X86::BI__builtin_ia32_vfmsubph512_mask3: |
| case X86::BI__builtin_ia32_vfmaddsubpd512_mask: |
| case X86::BI__builtin_ia32_vfmaddsubpd512_maskz: |
| case X86::BI__builtin_ia32_vfmaddsubpd512_mask3: |
| case X86::BI__builtin_ia32_vfmsubaddpd512_mask3: |
| case X86::BI__builtin_ia32_vfmaddsubps512_mask: |
| case X86::BI__builtin_ia32_vfmaddsubps512_maskz: |
| case X86::BI__builtin_ia32_vfmaddsubps512_mask3: |
| case X86::BI__builtin_ia32_vfmsubaddps512_mask3: |
| case X86::BI__builtin_ia32_vfmaddsubph512_mask: |
| case X86::BI__builtin_ia32_vfmaddsubph512_maskz: |
| case X86::BI__builtin_ia32_vfmaddsubph512_mask3: |
| case X86::BI__builtin_ia32_vfmsubaddph512_mask3: |
| case X86::BI__builtin_ia32_vfmaddpd256_round_mask: |
| case X86::BI__builtin_ia32_vfmaddpd256_round_maskz: |
| case X86::BI__builtin_ia32_vfmaddpd256_round_mask3: |
| case X86::BI__builtin_ia32_vfmsubpd256_round_mask3: |
| case X86::BI__builtin_ia32_vfmaddps256_round_mask: |
| case X86::BI__builtin_ia32_vfmaddps256_round_maskz: |
| case X86::BI__builtin_ia32_vfmaddps256_round_mask3: |
| case X86::BI__builtin_ia32_vfmsubps256_round_mask3: |
| case X86::BI__builtin_ia32_vfmaddph256_round_mask: |
| case X86::BI__builtin_ia32_vfmaddph256_round_maskz: |
| case X86::BI__builtin_ia32_vfmaddph256_round_mask3: |
| case X86::BI__builtin_ia32_vfmsubph256_round_mask3: |
| case X86::BI__builtin_ia32_vfmaddsubpd256_round_mask: |
| case X86::BI__builtin_ia32_vfmaddsubpd256_round_maskz: |
| case X86::BI__builtin_ia32_vfmaddsubpd256_round_mask3: |
| case X86::BI__builtin_ia32_vfmsubaddpd256_round_mask3: |
| case X86::BI__builtin_ia32_vfmaddsubps256_round_mask: |
| case X86::BI__builtin_ia32_vfmaddsubps256_round_maskz: |
| case X86::BI__builtin_ia32_vfmaddsubps256_round_mask3: |
| case X86::BI__builtin_ia32_vfmsubaddps256_round_mask3: |
| case X86::BI__builtin_ia32_vfmaddsubph256_round_mask: |
| case X86::BI__builtin_ia32_vfmaddsubph256_round_maskz: |
| case X86::BI__builtin_ia32_vfmaddsubph256_round_mask3: |
| case X86::BI__builtin_ia32_vfmsubaddph256_round_mask3: |
| case X86::BI__builtin_ia32_vfmaddcph256_round_mask: |
| case X86::BI__builtin_ia32_vfmaddcph256_round_maskz: |
| case X86::BI__builtin_ia32_vfmaddcph256_round_mask3: |
| case X86::BI__builtin_ia32_vfcmaddcph256_round_mask: |
| case X86::BI__builtin_ia32_vfcmaddcph256_round_maskz: |
| case X86::BI__builtin_ia32_vfcmaddcph256_round_mask3: |
| case X86::BI__builtin_ia32_vfmulcph256_round_mask: |
| case X86::BI__builtin_ia32_vfcmulcph256_round_mask: |
| case X86::BI__builtin_ia32_vfmaddcsh_mask: |
| case X86::BI__builtin_ia32_vfmaddcsh_round_mask: |
| case X86::BI__builtin_ia32_vfmaddcsh_round_mask3: |
| case X86::BI__builtin_ia32_vfmaddcph512_mask: |
| case X86::BI__builtin_ia32_vfmaddcph512_maskz: |
| case X86::BI__builtin_ia32_vfmaddcph512_mask3: |
| case X86::BI__builtin_ia32_vfcmaddcsh_mask: |
| case X86::BI__builtin_ia32_vfcmaddcsh_round_mask: |
| case X86::BI__builtin_ia32_vfcmaddcsh_round_mask3: |
| case X86::BI__builtin_ia32_vfcmaddcph512_mask: |
| case X86::BI__builtin_ia32_vfcmaddcph512_maskz: |
| case X86::BI__builtin_ia32_vfcmaddcph512_mask3: |
| case X86::BI__builtin_ia32_vfmulcsh_mask: |
| case X86::BI__builtin_ia32_vfmulcph512_mask: |
| case X86::BI__builtin_ia32_vfcmulcsh_mask: |
| case X86::BI__builtin_ia32_vfcmulcph512_mask: |
| case X86::BI__builtin_ia32_vcvt2ps2phx256_mask: |
| case X86::BI__builtin_ia32_vcvt2ps2phx512_mask: |
| ArgNum = 4; |
| HasRC = true; |
| break; |
| case X86::BI__builtin_ia32_vcvttpd2dqs256_round_mask: |
| case X86::BI__builtin_ia32_vcvttpd2dqs512_round_mask: |
| case X86::BI__builtin_ia32_vcvttpd2udqs256_round_mask: |
| case X86::BI__builtin_ia32_vcvttpd2udqs512_round_mask: |
| case X86::BI__builtin_ia32_vcvttpd2qqs256_round_mask: |
| case X86::BI__builtin_ia32_vcvttpd2qqs512_round_mask: |
| case X86::BI__builtin_ia32_vcvttpd2uqqs256_round_mask: |
| case X86::BI__builtin_ia32_vcvttpd2uqqs512_round_mask: |
| case X86::BI__builtin_ia32_vcvttps2dqs256_round_mask: |
| case X86::BI__builtin_ia32_vcvttps2dqs512_round_mask: |
| case X86::BI__builtin_ia32_vcvttps2udqs256_round_mask: |
| case X86::BI__builtin_ia32_vcvttps2udqs512_round_mask: |
| case X86::BI__builtin_ia32_vcvttps2qqs256_round_mask: |
| case X86::BI__builtin_ia32_vcvttps2qqs512_round_mask: |
| case X86::BI__builtin_ia32_vcvttps2uqqs256_round_mask: |
| case X86::BI__builtin_ia32_vcvttps2uqqs512_round_mask: |
| ArgNum = 3; |
| 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 (SemaRef.BuiltinConstantArg(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 the intrinsic does not have rounding |
| // control, allow ROUND_NO_EXC and ROUND_CUR_DIRECTION together. |
| if (Result == 4 /*ROUND_CUR_DIRECTION*/ || Result == 8 /*ROUND_NO_EXC*/ || |
| (!HasRC && Result == 12 /*ROUND_CUR_DIRECTION|ROUND_NO_EXC*/) || |
| (HasRC && Result.getZExtValue() >= 8 && Result.getZExtValue() <= 11)) |
| return false; |
| |
| return Diag(TheCall->getBeginLoc(), diag::err_x86_builtin_invalid_rounding) |
| << Arg->getSourceRange(); |
| } |
| |
| // Check if the gather/scatter scale is legal. |
| bool SemaX86::CheckBuiltinGatherScatterScale(unsigned BuiltinID, |
| CallExpr *TheCall) { |
| unsigned ArgNum = 0; |
| switch (BuiltinID) { |
| default: |
| return false; |
| case X86::BI__builtin_ia32_gatherd_pd: |
| case X86::BI__builtin_ia32_gatherd_pd256: |
| case X86::BI__builtin_ia32_gatherq_pd: |
| case X86::BI__builtin_ia32_gatherq_pd256: |
| case X86::BI__builtin_ia32_gatherd_ps: |
| case X86::BI__builtin_ia32_gatherd_ps256: |
| case X86::BI__builtin_ia32_gatherq_ps: |
| case X86::BI__builtin_ia32_gatherq_ps256: |
| case X86::BI__builtin_ia32_gatherd_q: |
| case X86::BI__builtin_ia32_gatherd_q256: |
| case X86::BI__builtin_ia32_gatherq_q: |
| case X86::BI__builtin_ia32_gatherq_q256: |
| case X86::BI__builtin_ia32_gatherd_d: |
| case X86::BI__builtin_ia32_gatherd_d256: |
| case X86::BI__builtin_ia32_gatherq_d: |
| case X86::BI__builtin_ia32_gatherq_d256: |
| case X86::BI__builtin_ia32_gather3div2df: |
| case X86::BI__builtin_ia32_gather3div2di: |
| case X86::BI__builtin_ia32_gather3div4df: |
| case X86::BI__builtin_ia32_gather3div4di: |
| case X86::BI__builtin_ia32_gather3div4sf: |
| case X86::BI__builtin_ia32_gather3div4si: |
| case X86::BI__builtin_ia32_gather3div8sf: |
| case X86::BI__builtin_ia32_gather3div8si: |
| case X86::BI__builtin_ia32_gather3siv2df: |
| case X86::BI__builtin_ia32_gather3siv2di: |
| case X86::BI__builtin_ia32_gather3siv4df: |
| case X86::BI__builtin_ia32_gather3siv4di: |
| case X86::BI__builtin_ia32_gather3siv4sf: |
| case X86::BI__builtin_ia32_gather3siv4si: |
| case X86::BI__builtin_ia32_gather3siv8sf: |
| case X86::BI__builtin_ia32_gather3siv8si: |
| case X86::BI__builtin_ia32_gathersiv8df: |
| case X86::BI__builtin_ia32_gathersiv16sf: |
| case X86::BI__builtin_ia32_gatherdiv8df: |
| case X86::BI__builtin_ia32_gatherdiv16sf: |
| case X86::BI__builtin_ia32_gathersiv8di: |
| case X86::BI__builtin_ia32_gathersiv16si: |
| case X86::BI__builtin_ia32_gatherdiv8di: |
| case X86::BI__builtin_ia32_gatherdiv16si: |
| case X86::BI__builtin_ia32_scatterdiv2df: |
| case X86::BI__builtin_ia32_scatterdiv2di: |
| case X86::BI__builtin_ia32_scatterdiv4df: |
| case X86::BI__builtin_ia32_scatterdiv4di: |
| case X86::BI__builtin_ia32_scatterdiv4sf: |
| case X86::BI__builtin_ia32_scatterdiv4si: |
| case X86::BI__builtin_ia32_scatterdiv8sf: |
| case X86::BI__builtin_ia32_scatterdiv8si: |
| case X86::BI__builtin_ia32_scattersiv2df: |
| case X86::BI__builtin_ia32_scattersiv2di: |
| case X86::BI__builtin_ia32_scattersiv4df: |
| case X86::BI__builtin_ia32_scattersiv4di: |
| case X86::BI__builtin_ia32_scattersiv4sf: |
| case X86::BI__builtin_ia32_scattersiv4si: |
| case X86::BI__builtin_ia32_scattersiv8sf: |
| case X86::BI__builtin_ia32_scattersiv8si: |
| case X86::BI__builtin_ia32_scattersiv8df: |
| case X86::BI__builtin_ia32_scattersiv16sf: |
| case X86::BI__builtin_ia32_scatterdiv8df: |
| case X86::BI__builtin_ia32_scatterdiv16sf: |
| case X86::BI__builtin_ia32_scattersiv8di: |
| case X86::BI__builtin_ia32_scattersiv16si: |
| case X86::BI__builtin_ia32_scatterdiv8di: |
| case X86::BI__builtin_ia32_scatterdiv16si: |
| ArgNum = 4; |
| 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 (SemaRef.BuiltinConstantArg(TheCall, ArgNum, Result)) |
| return true; |
| |
| if (Result == 1 || Result == 2 || Result == 4 || Result == 8) |
| return false; |
| |
| return Diag(TheCall->getBeginLoc(), diag::err_x86_builtin_invalid_scale) |
| << Arg->getSourceRange(); |
| } |
| |
| enum { TileRegLow = 0, TileRegHigh = 7 }; |
| |
| bool SemaX86::CheckBuiltinTileArgumentsRange(CallExpr *TheCall, |
| ArrayRef<int> ArgNums) { |
| for (int ArgNum : ArgNums) { |
| if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, TileRegLow, |
| TileRegHigh)) |
| return true; |
| } |
| return false; |
| } |
| |
| bool SemaX86::CheckBuiltinTileDuplicate(CallExpr *TheCall, |
| ArrayRef<int> ArgNums) { |
| // Because the max number of tile register is TileRegHigh + 1, so here we use |
| // each bit to represent the usage of them in bitset. |
| std::bitset<TileRegHigh + 1> ArgValues; |
| for (int ArgNum : ArgNums) { |
| Expr *Arg = TheCall->getArg(ArgNum); |
| if (Arg->isTypeDependent() || Arg->isValueDependent()) |
| continue; |
| |
| llvm::APSInt Result; |
| if (SemaRef.BuiltinConstantArg(TheCall, ArgNum, Result)) |
| return true; |
| int ArgExtValue = Result.getExtValue(); |
| assert((ArgExtValue >= TileRegLow && ArgExtValue <= TileRegHigh) && |
| "Incorrect tile register num."); |
| if (ArgValues.test(ArgExtValue)) |
| return Diag(TheCall->getBeginLoc(), |
| diag::err_x86_builtin_tile_arg_duplicate) |
| << TheCall->getArg(ArgNum)->getSourceRange(); |
| ArgValues.set(ArgExtValue); |
| } |
| return false; |
| } |
| |
| bool SemaX86::CheckBuiltinTileRangeAndDuplicate(CallExpr *TheCall, |
| ArrayRef<int> ArgNums) { |
| return CheckBuiltinTileArgumentsRange(TheCall, ArgNums) || |
| CheckBuiltinTileDuplicate(TheCall, ArgNums); |
| } |
| |
| bool SemaX86::CheckBuiltinTileArguments(unsigned BuiltinID, CallExpr *TheCall) { |
| switch (BuiltinID) { |
| default: |
| return false; |
| case X86::BI__builtin_ia32_tileloadd64: |
| case X86::BI__builtin_ia32_tileloaddt164: |
| case X86::BI__builtin_ia32_tileloaddrs64: |
| case X86::BI__builtin_ia32_tileloaddrst164: |
| case X86::BI__builtin_ia32_tilestored64: |
| case X86::BI__builtin_ia32_tilezero: |
| case X86::BI__builtin_ia32_t2rpntlvwz0: |
| case X86::BI__builtin_ia32_t2rpntlvwz0t1: |
| case X86::BI__builtin_ia32_t2rpntlvwz1: |
| case X86::BI__builtin_ia32_t2rpntlvwz1t1: |
| case X86::BI__builtin_ia32_t2rpntlvwz0rst1: |
| case X86::BI__builtin_ia32_t2rpntlvwz1rs: |
| case X86::BI__builtin_ia32_t2rpntlvwz1rst1: |
| case X86::BI__builtin_ia32_t2rpntlvwz0rs: |
| case X86::BI__builtin_ia32_tcvtrowps2bf16h: |
| case X86::BI__builtin_ia32_tcvtrowps2bf16l: |
| case X86::BI__builtin_ia32_tcvtrowps2phh: |
| case X86::BI__builtin_ia32_tcvtrowps2phl: |
| case X86::BI__builtin_ia32_tcvtrowd2ps: |
| case X86::BI__builtin_ia32_tilemovrow: |
| return CheckBuiltinTileArgumentsRange(TheCall, 0); |
| case X86::BI__builtin_ia32_tdpbssd: |
| case X86::BI__builtin_ia32_tdpbsud: |
| case X86::BI__builtin_ia32_tdpbusd: |
| case X86::BI__builtin_ia32_tdpbuud: |
| case X86::BI__builtin_ia32_tdpbf16ps: |
| case X86::BI__builtin_ia32_tdpfp16ps: |
| case X86::BI__builtin_ia32_tcmmimfp16ps: |
| case X86::BI__builtin_ia32_tcmmrlfp16ps: |
| case X86::BI__builtin_ia32_tdpbf8ps: |
| case X86::BI__builtin_ia32_tdpbhf8ps: |
| case X86::BI__builtin_ia32_tdphbf8ps: |
| case X86::BI__builtin_ia32_tdphf8ps: |
| case X86::BI__builtin_ia32_ttdpbf16ps: |
| case X86::BI__builtin_ia32_ttdpfp16ps: |
| case X86::BI__builtin_ia32_ttcmmimfp16ps: |
| case X86::BI__builtin_ia32_ttcmmrlfp16ps: |
| case X86::BI__builtin_ia32_tconjtcmmimfp16ps: |
| case X86::BI__builtin_ia32_tmmultf32ps: |
| case X86::BI__builtin_ia32_ttmmultf32ps: |
| return CheckBuiltinTileRangeAndDuplicate(TheCall, {0, 1, 2}); |
| case X86::BI__builtin_ia32_ttransposed: |
| case X86::BI__builtin_ia32_tconjtfp16: |
| return CheckBuiltinTileArgumentsRange(TheCall, {0, 1}); |
| } |
| } |
| static bool isX86_32Builtin(unsigned BuiltinID) { |
| // These builtins only work on x86-32 targets. |
| switch (BuiltinID) { |
| case X86::BI__builtin_ia32_readeflags_u32: |
| case X86::BI__builtin_ia32_writeeflags_u32: |
| return true; |
| } |
| |
| return false; |
| } |
| |
| bool SemaX86::CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, |
| CallExpr *TheCall) { |
| // Check for 32-bit only builtins on a 64-bit target. |
| const llvm::Triple &TT = TI.getTriple(); |
| if (TT.getArch() != llvm::Triple::x86 && isX86_32Builtin(BuiltinID)) |
| return Diag(TheCall->getCallee()->getBeginLoc(), |
| diag::err_32_bit_builtin_64_bit_tgt); |
| |
| // If the intrinsic has rounding or SAE make sure its valid. |
| if (CheckBuiltinRoundingOrSAE(BuiltinID, TheCall)) |
| return true; |
| |
| // If the intrinsic has a gather/scatter scale immediate make sure its valid. |
| if (CheckBuiltinGatherScatterScale(BuiltinID, TheCall)) |
| return true; |
| |
| // If the intrinsic has a tile arguments, make sure they are valid. |
| if (CheckBuiltinTileArguments(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; |
| switch (BuiltinID) { |
| default: |
| return false; |
| case X86::BI__builtin_ia32_vec_ext_v2di: |
| case X86::BI__builtin_ia32_vextractf128_pd256: |
| case X86::BI__builtin_ia32_vextractf128_ps256: |
| case X86::BI__builtin_ia32_vextractf128_si256: |
| case X86::BI__builtin_ia32_extract128i256: |
| case X86::BI__builtin_ia32_extractf64x4_mask: |
| case X86::BI__builtin_ia32_extracti64x4_mask: |
| case X86::BI__builtin_ia32_extractf32x8_mask: |
| case X86::BI__builtin_ia32_extracti32x8_mask: |
| case X86::BI__builtin_ia32_extractf64x2_256_mask: |
| case X86::BI__builtin_ia32_extracti64x2_256_mask: |
| case X86::BI__builtin_ia32_extractf32x4_256_mask: |
| case X86::BI__builtin_ia32_extracti32x4_256_mask: |
| i = 1; |
| l = 0; |
| u = 1; |
| break; |
| case X86::BI__builtin_ia32_vec_set_v2di: |
| case X86::BI__builtin_ia32_vinsertf128_pd256: |
| case X86::BI__builtin_ia32_vinsertf128_ps256: |
| case X86::BI__builtin_ia32_vinsertf128_si256: |
| case X86::BI__builtin_ia32_insert128i256: |
| case X86::BI__builtin_ia32_insertf32x8: |
| case X86::BI__builtin_ia32_inserti32x8: |
| case X86::BI__builtin_ia32_insertf64x4: |
| case X86::BI__builtin_ia32_inserti64x4: |
| case X86::BI__builtin_ia32_insertf64x2_256: |
| case X86::BI__builtin_ia32_inserti64x2_256: |
| case X86::BI__builtin_ia32_insertf32x4_256: |
| case X86::BI__builtin_ia32_inserti32x4_256: |
| i = 2; |
| l = 0; |
| u = 1; |
| break; |
| case X86::BI__builtin_ia32_vpermilpd: |
| case X86::BI__builtin_ia32_vec_ext_v4hi: |
| case X86::BI__builtin_ia32_vec_ext_v4si: |
| case X86::BI__builtin_ia32_vec_ext_v4sf: |
| case X86::BI__builtin_ia32_vec_ext_v4di: |
| case X86::BI__builtin_ia32_extractf32x4_mask: |
| case X86::BI__builtin_ia32_extracti32x4_mask: |
| case X86::BI__builtin_ia32_extractf64x2_512_mask: |
| case X86::BI__builtin_ia32_extracti64x2_512_mask: |
| i = 1; |
| l = 0; |
| u = 3; |
| break; |
| case X86::BI_mm_prefetch: |
| case X86::BI__builtin_ia32_vec_ext_v8hi: |
| case X86::BI__builtin_ia32_vec_ext_v8si: |
| i = 1; |
| l = 0; |
| u = 7; |
| break; |
| case X86::BI__builtin_ia32_sha1rnds4: |
| case X86::BI__builtin_ia32_blendpd: |
| case X86::BI__builtin_ia32_shufpd: |
| case X86::BI__builtin_ia32_vec_set_v4hi: |
| case X86::BI__builtin_ia32_vec_set_v4si: |
| case X86::BI__builtin_ia32_vec_set_v4di: |
| case X86::BI__builtin_ia32_shuf_f32x4_256: |
| case X86::BI__builtin_ia32_shuf_f64x2_256: |
| case X86::BI__builtin_ia32_shuf_i32x4_256: |
| case X86::BI__builtin_ia32_shuf_i64x2_256: |
| case X86::BI__builtin_ia32_insertf64x2_512: |
| case X86::BI__builtin_ia32_inserti64x2_512: |
| case X86::BI__builtin_ia32_insertf32x4: |
| case X86::BI__builtin_ia32_inserti32x4: |
| i = 2; |
| l = 0; |
| u = 3; |
| break; |
| case X86::BI__builtin_ia32_vpermil2pd: |
| case X86::BI__builtin_ia32_vpermil2pd256: |
| case X86::BI__builtin_ia32_vpermil2ps: |
| case X86::BI__builtin_ia32_vpermil2ps256: |
| i = 3; |
| l = 0; |
| u = 3; |
| break; |
| case X86::BI__builtin_ia32_cmpb128_mask: |
| case X86::BI__builtin_ia32_cmpw128_mask: |
| case X86::BI__builtin_ia32_cmpd128_mask: |
| case X86::BI__builtin_ia32_cmpq128_mask: |
| case X86::BI__builtin_ia32_cmpb256_mask: |
| case X86::BI__builtin_ia32_cmpw256_mask: |
| case X86::BI__builtin_ia32_cmpd256_mask: |
| case X86::BI__builtin_ia32_cmpq256_mask: |
| case X86::BI__builtin_ia32_cmpb512_mask: |
| case X86::BI__builtin_ia32_cmpw512_mask: |
| case X86::BI__builtin_ia32_cmpd512_mask: |
| case X86::BI__builtin_ia32_cmpq512_mask: |
| case X86::BI__builtin_ia32_ucmpb128_mask: |
| case X86::BI__builtin_ia32_ucmpw128_mask: |
| case X86::BI__builtin_ia32_ucmpd128_mask: |
| case X86::BI__builtin_ia32_ucmpq128_mask: |
| case X86::BI__builtin_ia32_ucmpb256_mask: |
| case X86::BI__builtin_ia32_ucmpw256_mask: |
| case X86::BI__builtin_ia32_ucmpd256_mask: |
| case X86::BI__builtin_ia32_ucmpq256_mask: |
| case X86::BI__builtin_ia32_ucmpb512_mask: |
| case X86::BI__builtin_ia32_ucmpw512_mask: |
| case X86::BI__builtin_ia32_ucmpd512_mask: |
| case X86::BI__builtin_ia32_ucmpq512_mask: |
| case X86::BI__builtin_ia32_vpcomub: |
| case X86::BI__builtin_ia32_vpcomuw: |
| case X86::BI__builtin_ia32_vpcomud: |
| case X86::BI__builtin_ia32_vpcomuq: |
| case X86::BI__builtin_ia32_vpcomb: |
| case X86::BI__builtin_ia32_vpcomw: |
| case X86::BI__builtin_ia32_vpcomd: |
| case X86::BI__builtin_ia32_vpcomq: |
| case X86::BI__builtin_ia32_vec_set_v8hi: |
| case X86::BI__builtin_ia32_vec_set_v8si: |
| i = 2; |
| l = 0; |
| u = 7; |
| break; |
| case X86::BI__builtin_ia32_vpermilpd256: |
| case X86::BI__builtin_ia32_roundps: |
| case X86::BI__builtin_ia32_roundpd: |
| case X86::BI__builtin_ia32_roundps256: |
| case X86::BI__builtin_ia32_roundpd256: |
| case X86::BI__builtin_ia32_getmantpd128_mask: |
| case X86::BI__builtin_ia32_getmantpd256_mask: |
| case X86::BI__builtin_ia32_getmantps128_mask: |
| case X86::BI__builtin_ia32_getmantps256_mask: |
| case X86::BI__builtin_ia32_getmantpd512_mask: |
| case X86::BI__builtin_ia32_getmantps512_mask: |
| case X86::BI__builtin_ia32_getmantph128_mask: |
| case X86::BI__builtin_ia32_getmantph256_mask: |
| case X86::BI__builtin_ia32_getmantph512_mask: |
| case X86::BI__builtin_ia32_vgetmantpd256_round_mask: |
| case X86::BI__builtin_ia32_vgetmantps256_round_mask: |
| case X86::BI__builtin_ia32_vgetmantph256_round_mask: |
| case X86::BI__builtin_ia32_vec_ext_v16qi: |
| case X86::BI__builtin_ia32_vec_ext_v16hi: |
| i = 1; |
| l = 0; |
| u = 15; |
| break; |
| case X86::BI__builtin_ia32_pblendd128: |
| case X86::BI__builtin_ia32_blendps: |
| case X86::BI__builtin_ia32_blendpd256: |
| case X86::BI__builtin_ia32_shufpd256: |
| case X86::BI__builtin_ia32_roundss: |
| case X86::BI__builtin_ia32_roundsd: |
| case X86::BI__builtin_ia32_rangepd128_mask: |
| case X86::BI__builtin_ia32_rangepd256_mask: |
| case X86::BI__builtin_ia32_rangepd512_mask: |
| case X86::BI__builtin_ia32_rangeps128_mask: |
| case X86::BI__builtin_ia32_rangeps256_mask: |
| case X86::BI__builtin_ia32_rangeps512_mask: |
| case X86::BI__builtin_ia32_vrangepd256_round_mask: |
| case X86::BI__builtin_ia32_vrangeps256_round_mask: |
| case X86::BI__builtin_ia32_getmantsd_round_mask: |
| case X86::BI__builtin_ia32_getmantss_round_mask: |
| case X86::BI__builtin_ia32_getmantsh_round_mask: |
| case X86::BI__builtin_ia32_vec_set_v16qi: |
| case X86::BI__builtin_ia32_vec_set_v16hi: |
| i = 2; |
| l = 0; |
| u = 15; |
| break; |
| case X86::BI__builtin_ia32_vec_ext_v32qi: |
| i = 1; |
| l = 0; |
| u = 31; |
| break; |
| case X86::BI__builtin_ia32_cmpps: |
| case X86::BI__builtin_ia32_cmpss: |
| case X86::BI__builtin_ia32_cmppd: |
| case X86::BI__builtin_ia32_cmpsd: |
| case X86::BI__builtin_ia32_cmpps256: |
| case X86::BI__builtin_ia32_cmppd256: |
| case X86::BI__builtin_ia32_cmpps128_mask: |
| case X86::BI__builtin_ia32_cmppd128_mask: |
| case X86::BI__builtin_ia32_cmpps256_mask: |
| case X86::BI__builtin_ia32_cmppd256_mask: |
| case X86::BI__builtin_ia32_cmpps512_mask: |
| case X86::BI__builtin_ia32_cmppd512_mask: |
| case X86::BI__builtin_ia32_cmpph512_mask: |
| case X86::BI__builtin_ia32_vcmppd256_round_mask: |
| case X86::BI__builtin_ia32_vcmpps256_round_mask: |
| case X86::BI__builtin_ia32_vcmpph256_round_mask: |
| case X86::BI__builtin_ia32_cmpsd_mask: |
| case X86::BI__builtin_ia32_cmpss_mask: |
| case X86::BI__builtin_ia32_vec_set_v32qi: |
| i = 2; |
| l = 0; |
| u = 31; |
| break; |
| case X86::BI__builtin_ia32_permdf256: |
| case X86::BI__builtin_ia32_permdi256: |
| case X86::BI__builtin_ia32_permdf512: |
| case X86::BI__builtin_ia32_permdi512: |
| case X86::BI__builtin_ia32_vpermilps: |
| case X86::BI__builtin_ia32_vpermilps256: |
| case X86::BI__builtin_ia32_vpermilpd512: |
| case X86::BI__builtin_ia32_vpermilps512: |
| case X86::BI__builtin_ia32_pshufd: |
| case X86::BI__builtin_ia32_pshufd256: |
| case X86::BI__builtin_ia32_pshufd512: |
| case X86::BI__builtin_ia32_pshufhw: |
| case X86::BI__builtin_ia32_pshufhw256: |
| case X86::BI__builtin_ia32_pshufhw512: |
| case X86::BI__builtin_ia32_pshuflw: |
| case X86::BI__builtin_ia32_pshuflw256: |
| case X86::BI__builtin_ia32_pshuflw512: |
| case X86::BI__builtin_ia32_vcvtps2ph: |
| case X86::BI__builtin_ia32_vcvtps2ph_mask: |
| case X86::BI__builtin_ia32_vcvtps2ph256: |
| case X86::BI__builtin_ia32_vcvtps2ph256_mask: |
| case X86::BI__builtin_ia32_vcvtps2ph512_mask: |
| case X86::BI__builtin_ia32_rndscaleps_128_mask: |
| case X86::BI__builtin_ia32_rndscalepd_128_mask: |
| case X86::BI__builtin_ia32_rndscaleps_256_mask: |
| case X86::BI__builtin_ia32_rndscalepd_256_mask: |
| case X86::BI__builtin_ia32_rndscaleps_mask: |
| case X86::BI__builtin_ia32_rndscalepd_mask: |
| case X86::BI__builtin_ia32_rndscaleph_mask: |
| case X86::BI__builtin_ia32_vrndscalebf16_128_mask: |
| case X86::BI__builtin_ia32_vrndscalebf16_256_mask: |
| case X86::BI__builtin_ia32_vrndscalebf16_mask: |
| case X86::BI__builtin_ia32_reducepd128_mask: |
| case X86::BI__builtin_ia32_reducepd256_mask: |
| case X86::BI__builtin_ia32_reducepd512_mask: |
| case X86::BI__builtin_ia32_reduceps128_mask: |
| case X86::BI__builtin_ia32_reduceps256_mask: |
| case X86::BI__builtin_ia32_reduceps512_mask: |
| case X86::BI__builtin_ia32_reduceph128_mask: |
| case X86::BI__builtin_ia32_reduceph256_mask: |
| case X86::BI__builtin_ia32_reduceph512_mask: |
| case X86::BI__builtin_ia32_vreducebf16128_mask: |
| case X86::BI__builtin_ia32_vreducebf16256_mask: |
| case X86::BI__builtin_ia32_vreducebf16512_mask: |
| case X86::BI__builtin_ia32_vreducepd256_round_mask: |
| case X86::BI__builtin_ia32_vreduceps256_round_mask: |
| case X86::BI__builtin_ia32_vreduceph256_round_mask: |
| case X86::BI__builtin_ia32_vrndscalepd256_round_mask: |
| case X86::BI__builtin_ia32_vrndscaleps256_round_mask: |
| case X86::BI__builtin_ia32_vrndscaleph256_round_mask: |
| case X86::BI__builtin_ia32_prold512: |
| case X86::BI__builtin_ia32_prolq512: |
| case X86::BI__builtin_ia32_prold128: |
| case X86::BI__builtin_ia32_prold256: |
| case X86::BI__builtin_ia32_prolq128: |
| case X86::BI__builtin_ia32_prolq256: |
| case X86::BI__builtin_ia32_prord512: |
| case X86::BI__builtin_ia32_prorq512: |
| case X86::BI__builtin_ia32_prord128: |
| case X86::BI__builtin_ia32_prord256: |
| case X86::BI__builtin_ia32_prorq128: |
| case X86::BI__builtin_ia32_prorq256: |
| case X86::BI__builtin_ia32_fpclasspd128_mask: |
| case X86::BI__builtin_ia32_fpclasspd256_mask: |
| case X86::BI__builtin_ia32_fpclassps128_mask: |
| case X86::BI__builtin_ia32_fpclassps256_mask: |
| case X86::BI__builtin_ia32_fpclassps512_mask: |
| case X86::BI__builtin_ia32_fpclasspd512_mask: |
| case X86::BI__builtin_ia32_fpclassph128_mask: |
| case X86::BI__builtin_ia32_fpclassph256_mask: |
| case X86::BI__builtin_ia32_fpclassph512_mask: |
| case X86::BI__builtin_ia32_vfpclassbf16128_mask: |
| case X86::BI__builtin_ia32_vfpclassbf16256_mask: |
| case X86::BI__builtin_ia32_vfpclassbf16512_mask: |
| case X86::BI__builtin_ia32_fpclasssd_mask: |
| case X86::BI__builtin_ia32_fpclassss_mask: |
| case X86::BI__builtin_ia32_fpclasssh_mask: |
| case X86::BI__builtin_ia32_pslldqi128_byteshift: |
| case X86::BI__builtin_ia32_pslldqi256_byteshift: |
| case X86::BI__builtin_ia32_pslldqi512_byteshift: |
| case X86::BI__builtin_ia32_psrldqi128_byteshift: |
| case X86::BI__builtin_ia32_psrldqi256_byteshift: |
| case X86::BI__builtin_ia32_psrldqi512_byteshift: |
| case X86::BI__builtin_ia32_kshiftliqi: |
| case X86::BI__builtin_ia32_kshiftlihi: |
| case X86::BI__builtin_ia32_kshiftlisi: |
| case X86::BI__builtin_ia32_kshiftlidi: |
| case X86::BI__builtin_ia32_kshiftriqi: |
| case X86::BI__builtin_ia32_kshiftrihi: |
| case X86::BI__builtin_ia32_kshiftrisi: |
| case X86::BI__builtin_ia32_kshiftridi: |
| i = 1; |
| l = 0; |
| u = 255; |
| break; |
| case X86::BI__builtin_ia32_vperm2f128_pd256: |
| case X86::BI__builtin_ia32_vperm2f128_ps256: |
| case X86::BI__builtin_ia32_vperm2f128_si256: |
| case X86::BI__builtin_ia32_permti256: |
| case X86::BI__builtin_ia32_pblendw128: |
| case X86::BI__builtin_ia32_pblendw256: |
| case X86::BI__builtin_ia32_blendps256: |
| case X86::BI__builtin_ia32_pblendd256: |
| case X86::BI__builtin_ia32_palignr128: |
| case X86::BI__builtin_ia32_palignr256: |
| case X86::BI__builtin_ia32_palignr512: |
| case X86::BI__builtin_ia32_alignq512: |
| case X86::BI__builtin_ia32_alignd512: |
| case X86::BI__builtin_ia32_alignd128: |
| case X86::BI__builtin_ia32_alignd256: |
| case X86::BI__builtin_ia32_alignq128: |
| case X86::BI__builtin_ia32_alignq256: |
| case X86::BI__builtin_ia32_vcomisd: |
| case X86::BI__builtin_ia32_vcomiss: |
| case X86::BI__builtin_ia32_shuf_f32x4: |
| case X86::BI__builtin_ia32_shuf_f64x2: |
| case X86::BI__builtin_ia32_shuf_i32x4: |
| case X86::BI__builtin_ia32_shuf_i64x2: |
| case X86::BI__builtin_ia32_shufpd512: |
| case X86::BI__builtin_ia32_shufps: |
| case X86::BI__builtin_ia32_shufps256: |
| case X86::BI__builtin_ia32_shufps512: |
| case X86::BI__builtin_ia32_dbpsadbw128: |
| case X86::BI__builtin_ia32_dbpsadbw256: |
| case X86::BI__builtin_ia32_dbpsadbw512: |
| case X86::BI__builtin_ia32_vpshldd128: |
| case X86::BI__builtin_ia32_vpshldd256: |
| case X86::BI__builtin_ia32_vpshldd512: |
| case X86::BI__builtin_ia32_vpshldq128: |
| case X86::BI__builtin_ia32_vpshldq256: |
| case X86::BI__builtin_ia32_vpshldq512: |
| case X86::BI__builtin_ia32_vpshldw128: |
| case X86::BI__builtin_ia32_vpshldw256: |
| case X86::BI__builtin_ia32_vpshldw512: |
| case X86::BI__builtin_ia32_vpshrdd128: |
| case X86::BI__builtin_ia32_vpshrdd256: |
| case X86::BI__builtin_ia32_vpshrdd512: |
| case X86::BI__builtin_ia32_vpshrdq128: |
| case X86::BI__builtin_ia32_vpshrdq256: |
| case X86::BI__builtin_ia32_vpshrdq512: |
| case X86::BI__builtin_ia32_vpshrdw128: |
| case X86::BI__builtin_ia32_vpshrdw256: |
| case X86::BI__builtin_ia32_vpshrdw512: |
| case X86::BI__builtin_ia32_vminmaxbf16128: |
| case X86::BI__builtin_ia32_vminmaxbf16256: |
| case X86::BI__builtin_ia32_vminmaxbf16512: |
| case X86::BI__builtin_ia32_vminmaxpd128_mask: |
| case X86::BI__builtin_ia32_vminmaxpd256_round_mask: |
| case X86::BI__builtin_ia32_vminmaxph128_mask: |
| case X86::BI__builtin_ia32_vminmaxph256_round_mask: |
| case X86::BI__builtin_ia32_vminmaxps128_mask: |
| case X86::BI__builtin_ia32_vminmaxps256_round_mask: |
| case X86::BI__builtin_ia32_vminmaxpd512_round_mask: |
| case X86::BI__builtin_ia32_vminmaxps512_round_mask: |
| case X86::BI__builtin_ia32_vminmaxph512_round_mask: |
| case X86::BI__builtin_ia32_vminmaxsd_round_mask: |
| case X86::BI__builtin_ia32_vminmaxsh_round_mask: |
| case X86::BI__builtin_ia32_vminmaxss_round_mask: |
| i = 2; |
| l = 0; |
| u = 255; |
| break; |
| case X86::BI__builtin_ia32_fixupimmpd512_mask: |
| case X86::BI__builtin_ia32_fixupimmpd512_maskz: |
| case X86::BI__builtin_ia32_fixupimmps512_mask: |
| case X86::BI__builtin_ia32_fixupimmps512_maskz: |
| case X86::BI__builtin_ia32_fixupimmsd_mask: |
| case X86::BI__builtin_ia32_fixupimmsd_maskz: |
| case X86::BI__builtin_ia32_fixupimmss_mask: |
| case X86::BI__builtin_ia32_fixupimmss_maskz: |
| case X86::BI__builtin_ia32_fixupimmpd128_mask: |
| case X86::BI__builtin_ia32_fixupimmpd128_maskz: |
| case X86::BI__builtin_ia32_fixupimmpd256_mask: |
| case X86::BI__builtin_ia32_fixupimmpd256_maskz: |
| case X86::BI__builtin_ia32_fixupimmps128_mask: |
| case X86::BI__builtin_ia32_fixupimmps128_maskz: |
| case X86::BI__builtin_ia32_fixupimmps256_mask: |
| case X86::BI__builtin_ia32_fixupimmps256_maskz: |
| case X86::BI__builtin_ia32_pternlogd512_mask: |
| case X86::BI__builtin_ia32_pternlogd512_maskz: |
| case X86::BI__builtin_ia32_pternlogq512_mask: |
| case X86::BI__builtin_ia32_pternlogq512_maskz: |
| case X86::BI__builtin_ia32_pternlogd128_mask: |
| case X86::BI__builtin_ia32_pternlogd128_maskz: |
| case X86::BI__builtin_ia32_pternlogd256_mask: |
| case X86::BI__builtin_ia32_pternlogd256_maskz: |
| case X86::BI__builtin_ia32_pternlogq128_mask: |
| case X86::BI__builtin_ia32_pternlogq128_maskz: |
| case X86::BI__builtin_ia32_pternlogq256_mask: |
| case X86::BI__builtin_ia32_pternlogq256_maskz: |
| case X86::BI__builtin_ia32_vsm3rnds2: |
| i = 3; |
| l = 0; |
| u = 255; |
| break; |
| 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: |
| case X86::BI__builtin_ia32_rndscalesh_round_mask: |
| case X86::BI__builtin_ia32_reducesh_mask: |
| i = 4; |
| l = 0; |
| u = 255; |
| break; |
| case X86::BI__builtin_ia32_cmpccxadd32: |
| case X86::BI__builtin_ia32_cmpccxadd64: |
| i = 3; |
| l = 0; |
| u = 15; |
| break; |
| } |
| |
| // Note that we don't force a hard error on the range check here, allowing |
| // template-generated or macro-generated dead code to potentially have out-of- |
| // range values. These need to code generate, but don't need to necessarily |
| // make any sense. We use a warning that defaults to an error. |
| return SemaRef.BuiltinConstantArgRange(TheCall, i, l, u, |
| /*RangeIsError*/ false); |
| } |
| |
| void SemaX86::handleAnyInterruptAttr(Decl *D, const ParsedAttr &AL) { |
| // Semantic checks for a function with the 'interrupt' attribute. |
| // a) Must be a function. |
| // b) Must have the 'void' return type. |
| // c) Must take 1 or 2 arguments. |
| // d) The 1st argument must be a pointer. |
| // e) The 2nd argument (if any) must be an unsigned integer. |
| ASTContext &Context = getASTContext(); |
| |
| if (!isFuncOrMethodForAttrSubject(D) || !hasFunctionProto(D) || |
| isInstanceMethod(D) || |
| CXXMethodDecl::isStaticOverloadedOperator( |
| cast<NamedDecl>(D)->getDeclName().getCXXOverloadedOperator())) { |
| Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) |
| << AL << AL.isRegularKeywordAttribute() |
| << ExpectedFunctionWithProtoType; |
| return; |
| } |
| // Interrupt handler must have void return type. |
| if (!getFunctionOrMethodResultType(D)->isVoidType()) { |
| Diag(getFunctionOrMethodResultSourceRange(D).getBegin(), |
| diag::err_anyx86_interrupt_attribute) |
| << (SemaRef.Context.getTargetInfo().getTriple().getArch() == |
| llvm::Triple::x86 |
| ? 0 |
| : 1) |
| << 0; |
| return; |
| } |
| // Interrupt handler must have 1 or 2 parameters. |
| unsigned NumParams = getFunctionOrMethodNumParams(D); |
| if (NumParams < 1 || NumParams > 2) { |
| Diag(D->getBeginLoc(), diag::err_anyx86_interrupt_attribute) |
| << (Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86 |
| ? 0 |
| : 1) |
| << 1; |
| return; |
| } |
| // The first argument must be a pointer. |
| if (!getFunctionOrMethodParamType(D, 0)->isPointerType()) { |
| Diag(getFunctionOrMethodParamRange(D, 0).getBegin(), |
| diag::err_anyx86_interrupt_attribute) |
| << (Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86 |
| ? 0 |
| : 1) |
| << 2; |
| return; |
| } |
| // The second argument, if present, must be an unsigned integer. |
| unsigned TypeSize = |
| Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86_64 |
| ? 64 |
| : 32; |
| if (NumParams == 2 && |
| (!getFunctionOrMethodParamType(D, 1)->isUnsignedIntegerType() || |
| Context.getTypeSize(getFunctionOrMethodParamType(D, 1)) != TypeSize)) { |
| Diag(getFunctionOrMethodParamRange(D, 1).getBegin(), |
| diag::err_anyx86_interrupt_attribute) |
| << (Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86 |
| ? 0 |
| : 1) |
| << 3 << Context.getIntTypeForBitwidth(TypeSize, /*Signed=*/false); |
| return; |
| } |
| D->addAttr(::new (Context) AnyX86InterruptAttr(Context, AL)); |
| D->addAttr(UsedAttr::CreateImplicit(Context)); |
| } |
| |
| void SemaX86::handleForceAlignArgPointerAttr(Decl *D, const ParsedAttr &AL) { |
| // If we try to apply it to a function pointer, don't warn, but don't |
| // do anything, either. It doesn't matter anyway, because there's nothing |
| // special about calling a force_align_arg_pointer function. |
| const auto *VD = dyn_cast<ValueDecl>(D); |
| if (VD && VD->getType()->isFunctionPointerType()) |
| return; |
| // Also don't warn on function pointer typedefs. |
| const auto *TD = dyn_cast<TypedefNameDecl>(D); |
| if (TD && (TD->getUnderlyingType()->isFunctionPointerType() || |
| TD->getUnderlyingType()->isFunctionType())) |
| return; |
| // Attribute can only be applied to function types. |
| if (!isa<FunctionDecl>(D)) { |
| Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) |
| << AL << AL.isRegularKeywordAttribute() << ExpectedFunction; |
| return; |
| } |
| |
| D->addAttr(::new (getASTContext()) |
| X86ForceAlignArgPointerAttr(getASTContext(), AL)); |
| } |
| |
| } // namespace clang |