diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -6214,12 +6214,11 @@ if (Extension.Features.none()) report_fatal_error("unsupported architectural extension: " + Name); - FeatureBitset ToggleFeatures = EnableFeature - ? (~Features & Extension.Features) - : ( Features & Extension.Features); - FeatureBitset Features = - ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures)); - setAvailableFeatures(Features); + FeatureBitset ToggleFeatures = + EnableFeature + ? STI.SetFeatureBitsTransitively(~Features & Extension.Features) + : STI.ToggleFeature(Features & Extension.Features); + setAvailableFeatures(ComputeAvailableFeatures(ToggleFeatures)); break; } } @@ -6252,12 +6251,11 @@ if (Extension.Features.none()) return Error(ExtLoc, "unsupported architectural extension: " + Name); - FeatureBitset ToggleFeatures = EnableFeature - ? (~Features & Extension.Features) - : (Features & Extension.Features); - FeatureBitset Features = - ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures)); - setAvailableFeatures(Features); + FeatureBitset ToggleFeatures = + EnableFeature + ? STI.SetFeatureBitsTransitively(~Features & Extension.Features) + : STI.ToggleFeature(Features & Extension.Features); + setAvailableFeatures(ComputeAvailableFeatures(ToggleFeatures)); return false; } @@ -6297,7 +6295,6 @@ ExpandCryptoAEK(llvm::AArch64::getCPUArchKind(CPU), RequestedExtensions); - FeatureBitset Features = STI.getFeatureBits(); for (auto Name : RequestedExtensions) { // Advance source location past '+'. CurLoc = incrementLoc(CurLoc, 1); @@ -6317,12 +6314,12 @@ if (Extension.Features.none()) report_fatal_error("unsupported architectural extension: " + Name); - FeatureBitset ToggleFeatures = EnableFeature - ? (~Features & Extension.Features) - : ( Features & Extension.Features); - FeatureBitset Features = - ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures)); - setAvailableFeatures(Features); + FeatureBitset Features = STI.getFeatureBits(); + FeatureBitset ToggleFeatures = + EnableFeature + ? STI.SetFeatureBitsTransitively(~Features & Extension.Features) + : STI.ToggleFeature(Features & Extension.Features); + setAvailableFeatures(ComputeAvailableFeatures(ToggleFeatures)); FoundExtension = true; break; diff --git a/llvm/test/MC/AArch64/SVE/directive-arch.s b/llvm/test/MC/AArch64/SVE/directive-arch.s --- a/llvm/test/MC/AArch64/SVE/directive-arch.s +++ b/llvm/test/MC/AArch64/SVE/directive-arch.s @@ -4,3 +4,9 @@ ptrue p0.b, pow2 // CHECK: ptrue p0.b, pow2 + +// Test that the implied +sve feature is also set from +sve2. +.arch armv8-a+sve2 + +ptrue p0.b, pow2 +// CHECK: ptrue p0.b, pow2 diff --git a/llvm/test/MC/AArch64/SVE/directive-arch_extension.s b/llvm/test/MC/AArch64/SVE/directive-arch_extension.s --- a/llvm/test/MC/AArch64/SVE/directive-arch_extension.s +++ b/llvm/test/MC/AArch64/SVE/directive-arch_extension.s @@ -4,3 +4,15 @@ ptrue p0.b, pow2 // CHECK: ptrue p0.b, pow2 + +// Test that the implied +sve feature is also set from +sve2. +.arch_extension nosve +.arch_extension sve2 +ptrue p0.b, pow2 +// CHECK: ptrue p0.b, pow2 + +// Check that setting +nosve2 does not imply +nosve +.arch_extension nosve2 + +ptrue p0.b, pow2 +// CHECK: ptrue p0.b, pow2 diff --git a/llvm/test/MC/AArch64/SVE/directive-cpu-negative.s b/llvm/test/MC/AArch64/SVE/directive-cpu-negative.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/SVE/directive-cpu-negative.s @@ -0,0 +1,6 @@ +// RUN: not llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s + +.cpu generic+sve+nosve +ptrue p0.b, pow2 +// CHECK: error: instruction requires: sve or sme +// CHECK-NEXT: ptrue p0.b, pow2 diff --git a/llvm/test/MC/AArch64/SVE/directive-cpu.s b/llvm/test/MC/AArch64/SVE/directive-cpu.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/SVE/directive-cpu.s @@ -0,0 +1,15 @@ +// RUN: llvm-mc -triple=aarch64 < %s | FileCheck %s + +.cpu generic+sve +ptrue p0.b, pow2 +// CHECK: ptrue p0.b, pow2 + +// Test that the implied +sve feature is also set from +sve2. +.cpu generic+sve2 +ptrue p0.b, pow2 +// CHECK: ptrue p0.b, pow2 + +// Check that setting +nosve2 does not imply +nosve +.cpu generic+sve2+nosve2 +ptrue p0.b, pow2 +// CHECK: ptrue p0.b, pow2