-
Notifications
You must be signed in to change notification settings - Fork 14.3k
Recommit "[RISCV][FMV] Support target_version" (#111096)" #111333
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-risc-v @llvm/pr-subscribers-clang-codegen Author: Piyou Chen (BeMg) ChangesFix the buildbot failure caused by heap use-after-free error. Origin message:
Patch is 57.55 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/111333.diff 8 Files Affected:
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index a81429ad6a2380..034fbbe0bc7829 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -14325,9 +14325,17 @@ void ASTContext::getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,
Target->initFeatureMap(FeatureMap, getDiagnostics(), TargetCPU, Features);
}
} else if (const auto *TV = FD->getAttr<TargetVersionAttr>()) {
- llvm::SmallVector<StringRef, 8> Feats;
- TV->getFeatures(Feats);
- std::vector<std::string> Features = getFMVBackendFeaturesFor(Feats);
+ std::vector<std::string> Features;
+ if (Target->getTriple().isRISCV()) {
+ ParsedTargetAttr ParsedAttr = Target->parseTargetAttr(TV->getName());
+ Features.insert(Features.begin(), ParsedAttr.Features.begin(),
+ ParsedAttr.Features.end());
+ } else {
+ assert(Target->getTriple().isAArch64());
+ llvm::SmallVector<StringRef, 8> Feats;
+ TV->getFeatures(Feats);
+ Features = getFMVBackendFeaturesFor(Feats);
+ }
Features.insert(Features.begin(),
Target->getTargetOpts().FeaturesAsWritten.begin(),
Target->getTargetOpts().FeaturesAsWritten.end());
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 25c1c496a4f27f..5ba098144a74e7 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -4287,8 +4287,13 @@ void CodeGenModule::emitMultiVersionFunctions() {
} else if (const auto *TVA = CurFD->getAttr<TargetVersionAttr>()) {
if (TVA->isDefaultVersion() && IsDefined)
ShouldEmitResolver = true;
- TVA->getFeatures(Feats);
llvm::Function *Func = createFunction(CurFD);
+ if (getTarget().getTriple().isRISCV()) {
+ Feats.push_back(TVA->getName());
+ } else {
+ assert(getTarget().getTriple().isAArch64());
+ TVA->getFeatures(Feats);
+ }
Options.emplace_back(Func, /*Architecture*/ "", Feats);
} else if (const auto *TC = CurFD->getAttr<TargetClonesAttr>()) {
if (IsDefined)
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 2bf610746bc317..5c4e0562152c5b 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -10329,7 +10329,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// Handle attributes.
ProcessDeclAttributes(S, NewFD, D);
const auto *NewTVA = NewFD->getAttr<TargetVersionAttr>();
- if (NewTVA && !NewTVA->isDefaultVersion() &&
+ if (Context.getTargetInfo().getTriple().isAArch64() && NewTVA &&
+ !NewTVA->isDefaultVersion() &&
!Context.getTargetInfo().hasFeature("fmv")) {
// Don't add to scope fmv functions declarations if fmv disabled
AddToScope = false;
@@ -11038,7 +11039,16 @@ static bool CheckMultiVersionValue(Sema &S, const FunctionDecl *FD) {
if (TVA) {
llvm::SmallVector<StringRef, 8> Feats;
- TVA->getFeatures(Feats);
+ ParsedTargetAttr ParseInfo;
+ if (S.getASTContext().getTargetInfo().getTriple().isRISCV()) {
+ ParseInfo =
+ S.getASTContext().getTargetInfo().parseTargetAttr(TVA->getName());
+ for (auto &Feat : ParseInfo.Features)
+ Feats.push_back(StringRef{Feat}.substr(1));
+ } else {
+ assert(S.getASTContext().getTargetInfo().getTriple().isAArch64());
+ TVA->getFeatures(Feats);
+ }
for (const auto &Feat : Feats) {
if (!TargetInfo.validateCpuSupports(Feat)) {
S.Diag(FD->getLocation(), diag::err_bad_multiversion_option)
@@ -11324,7 +11334,8 @@ static bool PreviousDeclsHaveMultiVersionAttribute(const FunctionDecl *FD) {
}
static void patchDefaultTargetVersion(FunctionDecl *From, FunctionDecl *To) {
- if (!From->getASTContext().getTargetInfo().getTriple().isAArch64())
+ if (!From->getASTContext().getTargetInfo().getTriple().isAArch64() &&
+ !From->getASTContext().getTargetInfo().getTriple().isRISCV())
return;
MultiVersionKind MVKindFrom = From->getMultiVersionKind();
@@ -15511,7 +15522,8 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
FD->setInvalidDecl();
}
if (const auto *Attr = FD->getAttr<TargetVersionAttr>()) {
- if (!Context.getTargetInfo().hasFeature("fmv") &&
+ if (Context.getTargetInfo().getTriple().isAArch64() &&
+ !Context.getTargetInfo().hasFeature("fmv") &&
!Attr->isDefaultVersion()) {
// If function multi versioning disabled skip parsing function body
// defined with non-default target_version attribute
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index c9b9f3a0007daa..af983349a89b58 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -3040,6 +3040,54 @@ bool Sema::checkTargetVersionAttr(SourceLocation LiteralLoc, Decl *D,
enum SecondParam { None };
enum ThirdParam { Target, TargetClones, TargetVersion };
llvm::SmallVector<StringRef, 8> Features;
+ if (Context.getTargetInfo().getTriple().isRISCV()) {
+ llvm::SmallVector<StringRef, 8> AttrStrs;
+ AttrStr.split(AttrStrs, ';');
+
+ bool HasArch = false;
+ bool HasPriority = false;
+ bool HasDefault = false;
+ bool DuplicateAttr = false;
+ for (auto &AttrStr : AttrStrs) {
+ // Only support arch=+ext,... syntax.
+ if (AttrStr.starts_with("arch=+")) {
+ if (HasArch)
+ DuplicateAttr = true;
+ HasArch = true;
+ ParsedTargetAttr TargetAttr =
+ Context.getTargetInfo().parseTargetAttr(AttrStr);
+
+ if (TargetAttr.Features.empty() ||
+ llvm::any_of(TargetAttr.Features, [&](const StringRef Ext) {
+ return !RISCV().isValidFMVExtension(Ext);
+ }))
+ return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
+ << Unsupported << None << AttrStr << TargetVersion;
+ } else if (AttrStr.starts_with("default")) {
+ if (HasDefault)
+ DuplicateAttr = true;
+ HasDefault = true;
+ } else if (AttrStr.consume_front("priority=")) {
+ if (HasPriority)
+ DuplicateAttr = true;
+ HasPriority = true;
+ int Digit;
+ if (AttrStr.getAsInteger(0, Digit))
+ return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
+ << Unsupported << None << AttrStr << TargetVersion;
+ } else {
+ return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
+ << Unsupported << None << AttrStr << TargetVersion;
+ }
+ }
+
+ if (((HasPriority || HasArch) && HasDefault) || DuplicateAttr ||
+ (HasPriority && !HasArch))
+ return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
+ << Unsupported << None << AttrStr << TargetVersion;
+
+ return false;
+ }
AttrStr.split(Features, "+");
for (auto &CurFeature : Features) {
CurFeature = CurFeature.trim();
diff --git a/clang/test/CodeGen/attr-target-version-riscv-invalid.c b/clang/test/CodeGen/attr-target-version-riscv-invalid.c
new file mode 100644
index 00000000000000..0948b3bfd9ef32
--- /dev/null
+++ b/clang/test/CodeGen/attr-target-version-riscv-invalid.c
@@ -0,0 +1,13 @@
+// RUN: not %clang_cc1 -triple riscv64 -target-feature +i -emit-llvm -o - %s 2>&1 | FileCheck %s --check-prefix=CHECK-UNSUPPORT-OS
+
+// CHECK-UNSUPPORT-OS: error: function multiversioning is currently only supported on Linux
+__attribute__((target_version("default"))) int foo(void) {
+ return 2;
+}
+
+__attribute__((target_version("arch=+c"))) int foo(void) {
+ return 2;
+}
+
+
+int bar() { return foo(); }
diff --git a/clang/test/CodeGen/attr-target-version-riscv.c b/clang/test/CodeGen/attr-target-version-riscv.c
new file mode 100644
index 00000000000000..7d0e61e61542f2
--- /dev/null
+++ b/clang/test/CodeGen/attr-target-version-riscv.c
@@ -0,0 +1,443 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals all --include-generated-funcs --version 4
+// RUN: %clang_cc1 -triple riscv64-linux-gnu -target-feature +i -emit-llvm -o - %s | FileCheck %s
+
+__attribute__((target_version("arch=+v"))) int foo1(void) { return 1; }
+__attribute__((target_version("default"))) int foo1(void) { return 1; }
+
+__attribute__((target_version("arch=+zbb"))) int foo2(void) { return 1; }
+__attribute__((target_version("arch=+m"))) int foo2(void) { return 1; }
+__attribute__((target_version("default"))) int foo2(void) { return 1; }
+
+__attribute__((target_version("arch=+zbb,+c"))) int foo3(void) { return 1; }
+__attribute__((target_version("arch=+m"))) int foo3(void) { return 1; }
+__attribute__((target_version("default"))) int foo3(void) { return 1; }
+
+__attribute__((target_version("arch=+zba"))) int foo4(void) { return 1; }
+__attribute__((target_version("arch=+zbb"))) int foo4(void) { return 1; }
+__attribute__((target_version("arch=+zbb,+zba"))) int foo4(void) { return 1; }
+__attribute__((target_version("default"))) int foo4(void) { return 1; }
+
+__attribute__((target_version("arch=+zba"))) int foo5(void) { return 1; }
+__attribute__((target_version("arch=+zbb,+zba"))) int foo5(void) { return 1; }
+__attribute__((target_version("arch=+zbb"))) int foo5(void) { return 1; }
+__attribute__((target_version("default"))) int foo5(void) { return 1; }
+
+__attribute__((target_version("arch=+zba"))) int foo6(void) { return 1; }
+__attribute__((target_version("arch=+zbb"))) int foo6(void) { return 1; }
+__attribute__((target_version("arch=+zbb,+zba;priority=10"))) int foo6(void) { return 1; }
+__attribute__((target_version("default"))) int foo6(void) { return 1; }
+
+__attribute__((target_version("priority=8;arch=+zba"))) int foo7(void) { return 1; }
+__attribute__((target_version("arch=+zbb;priority=9"))) int foo7(void) { return 1; }
+__attribute__((target_version("arch=+zbb,+zba;priority=10"))) int foo7(void) { return 1; }
+__attribute__((target_version("default"))) int foo7(void) { return 1; }
+
+__attribute__((target_version("priority=-1;arch=+zba"))) int foo8(void) { return 1; }
+__attribute__((target_version("arch=+zbb;priority=-2"))) int foo8(void) { return 1; }
+__attribute__((target_version("arch=+zbb,+zba;priority=3"))) int foo8(void) { return 1; }
+__attribute__((target_version("default"))) int foo8(void) { return 1; }
+
+int bar() { return foo1() + foo2() + foo3() + foo4() + foo5() + foo6() + foo7() + foo8(); }
+//.
+// CHECK: @__riscv_feature_bits = external dso_local global { i32, [2 x i64] }
+// CHECK: @foo1 = weak_odr ifunc i32 (), ptr @foo1.resolver
+// CHECK: @foo2 = weak_odr ifunc i32 (), ptr @foo2.resolver
+// CHECK: @foo3 = weak_odr ifunc i32 (), ptr @foo3.resolver
+// CHECK: @foo4 = weak_odr ifunc i32 (), ptr @foo4.resolver
+// CHECK: @foo5 = weak_odr ifunc i32 (), ptr @foo5.resolver
+// CHECK: @foo6 = weak_odr ifunc i32 (), ptr @foo6.resolver
+// CHECK: @foo7 = weak_odr ifunc i32 (), ptr @foo7.resolver
+// CHECK: @foo8 = weak_odr ifunc i32 (), ptr @foo8.resolver
+//.
+// CHECK-LABEL: define dso_local signext i32 @foo1._v(
+// CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo1.default(
+// CHECK-SAME: ) #[[ATTR1:[0-9]+]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo2._zbb(
+// CHECK-SAME: ) #[[ATTR2:[0-9]+]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo2._m(
+// CHECK-SAME: ) #[[ATTR3:[0-9]+]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo2.default(
+// CHECK-SAME: ) #[[ATTR1]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo3._c_zbb(
+// CHECK-SAME: ) #[[ATTR4:[0-9]+]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo3._m(
+// CHECK-SAME: ) #[[ATTR3]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo3.default(
+// CHECK-SAME: ) #[[ATTR1]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo4._zba(
+// CHECK-SAME: ) #[[ATTR5:[0-9]+]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo4._zbb(
+// CHECK-SAME: ) #[[ATTR2]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo4._zba_zbb(
+// CHECK-SAME: ) #[[ATTR6:[0-9]+]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo4.default(
+// CHECK-SAME: ) #[[ATTR1]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo5._zba(
+// CHECK-SAME: ) #[[ATTR5]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo5._zba_zbb(
+// CHECK-SAME: ) #[[ATTR6]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo5._zbb(
+// CHECK-SAME: ) #[[ATTR2]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo5.default(
+// CHECK-SAME: ) #[[ATTR1]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo6._zba(
+// CHECK-SAME: ) #[[ATTR5]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo6._zbb(
+// CHECK-SAME: ) #[[ATTR2]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo6._zba_zbb(
+// CHECK-SAME: ) #[[ATTR6]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo6.default(
+// CHECK-SAME: ) #[[ATTR1]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo7._zba(
+// CHECK-SAME: ) #[[ATTR5]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo7._zbb(
+// CHECK-SAME: ) #[[ATTR2]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo7._zba_zbb(
+// CHECK-SAME: ) #[[ATTR6]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo7.default(
+// CHECK-SAME: ) #[[ATTR1]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo8._zba(
+// CHECK-SAME: ) #[[ATTR5]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo8._zbb(
+// CHECK-SAME: ) #[[ATTR2]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo8._zba_zbb(
+// CHECK-SAME: ) #[[ATTR6]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo8.default(
+// CHECK-SAME: ) #[[ATTR1]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @bar(
+// CHECK-SAME: ) #[[ATTR1]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[CALL:%.*]] = call signext i32 @foo1()
+// CHECK-NEXT: [[CALL1:%.*]] = call signext i32 @foo2()
+// CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL]], [[CALL1]]
+// CHECK-NEXT: [[CALL2:%.*]] = call signext i32 @foo3()
+// CHECK-NEXT: [[ADD3:%.*]] = add nsw i32 [[ADD]], [[CALL2]]
+// CHECK-NEXT: [[CALL4:%.*]] = call signext i32 @foo4()
+// CHECK-NEXT: [[ADD5:%.*]] = add nsw i32 [[ADD3]], [[CALL4]]
+// CHECK-NEXT: [[CALL6:%.*]] = call signext i32 @foo5()
+// CHECK-NEXT: [[ADD7:%.*]] = add nsw i32 [[ADD5]], [[CALL6]]
+// CHECK-NEXT: [[CALL8:%.*]] = call signext i32 @foo6()
+// CHECK-NEXT: [[ADD9:%.*]] = add nsw i32 [[ADD7]], [[CALL8]]
+// CHECK-NEXT: [[CALL10:%.*]] = call signext i32 @foo7()
+// CHECK-NEXT: [[ADD11:%.*]] = add nsw i32 [[ADD9]], [[CALL10]]
+// CHECK-NEXT: [[CALL12:%.*]] = call signext i32 @foo8()
+// CHECK-NEXT: [[ADD13:%.*]] = add nsw i32 [[ADD11]], [[CALL12]]
+// CHECK-NEXT: ret i32 [[ADD13]]
+//
+//
+// CHECK-LABEL: define weak_odr ptr @foo1.resolver() comdat {
+// CHECK-NEXT: resolver_entry:
+// CHECK-NEXT: call void @__init_riscv_feature_bits(ptr null)
+// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8
+// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 2097152
+// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 2097152
+// CHECK-NEXT: br i1 [[TMP2]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]]
+// CHECK: resolver_return:
+// CHECK-NEXT: ret ptr @foo1._v
+// CHECK: resolver_else:
+// CHECK-NEXT: ret ptr @foo1.default
+//
+//
+// CHECK-LABEL: define weak_odr ptr @foo2.resolver() comdat {
+// CHECK-NEXT: resolver_entry:
+// CHECK-NEXT: call void @__init_riscv_feature_bits(ptr null)
+// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8
+// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 268435456
+// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 268435456
+// CHECK-NEXT: br i1 [[TMP2]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]]
+// CHECK: resolver_return:
+// CHECK-NEXT: ret ptr @foo2._zbb
+// CHECK: resolver_else:
+// CHECK-NEXT: [[TMP3:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8
+// CHECK-NEXT: [[TMP4:%.*]] = and i64 [[TMP3]], 4096
+// CHECK-NEXT: [[TMP5:%.*]] = icmp eq i64 [[TMP4]], 4096
+// CHECK-NEXT: br i1 [[TMP5]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]]
+// CHECK: resolver_return1:
+// CHECK-NEXT: ret ptr @foo2._m
+// CHECK: resolver_else2:
+// CHECK-NEXT: ret ptr @foo2.default
+//
+//
+// CHECK-LABEL: define weak_odr ptr @foo3.resolver() comdat {
+// CHECK-NEXT: resolver_entry:
+// CHECK-NEXT: call void @__init_riscv_feature_bits(ptr null)
+// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8
+// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 268435460
+// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 268435460
+// CHECK-NEXT: br i1 [[TMP2]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]]
+// CHECK: resolver_return:
+// CHECK-NEXT: ret ptr @foo3._c_zbb
+// CHECK: resolver_else:
+// CHECK-NEXT: [[TMP3:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8
+// CHECK-NEXT: [[TMP4:%.*]] = and i64 [[TMP3]], 4096
+// CHECK-NEXT: [[TMP5:%.*]] = icmp eq i64 [[TMP4]], 4096
+// CHECK-NEXT: br i1 [[TMP5]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]]
+// CHECK: resolver_return1:
+// CHECK-NEXT: ret ptr @foo3._m
+// CHECK: resolver_else2:
+// CHECK-NEXT: ret ptr @foo3.default
+//
+//
+// CHECK-LABEL: define weak_odr ptr @foo4.resolver() comdat {
+// CHECK-NEXT: resolver_entry:
+// CHECK-NEXT: call void @__init_riscv_feature_bits(ptr null)
+// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8
+// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 134217728
+// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 134217728
+// CHECK-NEXT: br i1 [[TMP2]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]]
+// CHECK: resolver_return:
+// CHECK-NEXT: ret ptr @foo4._zba
+// CHECK: resolver_else:
+// CHECK-NEXT: [[TMP3:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8
+// CHECK-NEXT: [[TMP4:%.*]] = and i64 [[TMP3]], 268435456
+// CHECK-NEXT: [[TMP5:%.*]] = icmp eq i64 [[TMP4]], 268435456
+// CHECK-NEXT: br i1 [[TMP5]], label [[RES...
[truncated]
|
@llvm/pr-subscribers-clang Author: Piyou Chen (BeMg) ChangesFix the buildbot failure caused by heap use-after-free error. Origin message:
Patch is 57.55 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/111333.diff 8 Files Affected:
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index a81429ad6a2380..034fbbe0bc7829 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -14325,9 +14325,17 @@ void ASTContext::getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,
Target->initFeatureMap(FeatureMap, getDiagnostics(), TargetCPU, Features);
}
} else if (const auto *TV = FD->getAttr<TargetVersionAttr>()) {
- llvm::SmallVector<StringRef, 8> Feats;
- TV->getFeatures(Feats);
- std::vector<std::string> Features = getFMVBackendFeaturesFor(Feats);
+ std::vector<std::string> Features;
+ if (Target->getTriple().isRISCV()) {
+ ParsedTargetAttr ParsedAttr = Target->parseTargetAttr(TV->getName());
+ Features.insert(Features.begin(), ParsedAttr.Features.begin(),
+ ParsedAttr.Features.end());
+ } else {
+ assert(Target->getTriple().isAArch64());
+ llvm::SmallVector<StringRef, 8> Feats;
+ TV->getFeatures(Feats);
+ Features = getFMVBackendFeaturesFor(Feats);
+ }
Features.insert(Features.begin(),
Target->getTargetOpts().FeaturesAsWritten.begin(),
Target->getTargetOpts().FeaturesAsWritten.end());
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 25c1c496a4f27f..5ba098144a74e7 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -4287,8 +4287,13 @@ void CodeGenModule::emitMultiVersionFunctions() {
} else if (const auto *TVA = CurFD->getAttr<TargetVersionAttr>()) {
if (TVA->isDefaultVersion() && IsDefined)
ShouldEmitResolver = true;
- TVA->getFeatures(Feats);
llvm::Function *Func = createFunction(CurFD);
+ if (getTarget().getTriple().isRISCV()) {
+ Feats.push_back(TVA->getName());
+ } else {
+ assert(getTarget().getTriple().isAArch64());
+ TVA->getFeatures(Feats);
+ }
Options.emplace_back(Func, /*Architecture*/ "", Feats);
} else if (const auto *TC = CurFD->getAttr<TargetClonesAttr>()) {
if (IsDefined)
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 2bf610746bc317..5c4e0562152c5b 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -10329,7 +10329,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// Handle attributes.
ProcessDeclAttributes(S, NewFD, D);
const auto *NewTVA = NewFD->getAttr<TargetVersionAttr>();
- if (NewTVA && !NewTVA->isDefaultVersion() &&
+ if (Context.getTargetInfo().getTriple().isAArch64() && NewTVA &&
+ !NewTVA->isDefaultVersion() &&
!Context.getTargetInfo().hasFeature("fmv")) {
// Don't add to scope fmv functions declarations if fmv disabled
AddToScope = false;
@@ -11038,7 +11039,16 @@ static bool CheckMultiVersionValue(Sema &S, const FunctionDecl *FD) {
if (TVA) {
llvm::SmallVector<StringRef, 8> Feats;
- TVA->getFeatures(Feats);
+ ParsedTargetAttr ParseInfo;
+ if (S.getASTContext().getTargetInfo().getTriple().isRISCV()) {
+ ParseInfo =
+ S.getASTContext().getTargetInfo().parseTargetAttr(TVA->getName());
+ for (auto &Feat : ParseInfo.Features)
+ Feats.push_back(StringRef{Feat}.substr(1));
+ } else {
+ assert(S.getASTContext().getTargetInfo().getTriple().isAArch64());
+ TVA->getFeatures(Feats);
+ }
for (const auto &Feat : Feats) {
if (!TargetInfo.validateCpuSupports(Feat)) {
S.Diag(FD->getLocation(), diag::err_bad_multiversion_option)
@@ -11324,7 +11334,8 @@ static bool PreviousDeclsHaveMultiVersionAttribute(const FunctionDecl *FD) {
}
static void patchDefaultTargetVersion(FunctionDecl *From, FunctionDecl *To) {
- if (!From->getASTContext().getTargetInfo().getTriple().isAArch64())
+ if (!From->getASTContext().getTargetInfo().getTriple().isAArch64() &&
+ !From->getASTContext().getTargetInfo().getTriple().isRISCV())
return;
MultiVersionKind MVKindFrom = From->getMultiVersionKind();
@@ -15511,7 +15522,8 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
FD->setInvalidDecl();
}
if (const auto *Attr = FD->getAttr<TargetVersionAttr>()) {
- if (!Context.getTargetInfo().hasFeature("fmv") &&
+ if (Context.getTargetInfo().getTriple().isAArch64() &&
+ !Context.getTargetInfo().hasFeature("fmv") &&
!Attr->isDefaultVersion()) {
// If function multi versioning disabled skip parsing function body
// defined with non-default target_version attribute
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index c9b9f3a0007daa..af983349a89b58 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -3040,6 +3040,54 @@ bool Sema::checkTargetVersionAttr(SourceLocation LiteralLoc, Decl *D,
enum SecondParam { None };
enum ThirdParam { Target, TargetClones, TargetVersion };
llvm::SmallVector<StringRef, 8> Features;
+ if (Context.getTargetInfo().getTriple().isRISCV()) {
+ llvm::SmallVector<StringRef, 8> AttrStrs;
+ AttrStr.split(AttrStrs, ';');
+
+ bool HasArch = false;
+ bool HasPriority = false;
+ bool HasDefault = false;
+ bool DuplicateAttr = false;
+ for (auto &AttrStr : AttrStrs) {
+ // Only support arch=+ext,... syntax.
+ if (AttrStr.starts_with("arch=+")) {
+ if (HasArch)
+ DuplicateAttr = true;
+ HasArch = true;
+ ParsedTargetAttr TargetAttr =
+ Context.getTargetInfo().parseTargetAttr(AttrStr);
+
+ if (TargetAttr.Features.empty() ||
+ llvm::any_of(TargetAttr.Features, [&](const StringRef Ext) {
+ return !RISCV().isValidFMVExtension(Ext);
+ }))
+ return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
+ << Unsupported << None << AttrStr << TargetVersion;
+ } else if (AttrStr.starts_with("default")) {
+ if (HasDefault)
+ DuplicateAttr = true;
+ HasDefault = true;
+ } else if (AttrStr.consume_front("priority=")) {
+ if (HasPriority)
+ DuplicateAttr = true;
+ HasPriority = true;
+ int Digit;
+ if (AttrStr.getAsInteger(0, Digit))
+ return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
+ << Unsupported << None << AttrStr << TargetVersion;
+ } else {
+ return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
+ << Unsupported << None << AttrStr << TargetVersion;
+ }
+ }
+
+ if (((HasPriority || HasArch) && HasDefault) || DuplicateAttr ||
+ (HasPriority && !HasArch))
+ return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
+ << Unsupported << None << AttrStr << TargetVersion;
+
+ return false;
+ }
AttrStr.split(Features, "+");
for (auto &CurFeature : Features) {
CurFeature = CurFeature.trim();
diff --git a/clang/test/CodeGen/attr-target-version-riscv-invalid.c b/clang/test/CodeGen/attr-target-version-riscv-invalid.c
new file mode 100644
index 00000000000000..0948b3bfd9ef32
--- /dev/null
+++ b/clang/test/CodeGen/attr-target-version-riscv-invalid.c
@@ -0,0 +1,13 @@
+// RUN: not %clang_cc1 -triple riscv64 -target-feature +i -emit-llvm -o - %s 2>&1 | FileCheck %s --check-prefix=CHECK-UNSUPPORT-OS
+
+// CHECK-UNSUPPORT-OS: error: function multiversioning is currently only supported on Linux
+__attribute__((target_version("default"))) int foo(void) {
+ return 2;
+}
+
+__attribute__((target_version("arch=+c"))) int foo(void) {
+ return 2;
+}
+
+
+int bar() { return foo(); }
diff --git a/clang/test/CodeGen/attr-target-version-riscv.c b/clang/test/CodeGen/attr-target-version-riscv.c
new file mode 100644
index 00000000000000..7d0e61e61542f2
--- /dev/null
+++ b/clang/test/CodeGen/attr-target-version-riscv.c
@@ -0,0 +1,443 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals all --include-generated-funcs --version 4
+// RUN: %clang_cc1 -triple riscv64-linux-gnu -target-feature +i -emit-llvm -o - %s | FileCheck %s
+
+__attribute__((target_version("arch=+v"))) int foo1(void) { return 1; }
+__attribute__((target_version("default"))) int foo1(void) { return 1; }
+
+__attribute__((target_version("arch=+zbb"))) int foo2(void) { return 1; }
+__attribute__((target_version("arch=+m"))) int foo2(void) { return 1; }
+__attribute__((target_version("default"))) int foo2(void) { return 1; }
+
+__attribute__((target_version("arch=+zbb,+c"))) int foo3(void) { return 1; }
+__attribute__((target_version("arch=+m"))) int foo3(void) { return 1; }
+__attribute__((target_version("default"))) int foo3(void) { return 1; }
+
+__attribute__((target_version("arch=+zba"))) int foo4(void) { return 1; }
+__attribute__((target_version("arch=+zbb"))) int foo4(void) { return 1; }
+__attribute__((target_version("arch=+zbb,+zba"))) int foo4(void) { return 1; }
+__attribute__((target_version("default"))) int foo4(void) { return 1; }
+
+__attribute__((target_version("arch=+zba"))) int foo5(void) { return 1; }
+__attribute__((target_version("arch=+zbb,+zba"))) int foo5(void) { return 1; }
+__attribute__((target_version("arch=+zbb"))) int foo5(void) { return 1; }
+__attribute__((target_version("default"))) int foo5(void) { return 1; }
+
+__attribute__((target_version("arch=+zba"))) int foo6(void) { return 1; }
+__attribute__((target_version("arch=+zbb"))) int foo6(void) { return 1; }
+__attribute__((target_version("arch=+zbb,+zba;priority=10"))) int foo6(void) { return 1; }
+__attribute__((target_version("default"))) int foo6(void) { return 1; }
+
+__attribute__((target_version("priority=8;arch=+zba"))) int foo7(void) { return 1; }
+__attribute__((target_version("arch=+zbb;priority=9"))) int foo7(void) { return 1; }
+__attribute__((target_version("arch=+zbb,+zba;priority=10"))) int foo7(void) { return 1; }
+__attribute__((target_version("default"))) int foo7(void) { return 1; }
+
+__attribute__((target_version("priority=-1;arch=+zba"))) int foo8(void) { return 1; }
+__attribute__((target_version("arch=+zbb;priority=-2"))) int foo8(void) { return 1; }
+__attribute__((target_version("arch=+zbb,+zba;priority=3"))) int foo8(void) { return 1; }
+__attribute__((target_version("default"))) int foo8(void) { return 1; }
+
+int bar() { return foo1() + foo2() + foo3() + foo4() + foo5() + foo6() + foo7() + foo8(); }
+//.
+// CHECK: @__riscv_feature_bits = external dso_local global { i32, [2 x i64] }
+// CHECK: @foo1 = weak_odr ifunc i32 (), ptr @foo1.resolver
+// CHECK: @foo2 = weak_odr ifunc i32 (), ptr @foo2.resolver
+// CHECK: @foo3 = weak_odr ifunc i32 (), ptr @foo3.resolver
+// CHECK: @foo4 = weak_odr ifunc i32 (), ptr @foo4.resolver
+// CHECK: @foo5 = weak_odr ifunc i32 (), ptr @foo5.resolver
+// CHECK: @foo6 = weak_odr ifunc i32 (), ptr @foo6.resolver
+// CHECK: @foo7 = weak_odr ifunc i32 (), ptr @foo7.resolver
+// CHECK: @foo8 = weak_odr ifunc i32 (), ptr @foo8.resolver
+//.
+// CHECK-LABEL: define dso_local signext i32 @foo1._v(
+// CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo1.default(
+// CHECK-SAME: ) #[[ATTR1:[0-9]+]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo2._zbb(
+// CHECK-SAME: ) #[[ATTR2:[0-9]+]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo2._m(
+// CHECK-SAME: ) #[[ATTR3:[0-9]+]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo2.default(
+// CHECK-SAME: ) #[[ATTR1]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo3._c_zbb(
+// CHECK-SAME: ) #[[ATTR4:[0-9]+]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo3._m(
+// CHECK-SAME: ) #[[ATTR3]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo3.default(
+// CHECK-SAME: ) #[[ATTR1]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo4._zba(
+// CHECK-SAME: ) #[[ATTR5:[0-9]+]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo4._zbb(
+// CHECK-SAME: ) #[[ATTR2]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo4._zba_zbb(
+// CHECK-SAME: ) #[[ATTR6:[0-9]+]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo4.default(
+// CHECK-SAME: ) #[[ATTR1]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo5._zba(
+// CHECK-SAME: ) #[[ATTR5]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo5._zba_zbb(
+// CHECK-SAME: ) #[[ATTR6]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo5._zbb(
+// CHECK-SAME: ) #[[ATTR2]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo5.default(
+// CHECK-SAME: ) #[[ATTR1]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo6._zba(
+// CHECK-SAME: ) #[[ATTR5]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo6._zbb(
+// CHECK-SAME: ) #[[ATTR2]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo6._zba_zbb(
+// CHECK-SAME: ) #[[ATTR6]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo6.default(
+// CHECK-SAME: ) #[[ATTR1]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo7._zba(
+// CHECK-SAME: ) #[[ATTR5]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo7._zbb(
+// CHECK-SAME: ) #[[ATTR2]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo7._zba_zbb(
+// CHECK-SAME: ) #[[ATTR6]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo7.default(
+// CHECK-SAME: ) #[[ATTR1]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo8._zba(
+// CHECK-SAME: ) #[[ATTR5]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo8._zbb(
+// CHECK-SAME: ) #[[ATTR2]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo8._zba_zbb(
+// CHECK-SAME: ) #[[ATTR6]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @foo8.default(
+// CHECK-SAME: ) #[[ATTR1]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: ret i32 1
+//
+//
+// CHECK-LABEL: define dso_local signext i32 @bar(
+// CHECK-SAME: ) #[[ATTR1]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[CALL:%.*]] = call signext i32 @foo1()
+// CHECK-NEXT: [[CALL1:%.*]] = call signext i32 @foo2()
+// CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL]], [[CALL1]]
+// CHECK-NEXT: [[CALL2:%.*]] = call signext i32 @foo3()
+// CHECK-NEXT: [[ADD3:%.*]] = add nsw i32 [[ADD]], [[CALL2]]
+// CHECK-NEXT: [[CALL4:%.*]] = call signext i32 @foo4()
+// CHECK-NEXT: [[ADD5:%.*]] = add nsw i32 [[ADD3]], [[CALL4]]
+// CHECK-NEXT: [[CALL6:%.*]] = call signext i32 @foo5()
+// CHECK-NEXT: [[ADD7:%.*]] = add nsw i32 [[ADD5]], [[CALL6]]
+// CHECK-NEXT: [[CALL8:%.*]] = call signext i32 @foo6()
+// CHECK-NEXT: [[ADD9:%.*]] = add nsw i32 [[ADD7]], [[CALL8]]
+// CHECK-NEXT: [[CALL10:%.*]] = call signext i32 @foo7()
+// CHECK-NEXT: [[ADD11:%.*]] = add nsw i32 [[ADD9]], [[CALL10]]
+// CHECK-NEXT: [[CALL12:%.*]] = call signext i32 @foo8()
+// CHECK-NEXT: [[ADD13:%.*]] = add nsw i32 [[ADD11]], [[CALL12]]
+// CHECK-NEXT: ret i32 [[ADD13]]
+//
+//
+// CHECK-LABEL: define weak_odr ptr @foo1.resolver() comdat {
+// CHECK-NEXT: resolver_entry:
+// CHECK-NEXT: call void @__init_riscv_feature_bits(ptr null)
+// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8
+// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 2097152
+// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 2097152
+// CHECK-NEXT: br i1 [[TMP2]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]]
+// CHECK: resolver_return:
+// CHECK-NEXT: ret ptr @foo1._v
+// CHECK: resolver_else:
+// CHECK-NEXT: ret ptr @foo1.default
+//
+//
+// CHECK-LABEL: define weak_odr ptr @foo2.resolver() comdat {
+// CHECK-NEXT: resolver_entry:
+// CHECK-NEXT: call void @__init_riscv_feature_bits(ptr null)
+// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8
+// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 268435456
+// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 268435456
+// CHECK-NEXT: br i1 [[TMP2]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]]
+// CHECK: resolver_return:
+// CHECK-NEXT: ret ptr @foo2._zbb
+// CHECK: resolver_else:
+// CHECK-NEXT: [[TMP3:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8
+// CHECK-NEXT: [[TMP4:%.*]] = and i64 [[TMP3]], 4096
+// CHECK-NEXT: [[TMP5:%.*]] = icmp eq i64 [[TMP4]], 4096
+// CHECK-NEXT: br i1 [[TMP5]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]]
+// CHECK: resolver_return1:
+// CHECK-NEXT: ret ptr @foo2._m
+// CHECK: resolver_else2:
+// CHECK-NEXT: ret ptr @foo2.default
+//
+//
+// CHECK-LABEL: define weak_odr ptr @foo3.resolver() comdat {
+// CHECK-NEXT: resolver_entry:
+// CHECK-NEXT: call void @__init_riscv_feature_bits(ptr null)
+// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8
+// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 268435460
+// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 268435460
+// CHECK-NEXT: br i1 [[TMP2]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]]
+// CHECK: resolver_return:
+// CHECK-NEXT: ret ptr @foo3._c_zbb
+// CHECK: resolver_else:
+// CHECK-NEXT: [[TMP3:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8
+// CHECK-NEXT: [[TMP4:%.*]] = and i64 [[TMP3]], 4096
+// CHECK-NEXT: [[TMP5:%.*]] = icmp eq i64 [[TMP4]], 4096
+// CHECK-NEXT: br i1 [[TMP5]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]]
+// CHECK: resolver_return1:
+// CHECK-NEXT: ret ptr @foo3._m
+// CHECK: resolver_else2:
+// CHECK-NEXT: ret ptr @foo3.default
+//
+//
+// CHECK-LABEL: define weak_odr ptr @foo4.resolver() comdat {
+// CHECK-NEXT: resolver_entry:
+// CHECK-NEXT: call void @__init_riscv_feature_bits(ptr null)
+// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8
+// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 134217728
+// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 134217728
+// CHECK-NEXT: br i1 [[TMP2]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]]
+// CHECK: resolver_return:
+// CHECK-NEXT: ret ptr @foo4._zba
+// CHECK: resolver_else:
+// CHECK-NEXT: [[TMP3:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8
+// CHECK-NEXT: [[TMP4:%.*]] = and i64 [[TMP3]], 268435456
+// CHECK-NEXT: [[TMP5:%.*]] = icmp eq i64 [[TMP4]], 268435456
+// CHECK-NEXT: br i1 [[TMP5]], label [[RES...
[truncated]
|
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
It looks like this change caused a regression: #115000 |
Fix the buildbot failure caused by heap use-after-free error.
Origin message: