llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-codegen Author: Abhishek Kaushik (abhishek-kaushik22) <details> <summary>Changes</summary> Fixes #<!-- -->149866 --- Full diff: https://github.com/llvm/llvm-project/pull/154801.diff 8 Files Affected: - (modified) clang/docs/ReleaseNotes.rst (+3) - (modified) clang/include/clang/Basic/DiagnosticFrontendKinds.td (+5) - (modified) clang/lib/CodeGen/CGCall.cpp (+6-3) - (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+31-14) - (added) clang/test/CodeGen/target-features-error-3.c (+12) - (added) clang/test/CodeGen/target-features-error-4.c (+12) - (added) clang/test/CodeGen/target-features-error-5.c (+12) - (added) clang/test/CodeGen/target-features-no-error-2.c (+12) ``````````diff diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index fe1dd15c6f885..ebd5b7621ef91 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -229,6 +229,9 @@ Bug Fixes in This Version cast chain. (#GH149967). - Fixed a crash with incompatible pointer to integer conversions in designated initializers involving string literals. (#GH154046) +- Clang now emits a frontend error when a function marked with the `flatten` attribute + calls another function that requires target features not enabled in the caller. This + prevents a fatal error in the backend. Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td index 8a8db27490f06..a3b918842f53e 100644 --- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -287,6 +287,11 @@ def err_function_needs_feature : Error< "always_inline function %1 requires target feature '%2', but would " "be inlined into function %0 that is compiled without support for '%2'">; +def err_flatten_function_needs_feature + : Error<"flatten function %0 calls %1 which requires target feature '%2', " + "but the " + "caller is compiled without support for '%2'">; + let CategoryName = "Codegen ABI Check" in { def err_function_always_inline_attribute_mismatch : Error< "always_inline function %1 and its caller %0 have mismatching %2 attributes">; diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 466546b2f1309..9c4fa12f18b20 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -5261,9 +5261,12 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, // since otherwise we could be making a conditional call after a check for // the proper cpu features (and it won't cause code generation issues due to // function based code generation). - if (TargetDecl->hasAttr<AlwaysInlineAttr>() && - (TargetDecl->hasAttr<TargetAttr>() || - (CurFuncDecl && CurFuncDecl->hasAttr<TargetAttr>()))) + if ((TargetDecl->hasAttr<AlwaysInlineAttr>() && + (TargetDecl->hasAttr<TargetAttr>() || + (CurFuncDecl && CurFuncDecl->hasAttr<TargetAttr>()))) || + (CurFuncDecl && CurFuncDecl->hasAttr<FlattenAttr>() && + (CurFuncDecl->hasAttr<TargetAttr>() || + TargetDecl->hasAttr<TargetAttr>()))) checkTargetFeatures(Loc, FD); } diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 652fe672f15e3..9854dae33d6f3 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -2827,6 +2827,9 @@ void CodeGenFunction::checkTargetFeatures(SourceLocation Loc, if (!FD) return; + bool IsAlwaysInline = TargetDecl->hasAttr<AlwaysInlineAttr>(); + bool IsFlatten = FD && FD->hasAttr<FlattenAttr>(); + // Grab the required features for the call. For a builtin this is listed in // the td file with the default cpu, for an always_inline function this is any // listed cpu and any listed features. @@ -2869,25 +2872,39 @@ void CodeGenFunction::checkTargetFeatures(SourceLocation Loc, if (F.getValue()) ReqFeatures.push_back(F.getKey()); } - if (!llvm::all_of(ReqFeatures, [&](StringRef Feature) { - if (!CallerFeatureMap.lookup(Feature)) { - MissingFeature = Feature.str(); - return false; - } - return true; - }) && !IsHipStdPar) - CGM.getDiags().Report(Loc, diag::err_function_needs_feature) - << FD->getDeclName() << TargetDecl->getDeclName() << MissingFeature; + if (!llvm::all_of(ReqFeatures, + [&](StringRef Feature) { + if (!CallerFeatureMap.lookup(Feature)) { + MissingFeature = Feature.str(); + return false; + } + return true; + }) && + !IsHipStdPar) { + if (IsAlwaysInline) + CGM.getDiags().Report(Loc, diag::err_function_needs_feature) + << FD->getDeclName() << TargetDecl->getDeclName() << MissingFeature; + else if (IsFlatten) + CGM.getDiags().Report(Loc, diag::err_flatten_function_needs_feature) + << FD->getDeclName() << TargetDecl->getDeclName() << MissingFeature; + } + } else if (!FD->isMultiVersion() && FD->hasAttr<TargetAttr>()) { llvm::StringMap<bool> CalleeFeatureMap; CGM.getContext().getFunctionFeatureMap(CalleeFeatureMap, TargetDecl); for (const auto &F : CalleeFeatureMap) { - if (F.getValue() && (!CallerFeatureMap.lookup(F.getKey()) || - !CallerFeatureMap.find(F.getKey())->getValue()) && - !IsHipStdPar) - CGM.getDiags().Report(Loc, diag::err_function_needs_feature) - << FD->getDeclName() << TargetDecl->getDeclName() << F.getKey(); + if (F.getValue() && + (!CallerFeatureMap.lookup(F.getKey()) || + !CallerFeatureMap.find(F.getKey())->getValue()) && + !IsHipStdPar) { + if (IsAlwaysInline) + CGM.getDiags().Report(Loc, diag::err_function_needs_feature) + << FD->getDeclName() << TargetDecl->getDeclName() << F.getKey(); + else if (IsFlatten) + CGM.getDiags().Report(Loc, diag::err_flatten_function_needs_feature) + << FD->getDeclName() << TargetDecl->getDeclName() << F.getKey(); + } } } } diff --git a/clang/test/CodeGen/target-features-error-3.c b/clang/test/CodeGen/target-features-error-3.c new file mode 100644 index 0000000000000..ff4866ac69ca0 --- /dev/null +++ b/clang/test/CodeGen/target-features-error-3.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -emit-llvm -verify -o /dev/null + +typedef double __v2df __attribute__((__vector_size__(16))); + +__v2df __attribute__((target("sse4.1"))) foo() { + __v2df v = {0.0, 0.0}; + return __builtin_ia32_roundpd(v, 2); +} + +__v2df __attribute__((flatten)) bar() { + return foo(); // expected-error {{flatten function 'bar' calls 'foo' which requires target feature 'sse4.1', but the caller is compiled without support for 'sse4.1'}} +} diff --git a/clang/test/CodeGen/target-features-error-4.c b/clang/test/CodeGen/target-features-error-4.c new file mode 100644 index 0000000000000..fe4879e03b660 --- /dev/null +++ b/clang/test/CodeGen/target-features-error-4.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -emit-llvm -verify -o /dev/null + +typedef double __v2df __attribute__((__vector_size__(16))); + +__v2df __attribute__((target("sse4.1"))) foo() { + __v2df v = {0.0, 0.0}; + return __builtin_ia32_roundpd(v, 2); +} + +__v2df __attribute__((target("no-sse4.1"), flatten)) bar() { + return foo(); // expected-error {{flatten function 'bar' calls 'foo' which requires target feature 'sse4.1', but the caller is compiled without support for 'sse4.1'}} +} diff --git a/clang/test/CodeGen/target-features-error-5.c b/clang/test/CodeGen/target-features-error-5.c new file mode 100644 index 0000000000000..8bc3ba193463d --- /dev/null +++ b/clang/test/CodeGen/target-features-error-5.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -target-feature +sse4.1 -emit-llvm -verify -o /dev/null + +typedef double __v2df __attribute__((__vector_size__(16))); + +__v2df foo() { + __v2df v = {0.0, 0.0}; + return __builtin_ia32_roundpd(v, 2); +} + +__v2df __attribute__((target("no-sse4.1"), flatten)) bar() { + return foo(); // expected-error {{flatten function 'bar' calls 'foo' which requires target feature 'sse4.1', but the caller is compiled without support for 'sse4.1'}} +} diff --git a/clang/test/CodeGen/target-features-no-error-2.c b/clang/test/CodeGen/target-features-no-error-2.c new file mode 100644 index 0000000000000..eeec3f3d05d7b --- /dev/null +++ b/clang/test/CodeGen/target-features-no-error-2.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -emit-llvm -verify -o /dev/null + +typedef double __v2df __attribute__((__vector_size__(16))); + +__v2df __attribute__((target("sse4.1"))) foo() { + __v2df v = {0.0, 0.0}; + return __builtin_ia32_roundpd(v, 2); +} + +__v2df __attribute__((target("sse4.1"), flatten)) bar() { + return foo(); // expected-no-diagnostics +} `````````` </details> https://github.com/llvm/llvm-project/pull/154801 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits