Index: include/llvm/MC/SubtargetFeature.h =================================================================== --- include/llvm/MC/SubtargetFeature.h +++ include/llvm/MC/SubtargetFeature.h @@ -98,14 +98,13 @@ /// Adding Features. void AddFeature(StringRef String, bool Enable = true); - /// ToggleFeature - Toggle a feature and returns the newly updated feature - /// bits. - FeatureBitset ToggleFeature(FeatureBitset Bits, StringRef String, - ArrayRef FeatureTable); - - /// Apply the feature flag and return the newly updated feature bits. - FeatureBitset ApplyFeatureFlag(FeatureBitset Bits, StringRef Feature, - ArrayRef FeatureTable); + /// ToggleFeature - Toggle a feature and update the feature bits. + static void ToggleFeature(FeatureBitset &Bits, StringRef String, + ArrayRef FeatureTable); + + /// Apply the feature flag and update the feature bits. + static void ApplyFeatureFlag(FeatureBitset &Bits, StringRef Feature, + ArrayRef FeatureTable); /// Get feature bits of a CPU. FeatureBitset getFeatureBits(StringRef CPU, Index: lib/MC/MCSubtargetInfo.cpp =================================================================== --- lib/MC/MCSubtargetInfo.cpp +++ lib/MC/MCSubtargetInfo.cpp @@ -63,14 +63,12 @@ /// ToggleFeature - Toggle a feature and returns the re-computed feature /// bits. This version will also change all implied bits. FeatureBitset MCSubtargetInfo::ToggleFeature(StringRef FS) { - SubtargetFeatures Features; - FeatureBits = Features.ToggleFeature(FeatureBits, FS, ProcFeatures); + SubtargetFeatures::ToggleFeature(FeatureBits, FS, ProcFeatures); return FeatureBits; } FeatureBitset MCSubtargetInfo::ApplyFeatureFlag(StringRef FS) { - SubtargetFeatures Features; - FeatureBits = Features.ApplyFeatureFlag(FeatureBits, FS, ProcFeatures); + SubtargetFeatures::ApplyFeatureFlag(FeatureBits, FS, ProcFeatures); return FeatureBits; } Index: lib/MC/SubtargetFeature.cpp =================================================================== --- lib/MC/SubtargetFeature.cpp +++ lib/MC/SubtargetFeature.cpp @@ -162,8 +162,8 @@ /// ToggleFeature - Toggle a feature and returns the newly updated feature /// bits. -FeatureBitset -SubtargetFeatures::ToggleFeature(FeatureBitset Bits, StringRef Feature, +void +SubtargetFeatures::ToggleFeature(FeatureBitset &Bits, StringRef Feature, ArrayRef FeatureTable) { // Find feature in table. @@ -186,12 +186,9 @@ << "' is not a recognized feature for this target" << " (ignoring feature)\n"; } - - return Bits; } -FeatureBitset -SubtargetFeatures::ApplyFeatureFlag(FeatureBitset Bits, StringRef Feature, +void SubtargetFeatures::ApplyFeatureFlag(FeatureBitset &Bits, StringRef Feature, ArrayRef FeatureTable) { assert(hasFlag(Feature)); @@ -203,7 +200,7 @@ if (FeatureEntry) { // Enable/disable feature in bits if (isEnabled(Feature)) { - Bits |= FeatureEntry->Value; + Bits |= FeatureEntry->Value; // For each feature that this implies, set it. SetImpliedBits(Bits, FeatureEntry, FeatureTable); @@ -218,8 +215,6 @@ << "' is not a recognized feature for this target" << " (ignoring feature)\n"; } - - return Bits; } @@ -271,13 +266,28 @@ } } + // Cancel out the disabled features which are explicitly re-enabled later on. + FeatureBitset ExplicitlyEnabled; + for (auto Feature = Features.rbegin(); + Feature != Features.rend(); + ++Feature) { + const SubtargetFeatureKV *FeatureEntry = + Find(StripFlag(*Feature), FeatureTable); + if (FeatureEntry) { + if ((ExplicitlyEnabled & FeatureEntry->Value).any()) + Features.erase(std::next(Feature).base()); + else if (isEnabled(*Feature)) + ExplicitlyEnabled |= FeatureEntry->Value; + } + } + // Iterate through each feature for (auto &Feature : Features) { // Check for help if (Feature == "+help") Help(CPUTable, FeatureTable); - Bits = ApplyFeatureFlag(Bits, Feature, FeatureTable); + ApplyFeatureFlag(Bits, Feature, FeatureTable); } return Bits; Index: test/MC/ARM/fullfp16-neon.s =================================================================== --- test/MC/ARM/fullfp16-neon.s +++ test/MC/ARM/fullfp16-neon.s @@ -1,4 +1,4 @@ -@ RUN: llvm-mc -triple armv8a-none-eabi -mattr=+fullfp16,+neon -show-encoding < %s | FileCheck %s --check-prefix=ARM +@ RUN: llvm-mc -triple armv8a-none-eabi -mattr=+fullfp16,-fp-armv8,+fp-armv8,+neon -show-encoding < %s | FileCheck %s --check-prefix=ARM @ RUN: llvm-mc -triple thumbv8a-none-eabi -mattr=+fullfp16,+neon -show-encoding < %s | FileCheck %s --check-prefix=THUMB vadd.f16 d0, d1, d2