-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[Clang][LoongArch] Support target attribute for function #140700
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
|
@llvm/pr-subscribers-backend-loongarch @llvm/pr-subscribers-clang Author: None (Ami-zhang) ChangesThis adds support under LoongArch for the target("..") attributes. The supported formats are:
Full diff: https://github.com/llvm/llvm-project/pull/140700.diff 7 Files Affected:
diff --git a/clang/lib/Basic/Targets/LoongArch.cpp b/clang/lib/Basic/Targets/LoongArch.cpp
index ca742797d7a3b..aee273a76a608 100644
--- a/clang/lib/Basic/Targets/LoongArch.cpp
+++ b/clang/lib/Basic/Targets/LoongArch.cpp
@@ -388,6 +388,51 @@ bool LoongArchTargetInfo::handleTargetFeatures(
return true;
}
+ParsedTargetAttr
+LoongArchTargetInfo::parseTargetAttr(StringRef Features) const {
+ ParsedTargetAttr Ret;
+ if (Features == "default")
+ return Ret;
+ SmallVector<StringRef, 1> AttrFeatures;
+ Features.split(AttrFeatures, ",");
+
+ for (auto &Feature : AttrFeatures) {
+ Feature = Feature.trim();
+
+ if (Feature.starts_with("arch=")) {
+ StringRef ArchValue = Feature.split("=").second.trim();
+
+ if (llvm::LoongArch::isValidArchName(ArchValue) ||
+ ArchValue == "la64v1.0" || ArchValue == "la64v1.1") {
+ std::vector<llvm::StringRef> ArchFeatures;
+ if (llvm::LoongArch::getArchFeatures(ArchValue, ArchFeatures)) {
+ Ret.Features.insert(Ret.Features.end(), ArchFeatures.begin(),
+ ArchFeatures.end());
+ }
+
+ if (!Ret.CPU.empty())
+ Ret.Duplicate = "arch=";
+ else if (ArchValue == "la64v1.0" || ArchValue == "la64v1.1")
+ Ret.CPU = "loongarch64";
+ else
+ Ret.CPU = ArchValue;
+ } else {
+ Ret.Features.push_back("!arch=" + ArchValue.str());
+ }
+ } else if (Feature.starts_with("tune=")) {
+ if (!Ret.Tune.empty())
+ Ret.Duplicate = "tune=";
+ else
+ Ret.Tune = Feature.split("=").second.trim();
+ } else if (Feature.starts_with("no-")) {
+ Ret.Features.push_back("-" + Feature.split("-").second.str());
+ } else {
+ Ret.Features.push_back("+" + Feature.str());
+ }
+ }
+ return Ret;
+}
+
bool LoongArchTargetInfo::isValidCPUName(StringRef Name) const {
return llvm::LoongArch::isValidCPUName(Name);
}
@@ -396,3 +441,7 @@ void LoongArchTargetInfo::fillValidCPUList(
SmallVectorImpl<StringRef> &Values) const {
llvm::LoongArch::fillValidCPUList(Values);
}
+
+bool LoongArchTargetInfo::isValidFeatureName(StringRef Name) const {
+ return llvm::LoongArch::isValidFeatureName(Name);
+}
diff --git a/clang/lib/Basic/Targets/LoongArch.h b/clang/lib/Basic/Targets/LoongArch.h
index 4c7b53abfef9b..a83bb925bc310 100644
--- a/clang/lib/Basic/Targets/LoongArch.h
+++ b/clang/lib/Basic/Targets/LoongArch.h
@@ -101,6 +101,9 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo {
bool handleTargetFeatures(std::vector<std::string> &Features,
DiagnosticsEngine &Diags) override;
+ ParsedTargetAttr parseTargetAttr(StringRef Str) const override;
+ bool supportsTargetAttributeTune() const override { return true; }
+
bool
initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
StringRef CPU,
@@ -110,6 +113,7 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo {
bool isValidCPUName(StringRef Name) const override;
void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
+ bool isValidFeatureName(StringRef Name) const override;
};
class LLVM_LIBRARY_VISIBILITY LoongArch32TargetInfo
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 4d7f0455444f1..8e44e2e44bb24 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -3195,6 +3195,17 @@ bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) {
}
}
+ if (Context.getTargetInfo().getTriple().isLoongArch()) {
+ for (const auto &Feature : ParsedAttrs.Features) {
+ StringRef CurFeature = Feature;
+ if (CurFeature.starts_with("!arch=")) {
+ StringRef ArchValue = CurFeature.split("=").second.trim();
+ return Diag(LiteralLoc, diag::err_attribute_unsupported)
+ << "target(arch=..)" << ArchValue;
+ }
+ }
+ }
+
if (ParsedAttrs.Duplicate != "")
return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
<< Duplicate << None << ParsedAttrs.Duplicate << Target;
diff --git a/clang/test/CodeGen/LoongArch/targetattr.c b/clang/test/CodeGen/LoongArch/targetattr.c
new file mode 100644
index 0000000000000..a99e12051452b
--- /dev/null
+++ b/clang/test/CodeGen/LoongArch/targetattr.c
@@ -0,0 +1,92 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals all --version 5
+// RUN: %clang --target=loongarch64-linux-gnu %s -S -emit-llvm -o - \
+// RUN: | FileCheck %s
+
+__attribute__((target("div32")))
+// CHECK-LABEL: define dso_local void @testdiv32(
+// CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT: [[ENTRY:.*:]]
+// CHECK-NEXT: ret void
+//
+void testdiv32() {}
+
+__attribute__((target("arch=loongarch64")))
+// CHECK-LABEL: define dso_local void @testLoongarch64(
+// CHECK-SAME: ) #[[ATTR1:[0-9]+]] {
+// CHECK-NEXT: [[ENTRY:.*:]]
+// CHECK-NEXT: ret void
+//
+void testLoongarch64() {}
+
+__attribute__((target("arch=la64v1.0")))
+// CHECK-LABEL: define dso_local void @testLa64v10(
+// CHECK-SAME: ) #[[ATTR1]] {
+// CHECK-NEXT: [[ENTRY:.*:]]
+// CHECK-NEXT: ret void
+//
+void testLa64v10() {}
+
+__attribute__((target("arch=la64v1.1")))
+// CHECK-LABEL: define dso_local void @testLa64v11(
+// CHECK-SAME: ) #[[ATTR2:[0-9]+]] {
+// CHECK-NEXT: [[ENTRY:.*:]]
+// CHECK-NEXT: ret void
+//
+void testLa64v11() {}
+
+__attribute__((target("arch=la464")))
+// CHECK-LABEL: define dso_local void @testLa464(
+// CHECK-SAME: ) #[[ATTR3:[0-9]+]] {
+// CHECK-NEXT: [[ENTRY:.*:]]
+// CHECK-NEXT: ret void
+//
+void testLa464() {}
+
+__attribute__((target("arch=la664")))
+// CHECK-LABEL: define dso_local void @testLa664(
+// CHECK-SAME: ) #[[ATTR4:[0-9]+]] {
+// CHECK-NEXT: [[ENTRY:.*:]]
+// CHECK-NEXT: ret void
+//
+void testLa664() {}
+
+__attribute__((target("arch=la664, no-div32")))
+// CHECK-LABEL: define dso_local void @la664Nodiv32(
+// CHECK-SAME: ) #[[ATTR5:[0-9]+]] {
+// CHECK-NEXT: [[ENTRY:.*:]]
+// CHECK-NEXT: ret void
+//
+void la664Nodiv32() {}
+
+__attribute__((target("tune=la464")))
+// CHECK-LABEL: define dso_local void @tuneLa664(
+// CHECK-SAME: ) #[[ATTR6:[0-9]+]] {
+// CHECK-NEXT: [[ENTRY:.*:]]
+// CHECK-NEXT: ret void
+//
+void tuneLa664() {}
+
+__attribute__((target("arch=la464, tune=la664")))
+// CHECK-LABEL: define dso_local void @archLa464tuneLa664(
+// CHECK-SAME: ) #[[ATTR7:[0-9]+]] {
+// CHECK-NEXT: [[ENTRY:.*:]]
+// CHECK-NEXT: ret void
+//
+void archLa464tuneLa664() {}
+
+//.
+// CHECK: attributes #[[ATTR0]] = { noinline nounwind optnone "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="loongarch64" "target-features"="+64bit,+d,+div32,+f,+lsx,+ual" }
+// CHECK: attributes #[[ATTR1]] = { noinline nounwind optnone "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="loongarch64" "target-features"="+64bit,+d,+f,+lsx,+ual" }
+// CHECK: attributes #[[ATTR2]] = { noinline nounwind optnone "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="loongarch64" "target-features"="+64bit,+d,+div32,+f,+frecipe,+lam-bh,+lamcas,+ld-seq-sa,+lsx,+scq,+ual" }
+// CHECK: attributes #[[ATTR3]] = { noinline nounwind optnone "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="la464" "target-features"="+64bit,+d,+f,+lasx,+lsx,+ual" }
+// CHECK: attributes #[[ATTR4]] = { noinline nounwind optnone "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="la664" "target-features"="+64bit,+d,+div32,+f,+frecipe,+lam-bh,+lamcas,+lasx,+ld-seq-sa,+lsx,+scq,+ual" }
+// CHECK: attributes #[[ATTR5]] = { noinline nounwind optnone "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="la664" "target-features"="+64bit,+d,+f,+frecipe,+lam-bh,+lamcas,+lasx,+ld-seq-sa,+lsx,+scq,+ual,-div32" }
+// CHECK: attributes #[[ATTR6]] = { noinline nounwind optnone "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="loongarch64" "target-features"="+64bit,+d,+f,+lsx,+ual" "tune-cpu"="la464" }
+// CHECK: attributes #[[ATTR7]] = { noinline nounwind optnone "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="la464" "target-features"="+64bit,+d,+f,+lasx,+lsx,+ual" "tune-cpu"="la664" }
+//.
+// CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
+// CHECK: [[META1:![0-9]+]] = !{i32 8, !"PIC Level", i32 2}
+// CHECK: [[META2:![0-9]+]] = !{i32 7, !"PIE Level", i32 2}
+// CHECK: [[META3:![0-9]+]] = !{i32 7, !"frame-pointer", i32 2}
+// CHECK: [[META4:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"}
+//.
diff --git a/clang/test/Sema/attr-target-loongarch.c b/clang/test/Sema/attr-target-loongarch.c
new file mode 100644
index 0000000000000..77f13e891ea63
--- /dev/null
+++ b/clang/test/Sema/attr-target-loongarch.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple loongarch64-linux-gnu -fsyntax-only -verify %s
+
+// expected-error@+1 {{function multiversioning is not supported on the current target}}
+void __attribute__((target("default"))) bar(void){}
+
+// expected-error@+1 {{target(arch=..) attribute is not supported on targets missing invalid; specify an appropriate -march= or -mcpu=}}
+void __attribute__((target("arch=invalid"))) foo(void){}
+
+//expected-warning@+1 {{unsupported 'aaa' in the 'target' attribute string; 'target' attribute ignored}}
+int __attribute__((target("aaa"))) test_feature(void) { return 4; }
+
+//expected-warning@+1 {{unsupported 'aaa' in the 'target' attribute string; 'target' attribute ignored}}
+int __attribute__((target("no-aaa"))) test_nofeature(void) { return 4; }
+
+//expected-warning@+1 {{duplicate 'arch=' in the 'target' attribute string; 'target' attribute ignored}}
+int __attribute__((target("arch=la464,arch=la664"))) test_duplarch(void) { return 4; }
+
+//expected-warning@+1 {{unknown tune CPU 'la64v1.0' in the 'target' attribute string; 'target' attribute ignored}}
+int __attribute__((target("tune=la64v1.0"))) test_tune(void) { return 4; }
diff --git a/llvm/include/llvm/TargetParser/LoongArchTargetParser.h b/llvm/include/llvm/TargetParser/LoongArchTargetParser.h
index e08e7bc182e11..c425ce271c559 100644
--- a/llvm/include/llvm/TargetParser/LoongArchTargetParser.h
+++ b/llvm/include/llvm/TargetParser/LoongArchTargetParser.h
@@ -85,6 +85,7 @@ struct ArchInfo {
};
bool isValidArchName(StringRef Arch);
+bool isValidFeatureName(StringRef Arch);
bool getArchFeatures(StringRef Arch, std::vector<StringRef> &Features);
bool isValidCPUName(StringRef TuneCPU);
void fillValidCPUList(SmallVectorImpl<StringRef> &Values);
diff --git a/llvm/lib/TargetParser/LoongArchTargetParser.cpp b/llvm/lib/TargetParser/LoongArchTargetParser.cpp
index e394c0c15b207..7bd1711538d25 100644
--- a/llvm/lib/TargetParser/LoongArchTargetParser.cpp
+++ b/llvm/lib/TargetParser/LoongArchTargetParser.cpp
@@ -34,6 +34,17 @@ bool LoongArch::isValidArchName(StringRef Arch) {
return false;
}
+bool LoongArch::isValidFeatureName(StringRef Feature) {
+ Feature = Feature.starts_with("+") ? Feature.drop_front() : Feature;
+ for (const auto F : AllFeatures) {
+ StringRef CanonicalName =
+ F.Name.starts_with("+") ? F.Name.drop_front() : F.Name;
+ if (CanonicalName == Feature)
+ return true;
+ }
+ return false;
+}
+
bool LoongArch::getArchFeatures(StringRef Arch,
std::vector<StringRef> &Features) {
for (const auto A : AllArchs) {
|
| for (auto &Feature : AttrFeatures) { | ||
| Feature = Feature.trim(); | ||
|
|
||
| if (Feature.starts_with("arch=")) { |
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.
It's recommended to use use a helper function to handle the types of features. Like below.
If it's ok to define a FeatureKind enum, that would be even better.
static std::pair<llvm::StringRef, llvm::StringRef> getFeatureTypeAndValue(llvm::StringRef Feature) {
auto Split = Feature.split("=");
if (!Split.second.empty())
return {Split.first.trim(), Split.second.trim()};
if (Feature.starts_with("no-"))
return {"no", Feature.drop_front(3).trim()};
return {"feature", Feature.trim()};
} for (auto &Feature : AttrFeatures) {
Feature = Feature.trim();
auto [Kind, Value] = getFeatureTypeAndValue(Feature);
if (Kind == "arch") {
} else if (Kind == "tune") {
} ..
}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.
Thanks for the suggestion! Using a helper function with a FeatureKind enum is indeed a cleaner and more modular approach.
However, since parseTargetAttr is a common-layer interface that we are simply overriding, I'd prefer to maintain consistency with the common-layer and current RISCV/AArch64 implementations. Keeping the same style offers several benefits:
- Codebase uniformity – Ensures architectural implementations remain predictable.
- Easier maintenance – Developers working across architectures can recognize the pattern immediately.
- Historical consistency – Follows the established patterns for this interface.
If we decide to refactor this interface globally(e.g., by introducing helper functions), I'd be happy to align the LoongArch implementation accordingly.
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.
I believe that the previous approach was essentially off-the-cuff, done whichever way was most convenient.
If someone were to implement the same functionality for other architectures as well, they would find three pieces of code with very poor style.
To leave behind code that is more ergonomic for future developers, at the very least, the logic for handling features should be separated and handled individually.
auto handleArch = [&](StringRef Feature) { ... }
auto handleTune = [&](StringRef Feature) { ... }
if(feature.startwith("arch=") handleArch(feature)
else (feature.startwith("tune=") handleTune(feature)
else if ( ... ) ...
else {
}
| // RUN: %clang_cc1 -triple loongarch64-linux-gnu -fsyntax-only -verify %s | ||
|
|
||
| // expected-error@+1 {{function multiversioning is not supported on the current target}} | ||
| void __attribute__((target("default"))) bar(void){} |
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.
| void __attribute__((target("default"))) bar(void){} | |
| void __attribute__((target("default"))) bar(void) {} |
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.
Done.
| // expected-error@+1 {{target(arch=..) attribute is not supported on targets missing invalid; specify an appropriate -march= or -mcpu=}} | ||
| void __attribute__((target("arch=invalid"))) foo(void){} | ||
|
|
||
| //expected-warning@+1 {{unsupported 'aaa' in the 'target' attribute string; 'target' attribute ignored}} |
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.
| //expected-warning@+1 {{unsupported 'aaa' in the 'target' attribute string; 'target' attribute ignored}} | |
| // expected-warning@+1 {{unsupported 'aaa' in the 'target' attribute string; 'target' attribute ignored}} |
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.
Done.
| //expected-warning@+1 {{unsupported 'aaa' in the 'target' attribute string; 'target' attribute ignored}} | ||
| int __attribute__((target("aaa"))) test_feature(void) { return 4; } | ||
|
|
||
| //expected-warning@+1 {{unsupported 'aaa' in the 'target' attribute string; 'target' attribute ignored}} |
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.
| //expected-warning@+1 {{unsupported 'aaa' in the 'target' attribute string; 'target' attribute ignored}} | |
| // expected-warning@+1 {{unsupported 'aaa' in the 'target' attribute string; 'target' attribute ignored}} |
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.
Done.
heiher
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 with nits.
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.
Make the test function name align with the target feature.
| void tuneLa664() {} | |
| void tuneLa464() {} |
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.
Done.
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.
The caller has already performed trim(), so it's unnecessary here, just like starts_with() above doesn't use it either.
| return {AttrFeatureKind::Feature, AttrFeature.trim()}; | |
| return {AttrFeatureKind::Feature, AttrFeature}; |
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.
Done, thanks.
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.
The default return may cause us to miss the check for invalid strings. (like this: "+lasx", here will be two plus signs in the generated IR) . Perhaps we can perform the check inside isValidFeature()?"
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.
Appreciate the review suggestion. The validation will be handled in isValidFeatureName(), with corresponding test cases added.Thanks!
clang/lib/Sema/SemaDeclAttr.cpp
Outdated
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.
According to LoongArchTargetInfo::parseTargetAttr(), this condition may always be false.
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.
My mistake — I didn't notice the !.
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.
Arch -> Feature
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.
Done,thanks.
wangleiat
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 with some minor nits, thanks.
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.
The braces can be omitted.
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.
Done.
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.
Beware unnecessary copies.
auto &F
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.
Done.
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.
Is Invalid unused?
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.
Removed.
This adds support under LoongArch for the target("..") attributes.
The supported formats are:
- "arch=<arch>" strings, that specify the architecture features for a
function as per the -march=arch option.
- "tune=<cpu>" strings, that specify the tune-cpu cpu for a function as
per -mtune.
- "<feature>", "no-<feature>" enabled/disables the specific feature.
Introduce AttrFeatureKind enum to classify target attributes, and implement getAttrFeatureTypeAndValue() helper for centralized parsing.
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/11/builds/16173 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/202/builds/1531 Here is the relevant piece of the build log for the reference |
…41998) Reverts #140700 This breaks bots both in buildbot and downstream CI: - https://lab.llvm.org/buildbot/#/builders/11/builds/16173 - https://lab.llvm.org/buildbot/#/builders/202/builds/1531 - https://ci.chromium.org/ui/p/fuchsia/builders/toolchain.ci/clang-host-linux-x64/b8713537585914796017/overview
…nction" (#141998) Reverts llvm/llvm-project#140700 This breaks bots both in buildbot and downstream CI: - https://lab.llvm.org/buildbot/#/builders/11/builds/16173 - https://lab.llvm.org/buildbot/#/builders/202/builds/1531 - https://ci.chromium.org/ui/p/fuchsia/builders/toolchain.ci/clang-host-linux-x64/b8713537585914796017/overview
This adds support under LoongArch for the target("..") attributes.
The supported formats are:
- "arch=<arch>" strings, that specify the architecture features for a
function as per the -march=arch option.
- "tune=<cpu>" strings, that specify the tune-cpu cpu for a function as
per -mtune.
- "<feature>", "no-<feature>" enabled/disables the specific feature.
…41998) Reverts #140700 This breaks bots both in buildbot and downstream CI: - https://lab.llvm.org/buildbot/#/builders/11/builds/16173 - https://lab.llvm.org/buildbot/#/builders/202/builds/1531 - https://ci.chromium.org/ui/p/fuchsia/builders/toolchain.ci/clang-host-linux-x64/b8713537585914796017/overview
This relands llvm#140700. I have updated the test case('targetattr.c') to resolve the test failure. Original PR resulted in test fail: https://lab.llvm.org/buildbot/#/builders/11/builds/16173 https://lab.llvm.org/buildbot/#/builders/202/builds/1531 Original description: Followup to llvm#140700.
…42546) This relands #140700. I have updated the test case('targetattr.c') to resolve the test failure. Original PR resulted in test fail: https://lab.llvm.org/buildbot/#/builders/11/builds/16173 https://lab.llvm.org/buildbot/#/builders/202/builds/1531 Original description: Followup to #140700.
This adds support under LoongArch for the target("..") attributes.
The supported formats are: