Skip to content

Commit

Permalink
[RISCV] Fix arch string parsing for multi-character extensions
Browse files Browse the repository at this point in the history
Current implementation can't parse extension names that contains digits
correctly (e.g. `zvl128b`). This patch fixes it.

Reviewed By: asb

Differential Revision: https://reviews.llvm.org/D109215
  • Loading branch information
eopXD committed Dec 10, 2021
1 parent 79a0330 commit e308b8e
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 2 deletions.
2 changes: 1 addition & 1 deletion clang/test/Driver/riscv-arch.c
Expand Up @@ -392,7 +392,7 @@

// RUN: %clang -target riscv32-unknown-elf -march=rv32izbb1p0zbp0p93 -menable-experimental-extensions -### %s \
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-EXPERIMENTAL-ZBB-ZBP-UNDERSCORE %s
// RV32-EXPERIMENTAL-ZBB-ZBP-UNDERSCORE: error: invalid arch name 'rv32izbb1p0zbp0p93', multi-character extensions must be separated by underscores
// RV32-EXPERIMENTAL-ZBB-ZBP-UNDERSCORE: error: invalid arch name 'rv32izbb1p0zbp0p93', unsupported version number 0.93 for extension 'zbb1p0zbp'

// RUN: %clang -target riscv32-unknown-elf -march=rv32izba1p0 -menable-experimental-extensions -### %s \
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-EXPERIMENTAL-ZBA %s
Expand Down
24 changes: 23 additions & 1 deletion llvm/lib/Support/RISCVISAInfo.cpp
Expand Up @@ -72,6 +72,28 @@ static bool stripExperimentalPrefix(StringRef &Ext) {
return Ext.consume_front("experimental-");
}

// This function finds the first character that doesn't belong to a version
// (e.g. zbe0p93 is extension 'zbe' of version '0p93'). So the function will
// consume [0-9]*p[0-9]* starting from the backward. An extension name will not
// end with a digit or the letter 'p', so this function will parse correctly.
// NOTE: This function is NOT able to take empty strings or strings that only
// have version numbers and no extension name. It assumes the extension name
// will be at least more than one character.
static size_t findFirstNonVersionCharacter(const StringRef &Ext) {
if (Ext.size() == 0)
llvm_unreachable("Already guarded by if-statement in ::parseArchString");

int Pos = Ext.size() - 1;
while (Pos > 0 && isDigit(Ext[Pos]))
Pos--;
if (Pos > 0 && Ext[Pos] == 'p' && isDigit(Ext[Pos - 1])) {
Pos--;
while (Pos > 0 && isDigit(Ext[Pos]))
Pos--;
}
return Pos;
}

struct FindByName {
FindByName(StringRef Ext) : Ext(Ext){};
StringRef Ext;
Expand Down Expand Up @@ -638,7 +660,7 @@ RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension,

StringRef Type = getExtensionType(Ext);
StringRef Desc = getExtensionTypeDesc(Ext);
auto Pos = Ext.find_if(isDigit);
size_t Pos = findFirstNonVersionCharacter(Ext) + 1;
StringRef Name(Ext.substr(0, Pos));
StringRef Vers(Ext.substr(Pos));

Expand Down

0 comments on commit e308b8e

Please sign in to comment.