Skip to content

Commit

Permalink
[UpdateTestChecks] Use a counter for unpredictable FileCheck variables
Browse files Browse the repository at this point in the history
Variable captures such as `<MCInst #` can change based on unrelated changes
to the LLVM backends, to avoid the generated test cases being different
use an incrementing counter for variable names instead of using the
actual value from the output file.
This change may also be beneficial for some nameless IR variables
(especially when combined with filtering of output), but for now I've
restricted this change to the obvious candidates (--asm-show-inst output).

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D125405
  • Loading branch information
arichardson committed May 14, 2022
1 parent 37a6849 commit 996873c
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 38 deletions.
Expand Up @@ -6,17 +6,17 @@
define i8 @add_i8(i8 %a) nounwind {
; VERBOSE-LABEL: add_i8:
; VERBOSE: # %bb.0:
; VERBOSE-NEXT: movb {{[0-9]+}}(%esp), %al # <MCInst #[[#MCINST1804:]] MOV8rm
; VERBOSE-NEXT: movb {{[0-9]+}}(%esp), %al # <MCInst #[[#MCINST1:]] MOV8rm
; VERBOSE-NEXT: # <MCOperand Reg:[[#MCREG1:]]>
; VERBOSE-NEXT: # <MCOperand Reg:[[#MCREG2:]]>
; VERBOSE-NEXT: # <MCOperand Reg:[[#MCREG33:]]>
; VERBOSE-NEXT: # <MCOperand Imm:1>
; VERBOSE-NEXT: # <MCOperand Reg:[[#MCREG0:]]>
; VERBOSE-NEXT: # <MCOperand Reg:[[#MCREG3:]]>
; VERBOSE-NEXT: # <MCOperand Imm:4>
; VERBOSE-NEXT: # <MCOperand Reg:[[#MCREG0]]>>
; VERBOSE-NEXT: addb $2, %al # <MCInst #[[#MCINST400:]] ADD8i8
; VERBOSE-NEXT: # <MCOperand Reg:[[#MCREG3]]>>
; VERBOSE-NEXT: addb $2, %al # <MCInst #[[#MCINST2:]] ADD8i8
; VERBOSE-NEXT: # <MCOperand Imm:2>>
; VERBOSE-NEXT: retl # <MCInst #[[#MCINST2560:]] RET32
; VERBOSE-NEXT: # <MCOperand Reg:[[#MCREG2]]>>
; VERBOSE-NEXT: retl # <MCInst #[[#MCINST3:]] RET32
; VERBOSE-NEXT: # <MCOperand Reg:[[#MCREG1]]>>
;
; CHECK-LABEL: add_i8:
; CHECK: # %bb.0:
Expand All @@ -30,19 +30,19 @@ define i8 @add_i8(i8 %a) nounwind {
define i32 @add_i32(i32 %a) nounwind {
; VERBOSE-LABEL: add_i32:
; VERBOSE: # %bb.0:
; VERBOSE-NEXT: movl {{[0-9]+}}(%esp), %eax # <MCInst #[[#MCINST1768:]] MOV32rm
; VERBOSE-NEXT: # <MCOperand Reg:[[#MCREG22:]]>
; VERBOSE-NEXT: # <MCOperand Reg:[[#MCREG33]]>
; VERBOSE-NEXT: movl {{[0-9]+}}(%esp), %eax # <MCInst #[[#MCINST4:]] MOV32rm
; VERBOSE-NEXT: # <MCOperand Reg:[[#MCREG4:]]>
; VERBOSE-NEXT: # <MCOperand Reg:[[#MCREG2]]>
; VERBOSE-NEXT: # <MCOperand Imm:1>
; VERBOSE-NEXT: # <MCOperand Reg:[[#MCREG0]]>
; VERBOSE-NEXT: # <MCOperand Reg:[[#MCREG3]]>
; VERBOSE-NEXT: # <MCOperand Imm:4>
; VERBOSE-NEXT: # <MCOperand Reg:[[#MCREG0]]>>
; VERBOSE-NEXT: addl $2, %eax # <MCInst #[[#MCINST387:]] ADD32ri8
; VERBOSE-NEXT: # <MCOperand Reg:[[#MCREG22]]>
; VERBOSE-NEXT: # <MCOperand Reg:[[#MCREG22]]>
; VERBOSE-NEXT: # <MCOperand Reg:[[#MCREG3]]>>
; VERBOSE-NEXT: addl $2, %eax # <MCInst #[[#MCINST5:]] ADD32ri8
; VERBOSE-NEXT: # <MCOperand Reg:[[#MCREG4]]>
; VERBOSE-NEXT: # <MCOperand Reg:[[#MCREG4]]>
; VERBOSE-NEXT: # <MCOperand Imm:2>>
; VERBOSE-NEXT: retl # <MCInst #[[#MCINST2560]] RET32
; VERBOSE-NEXT: # <MCOperand Reg:[[#MCREG22]]>>
; VERBOSE-NEXT: retl # <MCInst #[[#MCINST3]] RET32
; VERBOSE-NEXT: # <MCOperand Reg:[[#MCREG4]]>>
;
; CHECK-LABEL: add_i32:
; CHECK: # %bb.0:
Expand Down
57 changes: 36 additions & 21 deletions llvm/utils/UpdateTestChecks/common.py
Expand Up @@ -597,7 +597,8 @@ def _get_failed_prefixes(self):

class NamelessValue:
def __init__(self, check_prefix, check_key, ir_prefix, global_ir_prefix, global_ir_prefix_regexp,
ir_regexp, global_ir_rhs_regexp, is_before_functions, is_number=False):
ir_regexp, global_ir_rhs_regexp, is_before_functions, *,
is_number=False, replace_number_with_counter=False):
self.check_prefix = check_prefix
self.check_key = check_key
self.ir_prefix = ir_prefix
Expand All @@ -607,6 +608,10 @@ def __init__(self, check_prefix, check_key, ir_prefix, global_ir_prefix, global_
self.global_ir_rhs_regexp = global_ir_rhs_regexp
self.is_before_functions = is_before_functions
self.is_number = is_number
# Some variable numbers (e.g. MCINST1234) will change based on unrelated
# modifications to LLVM, replace those with an incrementing counter.
self.replace_number_with_counter = replace_number_with_counter
self.variable_mapping = {}

# Return true if this kind of IR value is "local", basically if it matches '%{{.*}}'.
def is_local_def_ir_value_match(self, match):
Expand All @@ -632,10 +637,33 @@ def get_ir_regex_from_ir_value_re_match(self, match):
return self.ir_regexp
return self.global_ir_prefix_regexp

# Create a FileCheck variable name based on an IR name.
def get_value_name(self, var: str, check_prefix: str):
var = var.replace('!', '')
if self.replace_number_with_counter:
assert var.isdigit(), var
replacement = self.variable_mapping.get(var, None)
if replacement is None:
# Replace variable with an incrementing counter
replacement = str(len(self.variable_mapping) + 1)
self.variable_mapping[var] = replacement
var = replacement
# This is a nameless value, prepend check_prefix.
if var.isdigit():
var = check_prefix + var
else:
# This is a named value that clashes with the check_prefix, prepend with
# _prefix_filecheck_ir_name, if it has been defined.
if may_clash_with_default_check_prefix_name(check_prefix, var) and _prefix_filecheck_ir_name:
var = _prefix_filecheck_ir_name + var
var = var.replace('.', '_')
var = var.replace('-', '_')
return var.upper()

# Create a FileCheck variable from regex.
def get_value_definition(self, var, match):
# for backwards compatibility we check locals with '.*'
varname = get_value_name(var, self.check_prefix)
varname = self.get_value_name(var, self.check_prefix)
prefix = self.get_ir_prefix_from_ir_value_match(match)[0]
if self.is_number:
regex = '' # always capture a number in the default format
Expand All @@ -653,9 +681,9 @@ def get_value_use(self, var, match, var_prefix=None):
var_prefix = self.check_prefix
capture_start = '[[#' if self.is_number else '[['
if self.is_local_def_ir_value_match(match):
return capture_start + get_value_name(var, var_prefix) + ']]'
return capture_start + self.get_value_name(var, var_prefix) + ']]'
prefix = self.get_ir_prefix_from_ir_value_match(match)[0]
return prefix + capture_start + get_value_name(var, var_prefix) + ']]'
return prefix + capture_start + self.get_value_name(var, var_prefix) + ']]'

# Description of the different "unnamed" values we match in the IR, e.g.,
# (local) ssa values, (debug) metadata, etc.
Expand All @@ -675,8 +703,10 @@ def get_value_use(self, var, match, var_prefix=None):
]

asm_nameless_values = [
NamelessValue(r'MCINST', 'Inst#', None, '<MCInst #', r'\d+', None, r'.+', False, True),
NamelessValue(r'MCREG', 'Reg:', None, '<MCOperand Reg:', r'\d+', None, r'.+', False, True),
NamelessValue(r'MCINST', 'Inst#', None, '<MCInst #', r'\d+', None, r'.+',
False, is_number=True, replace_number_with_counter=True),
NamelessValue(r'MCREG', 'Reg:', None, '<MCOperand Reg:', r'\d+', None, r'.+',
False, is_number=True, replace_number_with_counter=True),
]

def createOrRegexp(old, new):
Expand Down Expand Up @@ -745,21 +775,6 @@ def get_nameless_value_from_match(match, nameless_values) -> NamelessValue:
def may_clash_with_default_check_prefix_name(check_prefix, var):
return check_prefix and re.match(r'^' + check_prefix + r'[0-9]+?$', var, re.IGNORECASE)

# Create a FileCheck variable name based on an IR name.
def get_value_name(var, check_prefix):
var = var.replace('!', '')
# This is a nameless value, prepend check_prefix.
if var.isdigit():
var = check_prefix + var
else:
# This is a named value that clashes with the check_prefix, prepend with _prefix_filecheck_ir_name,
# if it has been defined.
if may_clash_with_default_check_prefix_name(check_prefix, var) and _prefix_filecheck_ir_name:
var = _prefix_filecheck_ir_name + var
var = var.replace('.', '_')
var = var.replace('-', '_')
return var.upper()

def generalize_check_lines_common(lines, is_analyze, vars_seen,
global_vars_seen, nameless_values,
nameless_value_regex, is_asm):
Expand Down

0 comments on commit 996873c

Please sign in to comment.