Skip to content

Commit

Permalink
[X86][AArch64][PowerPC] __builtin_cpu_supports accepts unknown option…
Browse files Browse the repository at this point in the history
…s. (#83515)

The patch fixes #83407
modifing __builtin_cpu_supports behaviour so that it returns false if
unsupported features names provided in parameter and issue a warning.
__builtin_cpu_supports is target independent, but currently supported by
X86, AArch64 and PowerPC only.
  • Loading branch information
ilinpv committed Mar 1, 2024
1 parent 195744c commit 185b1df
Show file tree
Hide file tree
Showing 7 changed files with 30 additions and 14 deletions.
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -765,7 +765,7 @@ def err_builtin_redeclare : Error<"cannot redeclare builtin function %0">;
def err_arm_invalid_specialreg : Error<"invalid special register for builtin">;
def err_arm_invalid_coproc : Error<"coprocessor %0 must be configured as "
"%select{GCP|CDE}1">;
def err_invalid_cpu_supports : Error<"invalid cpu feature string for builtin">;
def warn_invalid_cpu_supports : Warning<"invalid cpu feature string for builtin">;
def err_invalid_cpu_is : Error<"invalid cpu name for builtin">;
def err_invalid_cpu_specific_dispatch_value : Error<
"invalid option '%0' for %select{cpu_specific|cpu_dispatch}1">;
Expand Down
7 changes: 6 additions & 1 deletion clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13952,6 +13952,8 @@ Value *CodeGenFunction::EmitX86CpuIs(StringRef CPUStr) {
Value *CodeGenFunction::EmitX86CpuSupports(const CallExpr *E) {
const Expr *FeatureExpr = E->getArg(0)->IgnoreParenCasts();
StringRef FeatureStr = cast<StringLiteral>(FeatureExpr)->getString();
if (!getContext().getTargetInfo().validateCpuSupports(FeatureStr))
return Builder.getFalse();
return EmitX86CpuSupports(FeatureStr);
}

Expand Down Expand Up @@ -14041,6 +14043,8 @@ Value *CodeGenFunction::EmitAArch64CpuSupports(const CallExpr *E) {
ArgStr.split(Features, "+");
for (auto &Feature : Features) {
Feature = Feature.trim();
if (!llvm::AArch64::parseArchExtension(Feature))
return Builder.getFalse();
if (Feature != "default")
Features.push_back(Feature);
}
Expand Down Expand Up @@ -16639,7 +16643,8 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
.Case(Name, {FA_WORD, Bitmask})
#include "llvm/TargetParser/PPCTargetParser.def"
.Default({0, 0});
assert(BitMask && "Invalid target feature string. Missed by SemaChecking?");
if (!BitMask)
return Builder.getFalse();
Value *Op0 = llvm::ConstantInt::get(Int32Ty, FeatureWord);
llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_fixed_addr_ld);
Value *TheCall = Builder.CreateCall(F, {Op0}, "cpu_supports");
Expand Down
8 changes: 5 additions & 3 deletions clang/lib/Sema/SemaChecking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2180,9 +2180,11 @@ static bool SemaBuiltinCpu(Sema &S, const TargetInfo &TI, CallExpr *TheCall,

// Check the contents of the string.
StringRef Feature = cast<StringLiteral>(Arg)->getString();
if (IsCPUSupports && !TheTI->validateCpuSupports(Feature))
return S.Diag(TheCall->getBeginLoc(), diag::err_invalid_cpu_supports)
<< Arg->getSourceRange();
if (IsCPUSupports && !TheTI->validateCpuSupports(Feature)) {
S.Diag(TheCall->getBeginLoc(), diag::warn_invalid_cpu_supports)
<< Arg->getSourceRange();
return false;
}
if (!IsCPUSupports && !TheTI->validateCpuIs(Feature))
return S.Diag(TheCall->getBeginLoc(), diag::err_invalid_cpu_is)
<< Arg->getSourceRange();
Expand Down
8 changes: 8 additions & 0 deletions clang/test/CodeGen/aarch64-cpu-supports.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
// CHECK-NEXT: store i32 3, ptr [[RETVAL]], align 4
// CHECK-NEXT: br label [[RETURN]]
// CHECK: if.end4:
// CHECK-NEXT: br i1 false, label [[IF_THEN5:%.*]], label [[IF_END6:%.*]]
// CHECK: if.then5:
// CHECK-NEXT: store i32 4, ptr [[RETVAL]], align 4
// CHECK-NEXT: br label [[RETURN]]
// CHECK: if.end6:
// CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4
// CHECK-NEXT: br label [[RETURN]]
// CHECK: return:
Expand All @@ -50,5 +55,8 @@ int main(void) {
if (__builtin_cpu_supports("sme2+ls64_v+wfxt"))
return 3;

if (__builtin_cpu_supports("avx2"))
return 4;

return 0;
}
3 changes: 2 additions & 1 deletion clang/test/Misc/warning-flags.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ This test serves two purposes:

The list of warnings below should NEVER grow. It should gradually shrink to 0.

CHECK: Warnings without flags (66):
CHECK: Warnings without flags (67):

CHECK-NEXT: ext_expected_semi_decl_list
CHECK-NEXT: ext_explicit_specialization_storage_class
Expand Down Expand Up @@ -58,6 +58,7 @@ CHECK-NEXT: warn_ignoring_ftabstop_value
CHECK-NEXT: warn_implements_nscopying
CHECK-NEXT: warn_incompatible_qualified_id
CHECK-NEXT: warn_invalid_asm_cast_lvalue
CHECK-NEXT: warn_invalid_cpu_supports
CHECK-NEXT: warn_maynot_respond
CHECK-NEXT: warn_method_param_redefinition
CHECK-NEXT: warn_missing_case_for_condition
Expand Down
10 changes: 5 additions & 5 deletions clang/test/Sema/aarch64-cpu-supports.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@ int test_aarch64_features(void) {
// expected-error@+1 {{expression is not a string literal}}
if (__builtin_cpu_supports(ssbs2))
return 1;
// expected-error@+1 {{invalid cpu feature string}}
// expected-warning@+1 {{invalid cpu feature string}}
if (__builtin_cpu_supports(""))
return 2;
// expected-error@+1 {{invalid cpu feature string}}
// expected-warning@+1 {{invalid cpu feature string}}
if (__builtin_cpu_supports("pmull128"))
return 3;
// expected-error@+1 {{invalid cpu feature string}}
// expected-warning@+1 {{invalid cpu feature string}}
if (__builtin_cpu_supports("sve2,rpres"))
return 4;
// expected-error@+1 {{invalid cpu feature string}}
// expected-warning@+1 {{invalid cpu feature string}}
if (__builtin_cpu_supports("dgh+sve2-pmull"))
return 5;
// expected-error@+1 {{invalid cpu feature string}}
// expected-warning@+1 {{invalid cpu feature string}}
if (__builtin_cpu_supports("default"))
return 6;
if (__builtin_cpu_supports(" ssbs + bti "))
Expand Down
6 changes: 3 additions & 3 deletions clang/test/Sema/builtin-cpu-supports.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ extern const char *str;

int main(void) {
#ifdef __x86_64__
if (__builtin_cpu_supports("ss")) // expected-error {{invalid cpu feature string}}
if (__builtin_cpu_supports("ss")) // expected-warning {{invalid cpu feature string}}
a("sse4.2");

if (__builtin_cpu_supports(str)) // expected-error {{expression is not a string literal}}
Expand All @@ -25,9 +25,9 @@ int main(void) {
(void)__builtin_cpu_supports("x86-64-v2");
(void)__builtin_cpu_supports("x86-64-v3");
(void)__builtin_cpu_supports("x86-64-v4");
(void)__builtin_cpu_supports("x86-64-v5"); // expected-error {{invalid cpu feature string for builtin}}
(void)__builtin_cpu_supports("x86-64-v5"); // expected-warning {{invalid cpu feature string for builtin}}
#else
if (__builtin_cpu_supports("neon")) // expected-error {{invalid cpu feature string for builtin}}
if (__builtin_cpu_supports("neon")) // expected-warning {{invalid cpu feature string for builtin}}
a("vsx");

if (__builtin_cpu_is("cortex-x3")) // expected-error {{builtin is not supported on this target}}
Expand Down

0 comments on commit 185b1df

Please sign in to comment.