diff --git a/mlir/lib/IR/AsmPrinter.cpp b/mlir/lib/IR/AsmPrinter.cpp --- a/mlir/lib/IR/AsmPrinter.cpp +++ b/mlir/lib/IR/AsmPrinter.cpp @@ -760,7 +760,43 @@ valueNames[value] = uniqueValueName(name); } +// Returns true if 'c' is an allowable punctuation character: [$._-] +// Returns false otherwise. +static bool isPunct(char c) { + return c == '$' || c == '.' || c == '_' || c == '-'; +} + StringRef SSANameState::uniqueValueName(StringRef name) { + assert(!name.empty() && "Shouldn't have an empty name here"); + + // Check to see if this name is valid. If it starts with a digit, then it + // could conflict with the autogenerated numeric ID's (we unique them in a + // different map), so add an underscore prefix to avoid problems. + if (isdigit(name[0])) { + SmallString<16> tmpName("_"); + tmpName += name; + return uniqueValueName(tmpName); + } + + // Check to see if the name consists of all-valid identifiers. If not, we + // need to escape them. + for (auto ch : name) { + if (isalpha(ch) || isPunct(ch) || isdigit(ch)) + continue; + + SmallString<16> tmpName; + for (auto ch : name) { + if (isalpha(ch) || isPunct(ch) || isdigit(ch)) + tmpName += ch; + else if (ch == ' ') + tmpName += '_'; + else { + tmpName += llvm::utohexstr((unsigned char)ch); + } + } + return uniqueValueName(tmpName); + } + // Check to see if this name is already unique. if (!usedNames.count(name)) { name = name.copy(usedNameAllocator); diff --git a/mlir/test/IR/pretty-region-args.mlir b/mlir/test/IR/pretty-region-args.mlir --- a/mlir/test/IR/pretty-region-args.mlir +++ b/mlir/test/IR/pretty-region-args.mlir @@ -10,3 +10,17 @@ // CHECK-NEXT: ^bb{{.*}}(%i: index, %j: index, %k: index): return } + +// CHECK-LABEL: func @weird_names +// Make sure the asmprinter handles weird names correctly. +func @weird_names() -> () { + "test.polyfor"() ( { + ^bb0(%arg0: i32, %arg1: i32, %arg2: index): + "foo"() : () -> i32 + }) { arg_names = ["a .^x", "0"] } : () -> () + // CHECK: test.polyfor + // CHECK-NEXT: ^bb{{.*}}(%a_.5Ex: i32, %_0: i32, %arg0: index): + // CHECK-NEXT: %0 = "foo"() + return +} +