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; } @@ -6317,12 +6315,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)); 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-negative.s b/llvm/test/MC/AArch64/SVE/directive-arch_extension-negative.s --- a/llvm/test/MC/AArch64/SVE/directive-arch_extension-negative.s +++ b/llvm/test/MC/AArch64/SVE/directive-arch_extension-negative.s @@ -5,3 +5,9 @@ ptrue p0.b, pow2 // CHECK: error: instruction requires: sve or sme // CHECK-NEXT: 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-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,9 @@ ptrue p0.b, pow2 // CHECK: ptrue p0.b, pow2 + +// Test that the implied +sve feature is also set from +sve2. +.arch_extension sve2 + +ptrue p0.b, pow2 +// CHECK: ptrue p0.b, pow2 diff --git a/llvm/test/MC/AArch64/SVE/directive-arch_extension-negative.s b/llvm/test/MC/AArch64/SVE/directive-cpu-negative.s copy from llvm/test/MC/AArch64/SVE/directive-arch_extension-negative.s copy to llvm/test/MC/AArch64/SVE/directive-cpu-negative.s --- a/llvm/test/MC/AArch64/SVE/directive-arch_extension-negative.s +++ b/llvm/test/MC/AArch64/SVE/directive-cpu-negative.s @@ -1,7 +1,13 @@ // RUN: not llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s -.arch_extension nosve +.cpu generic+nosve ptrue p0.b, pow2 // CHECK: error: instruction requires: sve or sme // CHECK-NEXT: ptrue p0.b, pow2 + +// Check that setting +nosve2 does not imply +nosve +.cpu generic+sve+nosve2 + +ptrue p0.b, pow2 +// CHECK: 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,12 @@ +// 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