diff --git a/llvm/test/tools/UpdateTestChecks/update_mir_test_checks/Inputs/x86-multiple-prefixes.ll b/llvm/test/tools/UpdateTestChecks/update_mir_test_checks/Inputs/x86-multiple-prefixes.ll new file mode 100644 --- /dev/null +++ b/llvm/test/tools/UpdateTestChecks/update_mir_test_checks/Inputs/x86-multiple-prefixes.ll @@ -0,0 +1,16 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin -stop-after=finalize-isel | FileCheck --check-prefixes=CHECK,NOAVX %s +; RUN: llc < %s -mtriple=x86_64-apple-darwin -stop-after=finalize-isel -mattr=avx | FileCheck --check-prefixes=CHECK,AVX %s + +@x = common global float zeroinitializer, align 4 +@z = common global <4 x float> zeroinitializer, align 16 + +define void @zero32() nounwind ssp { + store float zeroinitializer, ptr @x, align 4 + ret void +} + +define void @zero128() nounwind ssp { + store <4 x float> zeroinitializer, ptr @z, align 16 + ret void +} + diff --git a/llvm/test/tools/UpdateTestChecks/update_mir_test_checks/Inputs/x86-multiple-prefixes.ll.expected b/llvm/test/tools/UpdateTestChecks/update_mir_test_checks/Inputs/x86-multiple-prefixes.ll.expected new file mode 100644 --- /dev/null +++ b/llvm/test/tools/UpdateTestChecks/update_mir_test_checks/Inputs/x86-multiple-prefixes.ll.expected @@ -0,0 +1,34 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc < %s -mtriple=x86_64-apple-darwin -stop-after=finalize-isel | FileCheck --check-prefixes=CHECK,NOAVX %s +; RUN: llc < %s -mtriple=x86_64-apple-darwin -stop-after=finalize-isel -mattr=avx | FileCheck --check-prefixes=CHECK,AVX %s + +@x = common global float zeroinitializer, align 4 +@z = common global <4 x float> zeroinitializer, align 16 + +define void @zero32() nounwind ssp { + ; CHECK-LABEL: name: zero32 + ; CHECK: bb.0 (%ir-block.0): + ; CHECK-NEXT: [[MOV64rm:%[0-9]+]]:gr64 = MOV64rm $rip, 1, $noreg, target-flags(x86-gotpcrel) @x, $noreg :: (load (s64) from got) + ; CHECK-NEXT: MOV32mi killed [[MOV64rm]], 1, $noreg, 0, $noreg, 0 :: (store (s32) into @x) + ; CHECK-NEXT: RET 0 + store float zeroinitializer, ptr @x, align 4 + ret void +} + +define void @zero128() nounwind ssp { + ; NOAVX-LABEL: name: zero128 + ; NOAVX: bb.0 (%ir-block.0): + ; NOAVX-NEXT: [[V_SET0_:%[0-9]+]]:vr128 = V_SET0 + ; NOAVX-NEXT: [[MOV64rm:%[0-9]+]]:gr64 = MOV64rm $rip, 1, $noreg, target-flags(x86-gotpcrel) @z, $noreg :: (load (s64) from got, align 16) + ; NOAVX-NEXT: MOVAPSmr killed [[MOV64rm]], 1, $noreg, 0, $noreg, killed [[V_SET0_]] :: (store (s128) into @z) + ; NOAVX-NEXT: RET 0 + ; AVX-LABEL: name: zero128 + ; AVX: bb.0 (%ir-block.0): + ; AVX-NEXT: [[V_SET0_:%[0-9]+]]:vr128 = V_SET0 + ; AVX-NEXT: [[MOV64rm:%[0-9]+]]:gr64 = MOV64rm $rip, 1, $noreg, target-flags(x86-gotpcrel) @z, $noreg :: (load (s64) from got, align 16) + ; AVX-NEXT: VMOVAPSmr killed [[MOV64rm]], 1, $noreg, 0, $noreg, killed [[V_SET0_]] :: (store (s128) into @z) + ; AVX-NEXT: RET 0 + store <4 x float> zeroinitializer, ptr @z, align 16 + ret void +} + diff --git a/llvm/test/tools/UpdateTestChecks/update_mir_test_checks/x86-multiple-prefixes.test b/llvm/test/tools/UpdateTestChecks/update_mir_test_checks/x86-multiple-prefixes.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/UpdateTestChecks/update_mir_test_checks/x86-multiple-prefixes.test @@ -0,0 +1,5 @@ +# REQUIRES: x86-registered-target +## Check that update_mir_test_checks handles multiple check prefixes + +# RUN: cp -f %S/Inputs/x86-multiple-prefixes.ll %t.ll && %update_mir_test_checks %t.ll +# RUN: diff -u %S/Inputs/x86-multiple-prefixes.ll.expected %t.ll diff --git a/llvm/utils/update_mir_test_checks.py b/llvm/utils/update_mir_test_checks.py --- a/llvm/utils/update_mir_test_checks.py +++ b/llvm/utils/update_mir_test_checks.py @@ -139,13 +139,12 @@ run_list.append(Run(check_prefixes, cmd_args, triple)) - # Remove any common prefixes. We'll just leave those entirely alone. - common_prefixes = set([prefix for prefix in all_prefixes - if all_prefixes.count(prefix) > 1]) + # Sort prefixes that are shared between run lines before unshared prefixes. + # This causes us to prefer printing shared prefixes. for run in run_list: - run.prefixes = [p for p in run.prefixes if p not in common_prefixes] + run.prefixes.sort(key=lambda prefix: -all_prefixes.count(prefix)) - return run_list, common_prefixes + return run_list def find_functions_with_one_bb(lines, verbose=False): @@ -176,11 +175,30 @@ log('Processing function: {}'.format(func)) for l in body.splitlines(): log(' {}'.format(l)) + + # Vreg mangling + mangled = [] + vreg_map = {} + for func_line in body.splitlines(keepends=True): + m = VREG_DEF_RE.match(func_line) + if m: + for vreg in VREG_RE.finditer(m.group('vregs')): + name = mangle_vreg(m.group('opcode'), vreg_map.values()) + vreg_map[vreg.group(1)] = name + func_line = func_line.replace( + vreg.group(1), '[[{}:%[0-9]+]]'.format(name), 1) + for number, name in vreg_map.items(): + func_line = re.sub(r'{}\b'.format(number), '[[{}]]'.format(name), + func_line) + mangled.append(func_line) + body = ''.join(mangled) + for prefix in prefixes: - if func in func_dict[prefix] and func_dict[prefix][func] != body: - common.warn('Found conflicting asm for prefix: {}'.format(prefix), - test_file=test) - func_dict[prefix][func] = body + if func in func_dict[prefix]: + if func_dict[prefix][func] != body: + func_dict[prefix][func] = None + else: + func_dict[prefix][func] = body def add_checks_for_function(test, output_lines, run_list, func_dict, func_name, @@ -189,7 +207,7 @@ for run in run_list: for prefix in run.prefixes: if prefix in printed_prefixes: - continue + break if not func_dict[prefix][func_name]: continue # if printed_prefixes: @@ -200,6 +218,10 @@ add_check_lines(test, output_lines, prefix, func_name, single_bb, func_dict[prefix][func_name].splitlines()) break + else: + common.warn( + 'Found conflicting asm for function: {}'.format(func_name), + test_file=test) return output_lines @@ -222,22 +244,11 @@ output_lines.append('{}-LABEL: name: {}'.format(check, func_name)) first_check = True - vreg_map = {} for func_line in func_body: if not func_line.strip(): # The mir printer prints leading whitespace so we can't use CHECK-EMPTY: output_lines.append(check + '-NEXT: {{' + func_line + '$}}') continue - m = VREG_DEF_RE.match(func_line) - if m: - for vreg in VREG_RE.finditer(m.group('vregs')): - name = mangle_vreg(m.group('opcode'), vreg_map.values()) - vreg_map[vreg.group(1)] = name - func_line = func_line.replace( - vreg.group(1), '[[{}:%[0-9]+]]'.format(name), 1) - for number, name in vreg_map.items(): - func_line = re.sub(r'{}\b'.format(number), '[[{}]]'.format(name), - func_line) filecheck_directive = check if first_check else check + '-NEXT' first_check = False check_line = '{}: {}'.format(filecheck_directive, func_line[indent:]).rstrip() @@ -302,7 +313,7 @@ triple_in_ir = find_triple_in_ir(input_lines, args.verbose) run_lines = common.find_run_lines(test, input_lines) - run_list, common_prefixes = build_run_list(test, run_lines, args.verbose) + run_list = build_run_list(test, run_lines, args.verbose) simple_functions = find_functions_with_one_bb(input_lines, args.verbose) @@ -328,12 +339,6 @@ prefix_set = set([prefix for run in run_list for prefix in run.prefixes]) log('Rewriting FileCheck prefixes: {}'.format(prefix_set), args.verbose) - if args.remove_common_prefixes: - prefix_set.update(common_prefixes) - elif common_prefixes: - common.warn('Ignoring common prefixes: {}'.format(common_prefixes), - test_file=test) - comment_char = '#' if test.endswith('.mir') else ';' autogenerated_note = ('{} NOTE: Assertions have been autogenerated by ' 'utils/{}'.format(comment_char, script_name)) @@ -420,9 +425,6 @@ description=__doc__, formatter_class=argparse.RawTextHelpFormatter) parser.add_argument('--llc-binary', dest='llc', default='llc', type=LLC, help='The "llc" binary to generate the test case with') - parser.add_argument('--remove-common-prefixes', action='store_true', - help='Remove existing check lines whose prefixes are ' - 'shared between multiple commands') parser.add_argument('tests', nargs='+') args = common.parse_commandline_args(parser)