
Sema currently has checkTargetVersionAttr and checkTargetClonesAttrString to diagnose the said attributes. However the code tries to handle all of AArch64, RISC-V and X86 targets at once which is hard to maintain, therefore I am splitting these functions. Unfortunately I could not use polymorphism because all of Sema, SemaARM, SemaRISCV and SemaX86 inherit from SemaBase. The Sema instance itself contains instances of every other target specific Sema.
1122 lines
44 KiB
C++
1122 lines
44 KiB
C++
//===------ 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:
|
|
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_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_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_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:
|
|
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_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_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_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:
|
|
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_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_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_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_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_vcvt2ps2phx512_mask:
|
|
ArgNum = 4;
|
|
HasRC = true;
|
|
break;
|
|
case X86::BI__builtin_ia32_vcvttpd2dqs512_round_mask:
|
|
case X86::BI__builtin_ia32_vcvttpd2udqs512_round_mask:
|
|
case X86::BI__builtin_ia32_vcvttpd2qqs512_round_mask:
|
|
case X86::BI__builtin_ia32_vcvttpd2uqqs512_round_mask:
|
|
case X86::BI__builtin_ia32_vcvttps2dqs512_round_mask:
|
|
case X86::BI__builtin_ia32_vcvttps2udqs512_round_mask:
|
|
case X86::BI__builtin_ia32_vcvttps2qqs512_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_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_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_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_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_mask:
|
|
case X86::BI__builtin_ia32_vminmaxph128_mask:
|
|
case X86::BI__builtin_ia32_vminmaxph256_mask:
|
|
case X86::BI__builtin_ia32_vminmaxps128_mask:
|
|
case X86::BI__builtin_ia32_vminmaxps256_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;
|
|
case X86::BI__builtin_ia32_prefetchi:
|
|
i = 1;
|
|
l = 2; // _MM_HINT_T1
|
|
u = 3; // _MM_HINT_T0
|
|
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));
|
|
}
|
|
|
|
bool SemaX86::checkTargetClonesAttr(
|
|
SmallVectorImpl<StringRef> &Params, SmallVectorImpl<SourceLocation> &Locs,
|
|
SmallVectorImpl<SmallString<64>> &NewParams) {
|
|
using namespace DiagAttrParams;
|
|
|
|
assert(Params.size() == Locs.size() &&
|
|
"Mismatch between number of string parameters and locations");
|
|
|
|
bool HasDefault = false;
|
|
bool HasComma = false;
|
|
for (unsigned I = 0, E = Params.size(); I < E; ++I) {
|
|
const StringRef Param = Params[I].trim();
|
|
const SourceLocation &Loc = Locs[I];
|
|
|
|
if (Param.empty() || Param.ends_with(','))
|
|
return Diag(Loc, diag::warn_unsupported_target_attribute)
|
|
<< Unsupported << None << "" << TargetClones;
|
|
|
|
if (Param.contains(','))
|
|
HasComma = true;
|
|
|
|
StringRef LHS;
|
|
StringRef RHS = Param;
|
|
do {
|
|
std::tie(LHS, RHS) = RHS.split(',');
|
|
LHS = LHS.trim();
|
|
const SourceLocation &CurLoc =
|
|
Loc.getLocWithOffset(LHS.data() - Param.data());
|
|
|
|
if (LHS.starts_with("arch=")) {
|
|
if (!getASTContext().getTargetInfo().isValidCPUName(
|
|
LHS.drop_front(sizeof("arch=") - 1)))
|
|
return Diag(CurLoc, diag::warn_unsupported_target_attribute)
|
|
<< Unsupported << CPU << LHS.drop_front(sizeof("arch=") - 1)
|
|
<< TargetClones;
|
|
} else if (LHS == "default")
|
|
HasDefault = true;
|
|
else if (!getASTContext().getTargetInfo().isValidFeatureName(LHS) ||
|
|
getASTContext().getTargetInfo().getFMVPriority(LHS) == 0)
|
|
return Diag(CurLoc, diag::warn_unsupported_target_attribute)
|
|
<< Unsupported << None << LHS << TargetClones;
|
|
|
|
if (llvm::is_contained(NewParams, LHS))
|
|
Diag(CurLoc, diag::warn_target_clone_duplicate_options);
|
|
// Note: Add even if there are duplicates, since it changes name mangling.
|
|
NewParams.push_back(LHS);
|
|
} while (!RHS.empty());
|
|
}
|
|
if (HasComma && Params.size() > 1)
|
|
Diag(Locs[0], diag::warn_target_clone_mixed_values);
|
|
|
|
if (!HasDefault)
|
|
return Diag(Locs[0], diag::err_target_clone_must_have_default);
|
|
|
|
return false;
|
|
}
|
|
|
|
} // namespace clang
|