-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[Clang]Throw frontend error for target feature mismatch when using flatten attribute #154801
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…atten attribute Fixes llvm#149866
|
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-codegen Author: Abhishek Kaushik (abhishek-kaushik22) ChangesFixes #149866 Full diff: https://github.com/llvm/llvm-project/pull/154801.diff 8 Files Affected:
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
+}
|
|
@efriedma-quic @AaronBallman Can you please review this one? I messed up the last pr |
AaronBallman
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM aside from a formatting nit
|
The failing test looks unrelated to this change |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/186/builds/11865 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/141/builds/11075 Here is the relevant piece of the build log for the reference |
Fixes #149866