Skip to content

Commit 5a00cb1

Browse files
authored
Revert "[RISCV] Relax march string order constraint" (#79976)
Reverts #78120 Buildbot is broken: llvm/lib/Support/RISCVISAInfo.cpp:910:18: error: call to deleted constructor of 'llvm::Error' return E; ^
1 parent c61686e commit 5a00cb1

File tree

3 files changed

+173
-246
lines changed

3 files changed

+173
-246
lines changed

clang/test/Driver/riscv-arch.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,9 @@
156156
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32L %s
157157
// RV32L: error: invalid arch name 'rv32l'
158158

159-
// RUN: %clang --target=riscv32-unknown-elf -march=rv32imadf -### %s \
160-
// RUN: -fsyntax-only 2>&1 | FileCheck %s
159+
// RUN: not %clang --target=riscv32-unknown-elf -march=rv32imadf -### %s \
160+
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32IMADF %s
161+
// RV32IMADF: error: invalid arch name 'rv32imadf'
161162

162163
// RUN: not %clang --target=riscv32-unknown-elf -march=rv32imm -### %s \
163164
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32IMM %s
@@ -183,8 +184,9 @@
183184
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV64L %s
184185
// RV64L: error: invalid arch name 'rv64l'
185186

186-
// RUN: %clang --target=riscv64-unknown-elf -march=rv64imadf -### %s \
187-
// RUN: -fsyntax-only 2>&1 | FileCheck %s
187+
// RUN: not %clang --target=riscv64-unknown-elf -march=rv64imadf -### %s \
188+
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV64IMADF %s
189+
// RV64IMADF: error: invalid arch name 'rv64imadf'
188190

189191
// RUN: not %clang --target=riscv64-unknown-elf -march=rv64imm -### %s \
190192
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV64IMM %s
@@ -214,7 +216,7 @@
214216
// RUN: not %clang --target=riscv32-unknown-elf -march=rv32imcq -### %s \
215217
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-ORDER %s
216218
// RV32-ORDER: error: invalid arch name 'rv32imcq',
217-
// RV32-ORDER: unsupported standard user-level extension 'q'
219+
// RV32-ORDER: standard user-level extension not given in canonical order 'q'
218220

219221
// RUN: not %clang --target=riscv32-unknown-elf -march=rv32izvl64b -### %s \
220222
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-ZVL64B-ER %s
@@ -316,7 +318,7 @@
316318
// RUN: not %clang --target=riscv32-unknown-elf -march=rv32ixabc_a -### %s \
317319
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-PREFIX %s
318320
// RV32-PREFIX: error: invalid arch name 'rv32ixabc_a',
319-
// RV32-PREFIX: unsupported non-standard user-level extension 'xabc'
321+
// RV32-PREFIX: invalid extension prefix 'a'
320322

321323
// RUN: not %clang --target=riscv32-unknown-elf -march=rv32ixdef_sabc -### %s \
322324
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-X-ORDER %s

llvm/lib/Support/RISCVISAInfo.cpp

Lines changed: 145 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "llvm/Support/RISCVISAInfo.h"
10-
#include "llvm/ADT/MapVector.h"
1110
#include "llvm/ADT/STLExtras.h"
1211
#include "llvm/ADT/SetVector.h"
1312
#include "llvm/ADT/StringExtras.h"
@@ -704,106 +703,6 @@ RISCVISAInfo::parseNormalizedArchString(StringRef Arch) {
704703
return std::move(ISAInfo);
705704
}
706705

707-
static Error splitExtsByUnderscore(StringRef Exts,
708-
std::vector<std::string> &SplitExts) {
709-
SmallVector<StringRef, 8> Split;
710-
if (Exts.empty())
711-
return Error::success();
712-
713-
Exts.split(Split, "_");
714-
715-
for (auto Ext : Split) {
716-
if (Ext.empty())
717-
return createStringError(errc::invalid_argument,
718-
"extension name missing after separator '_'");
719-
720-
SplitExts.push_back(Ext.str());
721-
}
722-
return Error::success();
723-
}
724-
725-
static Error processMultiLetterExtension(
726-
StringRef RawExt,
727-
MapVector<std::string, RISCVISAInfo::ExtensionVersion,
728-
std::map<std::string, unsigned>> &SeenExtMap,
729-
bool IgnoreUnknown, bool EnableExperimentalExtension,
730-
bool ExperimentalExtensionVersionCheck) {
731-
StringRef Type = getExtensionType(RawExt);
732-
StringRef Desc = getExtensionTypeDesc(RawExt);
733-
auto Pos = findLastNonVersionCharacter(RawExt) + 1;
734-
StringRef Name(RawExt.substr(0, Pos));
735-
StringRef Vers(RawExt.substr(Pos));
736-
737-
if (Type.empty()) {
738-
if (IgnoreUnknown)
739-
return Error::success();
740-
return createStringError(errc::invalid_argument,
741-
"invalid extension prefix '" + RawExt + "'");
742-
}
743-
744-
if (!IgnoreUnknown && Name.size() == Type.size())
745-
return createStringError(errc::invalid_argument,
746-
"%s name missing after '%s'", Desc.str().c_str(),
747-
Type.str().c_str());
748-
749-
unsigned Major, Minor, ConsumeLength;
750-
if (auto E = getExtensionVersion(Name, Vers, Major, Minor, ConsumeLength,
751-
EnableExperimentalExtension,
752-
ExperimentalExtensionVersionCheck)) {
753-
if (IgnoreUnknown) {
754-
consumeError(std::move(E));
755-
return Error::success();
756-
}
757-
return E;
758-
}
759-
760-
// Check if duplicated extension.
761-
if (!IgnoreUnknown && SeenExtMap.contains(Name.str()))
762-
return createStringError(errc::invalid_argument, "duplicated %s '%s'",
763-
Desc.str().c_str(), Name.str().c_str());
764-
765-
if (IgnoreUnknown && !RISCVISAInfo::isSupportedExtension(Name))
766-
return Error::success();
767-
768-
SeenExtMap[Name.str()] = {Major, Minor};
769-
return Error::success();
770-
}
771-
772-
static Error processSingleLetterExtension(
773-
StringRef &RawExt,
774-
MapVector<std::string, RISCVISAInfo::ExtensionVersion,
775-
std::map<std::string, unsigned>> &SeenExtMap,
776-
bool IgnoreUnknown, bool EnableExperimentalExtension,
777-
bool ExperimentalExtensionVersionCheck) {
778-
unsigned Major, Minor, ConsumeLength;
779-
StringRef Name = RawExt.take_front(1);
780-
RawExt.consume_front(Name);
781-
if (auto E = getExtensionVersion(Name, RawExt, Major, Minor, ConsumeLength,
782-
EnableExperimentalExtension,
783-
ExperimentalExtensionVersionCheck)) {
784-
if (IgnoreUnknown) {
785-
consumeError(std::move(E));
786-
RawExt = RawExt.substr(ConsumeLength);
787-
return Error::success();
788-
}
789-
return E;
790-
}
791-
792-
RawExt = RawExt.substr(ConsumeLength);
793-
794-
// Check if duplicated extension.
795-
if (!IgnoreUnknown && SeenExtMap.contains(Name.str()))
796-
return createStringError(errc::invalid_argument,
797-
"duplicated standard user-level extension '%s'",
798-
Name.str().c_str());
799-
800-
if (IgnoreUnknown && !RISCVISAInfo::isSupportedExtension(Name))
801-
return Error::success();
802-
803-
SeenExtMap[Name.str()] = {Major, Minor};
804-
return Error::success();
805-
}
806-
807706
llvm::Expected<std::unique_ptr<RISCVISAInfo>>
808707
RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension,
809708
bool ExperimentalExtensionVersionCheck,
@@ -824,9 +723,6 @@ RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension,
824723

825724
unsigned XLen = HasRV64 ? 64 : 32;
826725
std::unique_ptr<RISCVISAInfo> ISAInfo(new RISCVISAInfo(XLen));
827-
MapVector<std::string, RISCVISAInfo::ExtensionVersion,
828-
std::map<std::string, unsigned>>
829-
SeenExtMap;
830726

831727
// The canonical order specified in ISA manual.
832728
// Ref: Table 22.1 in RISC-V User-Level ISA V2.2
@@ -857,6 +753,17 @@ RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension,
857753
// Skip rvxxx
858754
StringRef Exts = Arch.substr(5);
859755

756+
// Remove multi-letter standard extensions, non-standard extensions and
757+
// supervisor-level extensions. They have 'z', 'x', 's' prefixes.
758+
// Parse them at the end.
759+
// Find the very first occurrence of 's', 'x' or 'z'.
760+
StringRef OtherExts;
761+
size_t Pos = Exts.find_first_of("zsx");
762+
if (Pos != StringRef::npos) {
763+
OtherExts = Exts.substr(Pos);
764+
Exts = Exts.substr(0, Pos);
765+
}
766+
860767
unsigned Major, Minor, ConsumeLength;
861768
if (Baseline == 'g') {
862769
// Versions for g are disallowed, and this was checked for previously.
@@ -866,10 +773,9 @@ RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension,
866773
// version since the we don't have clear version scheme for that on
867774
// ISA spec.
868775
for (const auto *Ext : RISCVGImplications) {
869-
if (auto Version = findDefaultVersion(Ext)) {
870-
// Postpone AddExtension until end of this function
871-
SeenExtMap[Ext] = {Version->Major, Version->Minor};
872-
} else
776+
if (auto Version = findDefaultVersion(Ext))
777+
ISAInfo->addExtension(Ext, *Version);
778+
else
873779
llvm_unreachable("Default extension version not found?");
874780
}
875781
} else {
@@ -887,69 +793,151 @@ RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension,
887793
Minor = Version->Minor;
888794
}
889795

890-
// Postpone AddExtension until end of this function
891-
SeenExtMap[StringRef(&Baseline, 1).str()] = {Major, Minor};
796+
ISAInfo->addExtension(StringRef(&Baseline, 1), {Major, Minor});
892797
}
893798

894799
// Consume the base ISA version number and any '_' between rvxxx and the
895800
// first extension
896801
Exts = Exts.drop_front(ConsumeLength);
897802
Exts.consume_front("_");
898803

899-
std::vector<std::string> SplittedExts;
900-
if (auto E = splitExtsByUnderscore(Exts, SplittedExts))
901-
return std::move(E);
902-
903-
for (auto &Ext : SplittedExts) {
904-
StringRef CurrExt = Ext;
905-
while (!CurrExt.empty()) {
906-
if (AllStdExts.contains(CurrExt.front())) {
907-
if (auto E = processSingleLetterExtension(
908-
CurrExt, SeenExtMap, IgnoreUnknown, EnableExperimentalExtension,
909-
ExperimentalExtensionVersionCheck))
910-
return E;
911-
} else if (CurrExt.front() == 'z' || CurrExt.front() == 's' ||
912-
CurrExt.front() == 'x') {
913-
// Handle other types of extensions other than the standard
914-
// general purpose and standard user-level extensions.
915-
// Parse the ISA string containing non-standard user-level
916-
// extensions, standard supervisor-level extensions and
917-
// non-standard supervisor-level extensions.
918-
// These extensions start with 'z', 's', 'x' prefixes, might have a
919-
// version number (major, minor) and are separated by a single
920-
// underscore '_'. We do not enforce a canonical order for them.
921-
if (auto E = processMultiLetterExtension(
922-
CurrExt, SeenExtMap, IgnoreUnknown, EnableExperimentalExtension,
923-
ExperimentalExtensionVersionCheck))
924-
return E;
925-
// Multi-letter extension must be seperate following extension with
926-
// underscore
927-
break;
928-
} else {
929-
// FIXME: Could it be ignored by IgnoreUnknown?
930-
return createStringError(errc::invalid_argument,
931-
"invalid standard user-level extension '%c'",
932-
CurrExt.front());
804+
auto StdExtsItr = StdExts.begin();
805+
auto StdExtsEnd = StdExts.end();
806+
auto GoToNextExt = [](StringRef::iterator &I, unsigned ConsumeLength,
807+
StringRef::iterator E) {
808+
I += 1 + ConsumeLength;
809+
if (I != E && *I == '_')
810+
++I;
811+
};
812+
for (auto I = Exts.begin(), E = Exts.end(); I != E;) {
813+
char C = *I;
814+
815+
// Check ISA extensions are specified in the canonical order.
816+
while (StdExtsItr != StdExtsEnd && *StdExtsItr != C)
817+
++StdExtsItr;
818+
819+
if (StdExtsItr == StdExtsEnd) {
820+
// Either c contains a valid extension but it was not given in
821+
// canonical order or it is an invalid extension.
822+
if (StdExts.contains(C)) {
823+
return createStringError(
824+
errc::invalid_argument,
825+
"standard user-level extension not given in canonical order '" +
826+
Twine(C) + "'");
827+
}
828+
829+
return createStringError(errc::invalid_argument,
830+
"invalid standard user-level extension '" +
831+
Twine(C) + "'");
832+
}
833+
834+
// Move to next char to prevent repeated letter.
835+
++StdExtsItr;
836+
837+
StringRef Next;
838+
unsigned Major, Minor, ConsumeLength;
839+
if (std::next(I) != E)
840+
Next = StringRef(std::next(I), E - std::next(I));
841+
if (auto E = getExtensionVersion(StringRef(&C, 1), Next, Major, Minor,
842+
ConsumeLength, EnableExperimentalExtension,
843+
ExperimentalExtensionVersionCheck)) {
844+
if (IgnoreUnknown) {
845+
consumeError(std::move(E));
846+
GoToNextExt(I, ConsumeLength, Exts.end());
847+
continue;
848+
}
849+
return std::move(E);
850+
}
851+
852+
// The order is OK, then push it into features.
853+
// Currently LLVM supports only "mafdcvh".
854+
if (!isSupportedExtension(StringRef(&C, 1))) {
855+
if (IgnoreUnknown) {
856+
GoToNextExt(I, ConsumeLength, Exts.end());
857+
continue;
933858
}
859+
return createStringError(errc::invalid_argument,
860+
"unsupported standard user-level extension '" +
861+
Twine(C) + "'");
934862
}
863+
ISAInfo->addExtension(StringRef(&C, 1), {Major, Minor});
864+
865+
// Consume full extension name and version, including any optional '_'
866+
// between this extension and the next
867+
GoToNextExt(I, ConsumeLength, Exts.end());
935868
}
936869

937-
// Check all Extensions are supported.
938-
for (auto &SeenExtAndVers : SeenExtMap) {
939-
const std::string &ExtName = SeenExtAndVers.first;
940-
RISCVISAInfo::ExtensionVersion ExtVers = SeenExtAndVers.second;
870+
// Handle other types of extensions other than the standard
871+
// general purpose and standard user-level extensions.
872+
// Parse the ISA string containing non-standard user-level
873+
// extensions, standard supervisor-level extensions and
874+
// non-standard supervisor-level extensions.
875+
// These extensions start with 'z', 's', 'x' prefixes, might have a version
876+
// number (major, minor) and are separated by a single underscore '_'. We do
877+
// not enforce a canonical order for them.
878+
// Set the hardware features for the extensions that are supported.
879+
880+
// Multi-letter extensions are seperated by a single underscore
881+
// as described in RISC-V User-Level ISA V2.2.
882+
SmallVector<StringRef, 8> Split;
883+
OtherExts.split(Split, '_');
941884

942-
if (!RISCVISAInfo::isSupportedExtension(ExtName)) {
943-
if (ExtName.size() == 1) {
944-
return createStringError(
945-
errc::invalid_argument,
946-
"unsupported standard user-level extension '%s'", ExtName.c_str());
885+
SmallVector<StringRef, 8> AllExts;
886+
if (Split.size() > 1 || Split[0] != "") {
887+
for (StringRef Ext : Split) {
888+
if (Ext.empty())
889+
return createStringError(errc::invalid_argument,
890+
"extension name missing after separator '_'");
891+
892+
StringRef Type = getExtensionType(Ext);
893+
StringRef Desc = getExtensionTypeDesc(Ext);
894+
auto Pos = findLastNonVersionCharacter(Ext) + 1;
895+
StringRef Name(Ext.substr(0, Pos));
896+
StringRef Vers(Ext.substr(Pos));
897+
898+
if (Type.empty()) {
899+
if (IgnoreUnknown)
900+
continue;
901+
return createStringError(errc::invalid_argument,
902+
"invalid extension prefix '" + Ext + "'");
903+
}
904+
905+
if (!IgnoreUnknown && Name.size() == Type.size())
906+
return createStringError(errc::invalid_argument,
907+
Desc + " name missing after '" + Type + "'");
908+
909+
unsigned Major, Minor, ConsumeLength;
910+
if (auto E = getExtensionVersion(Name, Vers, Major, Minor, ConsumeLength,
911+
EnableExperimentalExtension,
912+
ExperimentalExtensionVersionCheck)) {
913+
if (IgnoreUnknown) {
914+
consumeError(std::move(E));
915+
continue;
916+
}
917+
return std::move(E);
947918
}
948-
return createStringError(errc::invalid_argument, "unsupported %s '%s'",
949-
getExtensionTypeDesc(ExtName).str().c_str(),
950-
ExtName.c_str());
919+
920+
// Check if duplicated extension.
921+
if (!IgnoreUnknown && llvm::is_contained(AllExts, Name))
922+
return createStringError(errc::invalid_argument,
923+
"duplicated " + Desc + " '" + Name + "'");
924+
925+
if (IgnoreUnknown && !isSupportedExtension(Name))
926+
continue;
927+
928+
ISAInfo->addExtension(Name, {Major, Minor});
929+
// Extension format is correct, keep parsing the extensions.
930+
// TODO: Save Type, Name, Major, Minor to avoid parsing them later.
931+
AllExts.push_back(Name);
932+
}
933+
}
934+
935+
for (auto Ext : AllExts) {
936+
if (!isSupportedExtension(Ext)) {
937+
StringRef Desc = getExtensionTypeDesc(getExtensionType(Ext));
938+
return createStringError(errc::invalid_argument,
939+
"unsupported " + Desc + " '" + Ext + "'");
951940
}
952-
ISAInfo->addExtension(ExtName, ExtVers);
953941
}
954942

955943
return RISCVISAInfo::postProcessAndChecking(std::move(ISAInfo));

0 commit comments

Comments
 (0)