[mips] Check that features required by built-ins are enabled

Now Clang does not check that features required by built-in functions
are enabled. That causes errors in the backend reported in PR44018.

This patch fixes this bug by checking that required features
are enabled.

This should fix PR44018.

Differential Revision: https://reviews.llvm.org/D70808
This commit is contained in:
Simon Atanasyan 2019-11-27 19:09:50 +03:00
parent ec3efcf11f
commit f4d32ae75b
7 changed files with 83 additions and 4 deletions

View File

@ -8742,6 +8742,12 @@ def err_32_bit_builtin_64_bit_tgt : Error<
"this builtin is only available on 32-bit targets">;
def err_builtin_x64_aarch64_only : Error<
"this builtin is only available on x86-64 and aarch64 targets">;
def err_mips_builtin_requires_dsp : Error<
"this builtin requires 'dsp' ASE, please use -mdsp">;
def err_mips_builtin_requires_dspr2 : Error<
"this builtin requires 'dsp r2' ASE, please use -mdspr2">;
def err_mips_builtin_requires_msa : Error<
"this builtin requires 'msa' ASE, please use -mmsa">;
def err_ppc_builtin_only_on_pwr7 : Error<
"this builtin is only valid on POWER7 or later CPUs">;
def err_x86_builtin_invalid_rounding : Error<

View File

@ -11282,6 +11282,8 @@ private:
bool CheckHexagonBuiltinCpu(unsigned BuiltinID, CallExpr *TheCall);
bool CheckHexagonBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall);
bool CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
bool CheckMipsBuiltinCpu(unsigned BuiltinID, CallExpr *TheCall);
bool CheckMipsBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall);
bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
bool CheckX86BuiltinRoundingOrSAE(unsigned BuiltinID, CallExpr *TheCall);
bool CheckX86BuiltinGatherScatterScale(unsigned BuiltinID, CallExpr *TheCall);

View File

@ -213,7 +213,10 @@ void MipsTargetInfo::getTargetDefines(const LangOptions &Opts,
bool MipsTargetInfo::hasFeature(StringRef Feature) const {
return llvm::StringSwitch<bool>(Feature)
.Case("mips", true)
.Case("dsp", DspRev >= DSP1)
.Case("dspr2", DspRev >= DSP2)
.Case("fp64", FPMode == FP64)
.Case("msa", HasMSA)
.Default(false);
}

View File

@ -3051,8 +3051,37 @@ bool Sema::CheckHexagonBuiltinFunctionCall(unsigned BuiltinID,
CheckHexagonBuiltinArgument(BuiltinID, TheCall);
}
bool Sema::CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
return CheckMipsBuiltinCpu(BuiltinID, TheCall) ||
CheckMipsBuiltinArgument(BuiltinID, TheCall);
}
// CheckMipsBuiltinFunctionCall - Checks the constant value passed to the
bool Sema::CheckMipsBuiltinCpu(unsigned BuiltinID, CallExpr *TheCall) {
const TargetInfo &TI = Context.getTargetInfo();
if (Mips::BI__builtin_mips_addu_qb <= BuiltinID &&
BuiltinID <= Mips::BI__builtin_mips_lwx) {
if (!TI.hasFeature("dsp"))
return Diag(TheCall->getBeginLoc(), diag::err_mips_builtin_requires_dsp);
}
if (Mips::BI__builtin_mips_absq_s_qb <= BuiltinID &&
BuiltinID <= Mips::BI__builtin_mips_subuh_r_qb) {
if (!TI.hasFeature("dspr2"))
return Diag(TheCall->getBeginLoc(),
diag::err_mips_builtin_requires_dspr2);
}
if (Mips::BI__builtin_msa_add_a_b <= BuiltinID &&
BuiltinID <= Mips::BI__builtin_msa_xori_b) {
if (!TI.hasFeature("msa"))
return Diag(TheCall->getBeginLoc(), diag::err_mips_builtin_requires_msa);
}
return false;
}
// CheckMipsBuiltinArgument - Checks the constant value passed to the
// intrinsic is correct. The switch statement is ordered by DSP, MSA. The
// ordering for DSP is unspecified. MSA is ordered by the data format used
// by the underlying instruction i.e., df/m, df/n and then by size.
@ -3061,7 +3090,7 @@ bool Sema::CheckHexagonBuiltinFunctionCall(unsigned BuiltinID,
// definitions from include/clang/Basic/BuiltinsMips.def.
// FIXME: GCC is strict on signedness for some of these intrinsics, we should
// be too.
bool Sema::CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
bool Sema::CheckMipsBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall) {
unsigned i = 0, l = 0, u = 0, m = 0;
switch (BuiltinID) {
default: return false;

View File

@ -1,5 +1,6 @@
// REQUIRES: mips-registered-target
// RUN: %clang_cc1 -triple mips-unknown-linux-gnu -fsyntax-only -verify %s
// RUN: %clang_cc1 -triple mips-unknown-linux-gnu -target-feature +dspr2 \
// RUN: -fsyntax-only -verify %s
void foo() {
// MIPS DSP Rev 1

View File

@ -1,5 +1,6 @@
// REQUIRES: mips-registered-target
// RUN: %clang_cc1 -triple mips-unknown-linux-gnu -emit-llvm %s -o - \
// RUN: %clang_cc1 -triple mips-unknown-linux-gnu -emit-llvm %s \
// RUN: -target-feature +dspr2 -o - \
// RUN: | FileCheck %s
typedef int q31;

View File

@ -0,0 +1,37 @@
// REQUIRES: mips-registered-target
// RUN: %clang_cc1 -triple mips64 -fsyntax-only -verify %s
typedef signed char v4i8 __attribute__ ((vector_size(4)));
typedef signed char v4q7 __attribute__ ((vector_size(4)));
typedef signed char v16i8 __attribute__((vector_size(16), aligned(16)));
typedef unsigned char v16u8 __attribute__((vector_size(16), aligned(16)));
void dsp() {
v4i8 a;
void* p;
// expected-error@+1 {{this builtin requires 'dsp' ASE, please use -mdsp}}
__builtin_mips_addu_qb(a, a);
// expected-error@+1 {{this builtin requires 'dsp' ASE, please use -mdsp}}
__builtin_mips_lwx(p, 32);
}
void dspr2() {
v4i8 a;
v4q7 b;
// expected-error@+1 {{this builtin requires 'dsp r2' ASE, please use -mdspr2}}
__builtin_mips_absq_s_qb(b);
// expected-error@+1 {{this builtin requires 'dsp r2' ASE, please use -mdspr2}}
__builtin_mips_subuh_r_qb(a, a);
}
void msa() {
v16i8 a;
v16u8 b;
// expected-error@+1 {{this builtin requires 'msa' ASE, please use -mmsa}}
__builtin_msa_add_a_b(a, a);
// expected-error@+1 {{this builtin requires 'msa' ASE, please use -mmsa}}
__builtin_msa_xori_b(b, 5);
}