diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index a2cdfda3842b0..c070462bc5d1f 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -744,7 +744,10 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const { else // Pushing the original feature string to give a sema error later on // when they get checked. - Features.push_back(Feature.str()); + if (Feature.startswith("no")) + Features.push_back("-" + Feature.drop_front(2).str()); + else + Features.push_back("+" + Feature.str()); } }; @@ -792,13 +795,25 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const { Ret.Duplicate = "tune="; else Ret.Tune = Feature.split("=").second.trim(); - } else if (Feature.startswith("no-")) - Ret.Features.push_back("-" + Feature.split("-").second.str()); - else if (Feature.startswith("+")) { + } else if (Feature.startswith("+")) { SplitAndAddFeatures(Feature, Ret.Features); + } else if (Feature.startswith("no-")) { + StringRef FeatureName = + llvm::AArch64::getArchExtFeature(Feature.split("-").second); + if (!FeatureName.empty()) + Ret.Features.push_back("-" + FeatureName.drop_front(1).str()); + else + Ret.Features.push_back("-" + Feature.split("-").second.str()); + } else { + // Try parsing the string to the internal target feature name. If it is + // invalid, add the original string (which could already be an internal + // name). These should be checked later by isValidFeatureName. + StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature); + if (!FeatureName.empty()) + Ret.Features.push_back(FeatureName.str()); + else + Ret.Features.push_back("+" + Feature.str()); } - else - Ret.Features.push_back("+" + Feature.str()); } return Ret; } diff --git a/clang/test/CodeGen/aarch64-targetattr.c b/clang/test/CodeGen/aarch64-targetattr.c index 0f1f7da54625e..bac132f7ef342 100644 --- a/clang/test/CodeGen/aarch64-targetattr.c +++ b/clang/test/CodeGen/aarch64-targetattr.c @@ -75,6 +75,20 @@ void all() {} __attribute__((target("cpu=neoverse-n1,tune=cortex-a710,arch=armv8.6-a+sve2,branch-protection=standard"))) void allplusbranchprotection() {} +// These tests check that the user facing and internal llvm name are both accepted. +// CHECK-LABEL: @plusnoneon() #18 +__attribute__((target("+noneon"))) +void plusnoneon() {} +// CHECK-LABEL: @plusnosimd() #18 +__attribute__((target("+nosimd"))) +void plusnosimd() {} +// CHECK-LABEL: @noneon() #18 +__attribute__((target("no-neon"))) +void noneon() {} +// CHECK-LABEL: @nosimd() #18 +__attribute__((target("no-simd"))) +void nosimd() {} + // CHECK: attributes #0 = { {{.*}} "target-features"="+v8.1a,+v8.2a,+v8a" } // CHECK: attributes #1 = { {{.*}} "target-features"="+sve,+v8.1a,+v8.2a,+v8a" } // CHECK: attributes #2 = { {{.*}} "target-features"="+sve2,+v8.1a,+v8.2a,+v8a" } @@ -92,3 +106,4 @@ void allplusbranchprotection() {} // CHECK: attributes #15 = { {{.*}} "target-features"="+fullfp16" } // CHECK: attributes #16 = { {{.*}} "target-cpu"="neoverse-n1" "target-features"="+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+spe,+ssbs,+sve2,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8.6a,+v8a" "tune-cpu"="cortex-a710" } // CHECK: attributes #17 = { {{.*}} "branch-target-enforcement"="true" {{.*}} "target-cpu"="neoverse-n1" "target-features"="+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+spe,+ssbs,+sve2,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8.6a,+v8a" "tune-cpu"="cortex-a710" } +// CHECK: attributes #18 = { {{.*}} "target-features"="-neon" } diff --git a/clang/test/Sema/aarch64-fp16-target.c b/clang/test/Sema/aarch64-fp16-target.c index 9a921e96e88e5..9d84cca84482f 100644 --- a/clang/test/Sema/aarch64-fp16-target.c +++ b/clang/test/Sema/aarch64-fp16-target.c @@ -10,13 +10,18 @@ void test_fullfp16(float16_t f16) { vabdh_f16(f16, f16); } +__attribute__((target("fp16"))) +void fp16(float16_t f16) { + vabdh_f16(f16, f16); +} + __attribute__((target("arch=armv8-a+fp16"))) void test_fp16_arch(float16_t f16) { vabdh_f16(f16, f16); } __attribute__((target("+fp16"))) -void test_fp16(float16_t f16) { +void test_plusfp16(float16_t f16) { vabdh_f16(f16, f16); }