llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Alexandros Lamprineas (labrinea) <details> <summary>Changes</summary> Fixes a crash and cleans up some dead code. namespace Foo { int bar(); __attribute((target_version("default"))) int bar() { return 0; } __attribute((target_version("mops"))) int bar() { return 1; } } $ clang++ --target=aarch64-linux-gnu --rtlib=compiler-rt fmv.cpp None multiversion type isn't valid here UNREACHABLE executed at clang/lib/CodeGen/CodeGenModule.cpp:1840! ... getMangledNameImpl clang::CodeGen::CodeGenModule::getMangledName clang::CodeGen::CodeGenModule::EmitGlobal --- Full diff: https://github.com/llvm/llvm-project/pull/96628.diff 6 Files Affected: - (modified) clang/include/clang/Sema/Sema.h (+1-2) - (modified) clang/lib/Sema/SemaDecl.cpp (+18-27) - (modified) clang/lib/Sema/SemaDeclAttr.cpp (+5-11) - (modified) clang/test/CodeGen/attr-target-version.c (+44-44) - (modified) clang/test/CodeGenCXX/fmv-namespace.cpp (+47-13) - (modified) clang/test/Sema/attr-target-version.c (+3-2) ``````````diff diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 2e7af0f691cbb..31bb81705a742 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -3786,8 +3786,7 @@ class Sema final : public SemaBase { StringRef Name); bool checkTargetAttr(SourceLocation LiteralLoc, StringRef Str); - bool checkTargetVersionAttr(SourceLocation LiteralLoc, Decl *D, - StringRef &Str, bool &isDefault); + bool checkTargetVersionAttr(SourceLocation Loc, Decl *D, StringRef Str); bool checkTargetClonesAttrString( SourceLocation LiteralLoc, StringRef Str, const StringLiteral *Literal, Decl *D, bool &HasDefault, bool &HasCommas, bool &HasNotDefault, diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 029ccf944c513..572c46eed1aaa 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -11465,6 +11465,10 @@ static bool CheckMultiVersionFirstFunction(Sema &S, FunctionDecl *FD) { // otherwise it is treated as a normal function. if (TA && !TA->isDefaultVersion()) return false; + // The target_version attribute only causes Multiversioning if this + // declaration is NOT the default version. + if (TVA && TVA->isDefaultVersion()) + return false; if ((TA || TVA) && CheckMultiVersionValue(S, FD)) { FD->setInvalidDecl(); @@ -11498,11 +11502,9 @@ static void patchDefaultTargetVersion(FunctionDecl *From, FunctionDecl *To) { if (MVKindTo == MultiVersionKind::None && (MVKindFrom == MultiVersionKind::TargetVersion || - MVKindFrom == MultiVersionKind::TargetClones)) { - To->setIsMultiVersion(); + MVKindFrom == MultiVersionKind::TargetClones)) To->addAttr(TargetVersionAttr::CreateImplicit( To->getASTContext(), "default", To->getSourceRange())); - } } static bool CheckTargetCausesMultiVersioning(Sema &S, FunctionDecl *OldFD, @@ -11523,10 +11525,16 @@ static bool CheckTargetCausesMultiVersioning(Sema &S, FunctionDecl *OldFD, const auto *OldTVA = OldFD->getAttr<TargetVersionAttr>(); // If the old decl is NOT MultiVersioned yet, and we don't cause that // to change, this is a simple redeclaration. - if ((NewTA && !NewTA->isDefaultVersion() && - (!OldTA || OldTA->getFeaturesStr() == NewTA->getFeaturesStr())) || - (NewTVA && !NewTVA->isDefaultVersion() && - (!OldTVA || OldTVA->getName() == NewTVA->getName()))) + if (NewTA && !NewTA->isDefaultVersion() && + (!OldTA || OldTA->getFeaturesStr() == NewTA->getFeaturesStr())) + return false; + + // The target_version attribute only causes Multiversioning if this + // declaration is NOT the default version. Moreover, the old declaration + // must be the default version (either explicitly via the attribute, + // or implicitly without it). + if (NewTVA && + (NewTVA->isDefaultVersion() || (OldTVA && !OldTVA->isDefaultVersion()))) return false; // Otherwise, this decl causes MultiVersioning. @@ -11543,8 +11551,7 @@ static bool CheckTargetCausesMultiVersioning(Sema &S, FunctionDecl *OldFD, } // If this is 'default', permit the forward declaration. - if ((NewTA && NewTA->isDefaultVersion() && !OldTA) || - (NewTVA && NewTVA->isDefaultVersion() && !OldTVA)) { + if (NewTA && NewTA->isDefaultVersion() && !OldTA) { Redeclaration = true; OldDecl = OldFD; OldFD->setIsMultiVersion(); @@ -11947,24 +11954,8 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, FunctionDecl *OldFD = OldDecl->getAsFunction(); - if (!OldFD->isMultiVersion() && MVKind == MultiVersionKind::None) { - if (NewTVA || !OldFD->getAttr<TargetVersionAttr>()) - return false; - if (!NewFD->getType()->getAs<FunctionProtoType>()) { - // Multiversion declaration doesn't have prototype. - S.Diag(NewFD->getLocation(), diag::err_multiversion_noproto); - NewFD->setInvalidDecl(); - } else { - // No "target_version" attribute is equivalent to "default" attribute. - NewFD->addAttr(TargetVersionAttr::CreateImplicit( - S.Context, "default", NewFD->getSourceRange())); - NewFD->setIsMultiVersion(); - OldFD->setIsMultiVersion(); - OldDecl = OldFD; - Redeclaration = true; - } - return true; - } + if (!OldFD->isMultiVersion() && MVKind == MultiVersionKind::None) + return false; // Multiversioned redeclarations aren't allowed to omit the attribute, except // for target_clones and target_version. diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index ce6b5b1ff6f93..82e447a79a6b2 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -3029,12 +3029,10 @@ bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) { // Check Target Version attrs bool Sema::checkTargetVersionAttr(SourceLocation LiteralLoc, Decl *D, - StringRef &AttrStr, bool &isDefault) { + StringRef AttrStr) { enum FirstParam { Unsupported }; enum SecondParam { None }; enum ThirdParam { Target, TargetClones, TargetVersion }; - if (AttrStr.trim() == "default") - isDefault = true; llvm::SmallVector<StringRef, 8> Features; AttrStr.split(Features, "+"); for (auto &CurFeature : Features) { @@ -3054,16 +3052,12 @@ bool Sema::checkTargetVersionAttr(SourceLocation LiteralLoc, Decl *D, static void handleTargetVersionAttr(Sema &S, Decl *D, const ParsedAttr &AL) { StringRef Str; SourceLocation LiteralLoc; - bool isDefault = false; if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc) || - S.checkTargetVersionAttr(LiteralLoc, D, Str, isDefault)) + S.checkTargetVersionAttr(LiteralLoc, D, Str)) return; - // Do not create default only target_version attribute - if (!isDefault) { - TargetVersionAttr *NewAttr = - ::new (S.Context) TargetVersionAttr(S.Context, AL, Str); - D->addAttr(NewAttr); - } + TargetVersionAttr *NewAttr = + ::new (S.Context) TargetVersionAttr(S.Context, AL, Str); + D->addAttr(NewAttr); } static void handleTargetAttr(Sema &S, Decl *D, const ParsedAttr &AL) { diff --git a/clang/test/CodeGen/attr-target-version.c b/clang/test/CodeGen/attr-target-version.c index 024aafffca629..4edfc5408fae7 100644 --- a/clang/test/CodeGen/attr-target-version.c +++ b/clang/test/CodeGen/attr-target-version.c @@ -428,13 +428,6 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_default -// CHECK-SAME: () #[[ATTR11]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 111 -// -// -// CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_c._Mssbs // CHECK-SAME: () #[[ATTR11]] { // CHECK-NEXT: entry: @@ -637,22 +630,18 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@recur +// CHECK-LABEL: define {{[^@]+}}@fmv_default // CHECK-SAME: () #[[ATTR11]] { // CHECK-NEXT: entry: -// CHECK-NEXT: call void @reca() -// CHECK-NEXT: ret void +// CHECK-NEXT: ret i32 111 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@main +// CHECK-LABEL: define {{[^@]+}}@recur // CHECK-SAME: () #[[ATTR11]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 -// CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4 -// CHECK-NEXT: call void @recur() -// CHECK-NEXT: [[CALL:%.*]] = call i32 @goo() -// CHECK-NEXT: ret i32 [[CALL]] +// CHECK-NEXT: call void @reca() +// CHECK-NEXT: ret void // // // CHECK: Function Attrs: noinline nounwind optnone @@ -818,6 +807,17 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // // // CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@main +// CHECK-SAME: () #[[ATTR11]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK-NEXT: call void @recur() +// CHECK-NEXT: [[CALL:%.*]] = call i32 @goo() +// CHECK-NEXT: ret i32 [[CALL]] +// +// +// CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mf64mmMpmullMsha1 // CHECK-SAME: () #[[ATTR22:[0-9]+]] { // CHECK-NEXT: entry: @@ -1020,20 +1020,6 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // // // CHECK-NOFMV: Function Attrs: noinline nounwind optnone -// CHECK-NOFMV-LABEL: define {{[^@]+}}@fmv_default -// CHECK-NOFMV-SAME: () #[[ATTR0]] { -// CHECK-NOFMV-NEXT: entry: -// CHECK-NOFMV-NEXT: ret i32 111 -// -// -// CHECK-NOFMV: Function Attrs: noinline nounwind optnone -// CHECK-NOFMV-LABEL: define {{[^@]+}}@fmv_c -// CHECK-NOFMV-SAME: () #[[ATTR0]] { -// CHECK-NOFMV-NEXT: entry: -// CHECK-NOFMV-NEXT: ret void -// -// -// CHECK-NOFMV: Function Attrs: noinline nounwind optnone // CHECK-NOFMV-LABEL: define {{[^@]+}}@goo // CHECK-NOFMV-SAME: () #[[ATTR0]] { // CHECK-NOFMV-NEXT: entry: @@ -1053,22 +1039,25 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // // // CHECK-NOFMV: Function Attrs: noinline nounwind optnone -// CHECK-NOFMV-LABEL: define {{[^@]+}}@recur +// CHECK-NOFMV-LABEL: define {{[^@]+}}@fmv_c // CHECK-NOFMV-SAME: () #[[ATTR0]] { // CHECK-NOFMV-NEXT: entry: -// CHECK-NOFMV-NEXT: call void @reca() // CHECK-NOFMV-NEXT: ret void // // // CHECK-NOFMV: Function Attrs: noinline nounwind optnone -// CHECK-NOFMV-LABEL: define {{[^@]+}}@main +// CHECK-NOFMV-LABEL: define {{[^@]+}}@fmv_default // CHECK-NOFMV-SAME: () #[[ATTR0]] { // CHECK-NOFMV-NEXT: entry: -// CHECK-NOFMV-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 -// CHECK-NOFMV-NEXT: store i32 0, ptr [[RETVAL]], align 4 -// CHECK-NOFMV-NEXT: call void @recur() -// CHECK-NOFMV-NEXT: [[CALL:%.*]] = call i32 @goo() -// CHECK-NOFMV-NEXT: ret i32 [[CALL]] +// CHECK-NOFMV-NEXT: ret i32 111 +// +// +// CHECK-NOFMV: Function Attrs: noinline nounwind optnone +// CHECK-NOFMV-LABEL: define {{[^@]+}}@recur +// CHECK-NOFMV-SAME: () #[[ATTR0]] { +// CHECK-NOFMV-NEXT: entry: +// CHECK-NOFMV-NEXT: call void @reca() +// CHECK-NOFMV-NEXT: ret void // // // CHECK-NOFMV: Function Attrs: noinline nounwind optnone @@ -1089,31 +1078,42 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // // // CHECK-NOFMV: Function Attrs: noinline nounwind optnone -// CHECK-NOFMV-LABEL: define {{[^@]+}}@unused_with_default_def +// CHECK-NOFMV-LABEL: define {{[^@]+}}@unused_with_implicit_default_def // CHECK-NOFMV-SAME: () #[[ATTR0]] { // CHECK-NOFMV-NEXT: entry: // CHECK-NOFMV-NEXT: ret i32 1 // // // CHECK-NOFMV: Function Attrs: noinline nounwind optnone -// CHECK-NOFMV-LABEL: define {{[^@]+}}@unused_with_implicit_default_def +// CHECK-NOFMV-LABEL: define {{[^@]+}}@unused_with_implicit_forward_default_def // CHECK-NOFMV-SAME: () #[[ATTR0]] { // CHECK-NOFMV-NEXT: entry: -// CHECK-NOFMV-NEXT: ret i32 1 +// CHECK-NOFMV-NEXT: ret i32 0 // // // CHECK-NOFMV: Function Attrs: noinline nounwind optnone -// CHECK-NOFMV-LABEL: define {{[^@]+}}@unused_with_implicit_forward_default_def +// CHECK-NOFMV-LABEL: define {{[^@]+}}@default_def_with_version_decls // CHECK-NOFMV-SAME: () #[[ATTR0]] { // CHECK-NOFMV-NEXT: entry: // CHECK-NOFMV-NEXT: ret i32 0 // // // CHECK-NOFMV: Function Attrs: noinline nounwind optnone -// CHECK-NOFMV-LABEL: define {{[^@]+}}@default_def_with_version_decls +// CHECK-NOFMV-LABEL: define {{[^@]+}}@main // CHECK-NOFMV-SAME: () #[[ATTR0]] { // CHECK-NOFMV-NEXT: entry: -// CHECK-NOFMV-NEXT: ret i32 0 +// CHECK-NOFMV-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK-NOFMV-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK-NOFMV-NEXT: call void @recur() +// CHECK-NOFMV-NEXT: [[CALL:%.*]] = call i32 @goo() +// CHECK-NOFMV-NEXT: ret i32 [[CALL]] +// +// +// CHECK-NOFMV: Function Attrs: noinline nounwind optnone +// CHECK-NOFMV-LABEL: define {{[^@]+}}@unused_with_default_def +// CHECK-NOFMV-SAME: () #[[ATTR0]] { +// CHECK-NOFMV-NEXT: entry: +// CHECK-NOFMV-NEXT: ret i32 1 // //. // CHECK: attributes #[[ATTR0]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+flagm,+fp-armv8,+fp16fml,+fullfp16,+neon,+rand,-v9.5a" } diff --git a/clang/test/CodeGenCXX/fmv-namespace.cpp b/clang/test/CodeGenCXX/fmv-namespace.cpp index 193f01db4c5d3..abfff1a74f86a 100644 --- a/clang/test/CodeGenCXX/fmv-namespace.cpp +++ b/clang/test/CodeGenCXX/fmv-namespace.cpp @@ -17,25 +17,26 @@ int __attribute((target_version("sve"))) foo() { return 2; } int baz() { return OtherName::foo(); } +namespace Foo { +int bar(); +__attribute((target_version("default"))) int bar() { return 0; } +__attribute((target_version("mops"))) int bar() { return 1; } +} + //. // CHECK: @__aarch64_cpu_features = external dso_local global { i64 } // CHECK: @_ZN4Name3fooEv = weak_odr ifunc i32 (), ptr @_ZN4Name3fooEv.resolver // CHECK: @_ZN9OtherName3fooEv = weak_odr ifunc i32 (), ptr @_ZN9OtherName3fooEv.resolver +// CHECK: @_ZN3Foo3barEv = weak_odr ifunc i32 (), ptr @_ZN3Foo3barEv.resolver //. -// CHECK-LABEL: define dso_local noundef i32 @_ZN4Name3fooEv.default( -// CHECK-SAME: ) #[[ATTR0:[0-9]+]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: ret i32 0 -// -// // CHECK-LABEL: define dso_local noundef i32 @_ZN4Name3fooEv._Msve( -// CHECK-SAME: ) #[[ATTR1:[0-9]+]] { +// CHECK-SAME: ) #[[ATTR0:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: ret i32 1 // // // CHECK-LABEL: define dso_local noundef i32 @_Z3barv( -// CHECK-SAME: ) #[[ATTR0]] { +// CHECK-SAME: ) #[[ATTR1:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[CALL:%.*]] = call noundef i32 @_ZN4Name3fooEv() // CHECK-NEXT: ret i32 [[CALL]] @@ -56,13 +57,13 @@ int baz() { return OtherName::foo(); } // // // CHECK-LABEL: define dso_local noundef i32 @_ZN9OtherName3fooEv._Msve( -// CHECK-SAME: ) #[[ATTR1]] { +// CHECK-SAME: ) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: ret i32 2 // // // CHECK-LABEL: define dso_local noundef i32 @_Z3bazv( -// CHECK-SAME: ) #[[ATTR0]] { +// CHECK-SAME: ) #[[ATTR1]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[CALL:%.*]] = call noundef i32 @_ZN9OtherName3fooEv() // CHECK-NEXT: ret i32 [[CALL]] @@ -81,10 +82,43 @@ int baz() { return OtherName::foo(); } // CHECK: [[RESOLVER_ELSE]]: // CHECK-NEXT: ret ptr @_ZN9OtherName3fooEv.default // +// +// CHECK-LABEL: define dso_local noundef i32 @_ZN3Foo3barEv.default( +// CHECK-SAME: ) #[[ATTR1]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret i32 0 +// +// +// CHECK-LABEL: define dso_local noundef i32 @_ZN3Foo3barEv._Mmops( +// CHECK-SAME: ) #[[ATTR2:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret i32 1 +// +// +// CHECK-LABEL: define dso_local noundef i32 @_ZN4Name3fooEv.default( +// CHECK-SAME: ) #[[ATTR1]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret i32 0 +// +// +// CHECK-LABEL: define weak_odr ptr @_ZN3Foo3barEv.resolver() comdat { +// CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 576460752303423488 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 576460752303423488 +// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label %[[RESOLVER_ELSE:.*]] +// CHECK: [[RESOLVER_RETURN]]: +// CHECK-NEXT: ret ptr @_ZN3Foo3barEv._Mmops +// CHECK: [[RESOLVER_ELSE]]: +// CHECK-NEXT: ret ptr @_ZN3Foo3barEv.default +// //. -// CHECK: attributes #[[ATTR0]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" } -// CHECK: attributes #[[ATTR1]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve" } -// CHECK: attributes #[[ATTR2:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +// CHECK: attributes #[[ATTR0]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve" } +// CHECK: attributes #[[ATTR1]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +// CHECK: attributes #[[ATTR2]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+mops" } +// CHECK: attributes #[[ATTR3:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" } //. // CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} // CHECK: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"} diff --git a/clang/test/Sema/attr-target-version.c b/clang/test/Sema/attr-target-version.c index cd5be459456eb..8de3eeeaff8f5 100644 --- a/clang/test/Sema/attr-target-version.c +++ b/clang/test/Sema/attr-target-version.c @@ -102,8 +102,9 @@ int __attribute__((target_version("sha2"))) combine(void) { return 1; } // expected-error@+1 {{multiversioned function declaration has a different calling convention}} int __attribute__((aarch64_vector_pcs, target_version("sha3"))) combine(void) { return 2; } -int __attribute__((target_version("fp+aes+pmull+rcpc"))) unspec_args() { return -1; } +int unspec_args(); // expected-error@-1 {{multiversioned function must have a prototype}} -// expected-error@+1 {{multiversioned function must have a prototype}} +// expected-note@+1 {{function multiversioning caused by this declaration}} +int __attribute__((target_version("fp"))) unspec_args() { return -1; } int __attribute__((target_version("default"))) unspec_args() { return 0; } int cargs() { return unspec_args(); } `````````` </details> https://github.com/llvm/llvm-project/pull/96628 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits