From 1698cc7ebabe47be6cf225960e55ddb8a884d118 Mon Sep 17 00:00:00 2001 From: Johannes Doerfert Date: Thu, 31 Oct 2019 22:45:17 -0500 Subject: [PATCH] [Utils] Allow "on-the-fly" argument changes for update_test_check scripts Update test scripts were limited because they performed a single action on the entire file and if that action was controlled by arguments, like the one introduced in D68819, there was no record of it. This patch introduces the capability of changing the arguments passed to the script "on-the-fly" while processing a test file. In addition, an "on/off" switch was added so that processing can be disabled for parts of the file where the content is simply copied. The last extension is a record of the invocation arguments in the auto generated NOTE. These arguments are also picked up in a subsequent invocation, allowing updates with special options enabled without user interaction. To change the arguments the string `UTC_ARGS:` has to be present in a line, followed by "additional command line arguments". That is everything that follows `UTC_ARGS:` will be added to a growing list of "command line arguments" which is reparsed after every update. Reviewed By: arichardson Differential Revision: https://reviews.llvm.org/D69701 --- llvm/test/Transforms/Attributor/align.ll | 4 +- llvm/test/Transforms/Attributor/liveness.ll | 11 +++--- .../Inputs/argument_name_reuse.ll.expected | 2 +- .../Inputs/basic.ll.funcsig.expected | 2 +- .../Inputs/on_the_fly_arg_change.ll | 30 +++++++++++++++ .../Inputs/on_the_fly_arg_change.ll.expected | 45 ++++++++++++++++++++++ .../Inputs/scrub_attrs.ll.scrub.expected | 2 +- .../UpdateTestChecks/update_test_checks/basic.test | 7 +++- .../update_test_checks/on_the_fly_arg_change.test | 6 +++ .../update_test_checks/scrub_attrs.test | 6 +-- llvm/utils/UpdateTestChecks/common.py | 26 +++++++++++++ llvm/utils/update_test_checks.py | 23 ++++++++--- 12 files changed, 144 insertions(+), 20 deletions(-) create mode 100644 llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/on_the_fly_arg_change.ll create mode 100644 llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/on_the_fly_arg_change.ll.expected create mode 100644 llvm/test/tools/UpdateTestChecks/update_test_checks/on_the_fly_arg_change.test diff --git a/llvm/test/Transforms/Attributor/align.ll b/llvm/test/Transforms/Attributor/align.ll index 13f524d..3d4a761 100644 --- a/llvm/test/Transforms/Attributor/align.ll +++ b/llvm/test/Transforms/Attributor/align.ll @@ -133,7 +133,7 @@ define internal i8* @f3(i8* readnone %0) local_unnamed_addr #0 { ret i8* %6 } -; UTC_ARGS: --turn=on +; UTC_ARGS: --enable ; TEST 7 ; Better than IR information @@ -264,7 +264,7 @@ define align 4 i32* @test7b(i32* align 32 %p) #0 { ret i32* %p } -; UTC_ARGS: --turn=off +; UTC_ARGS: --disable ; TEST 8 define void @test8_helper() { diff --git a/llvm/test/Transforms/Attributor/liveness.ll b/llvm/test/Transforms/Attributor/liveness.ll index 4f1cc36..92142f0 100644 --- a/llvm/test/Transforms/Attributor/liveness.ll +++ b/llvm/test/Transforms/Attributor/liveness.ll @@ -3,7 +3,7 @@ ; RUN: opt -attributor-cgscc --attributor-disable=false -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC ; RUN: opt -passes=attributor --attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,MODULE,ALL_BUT_OLD_CGSCCC ; RUN: opt -passes='attributor-cgscc' --attributor-disable=false -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC,ALL_BUT_OLD_CGSCCC -; UTC_ARGS: --turn off +; UTC_ARGS: --disable ; ALL_BUT_OLD_CGSCCC: @dead_with_blockaddress_users.l = constant [2 x i8*] [i8* inttoptr (i32 1 to i8*), i8* inttoptr (i32 1 to i8*)] @dead_with_blockaddress_users.l = constant [2 x i8*] [i8* blockaddress(@dead_with_blockaddress_users, %lab0), i8* blockaddress(@dead_with_blockaddress_users, %end)] @@ -280,7 +280,7 @@ cleanup: ret i32 0 } -; UTC_ARGS: --turn on +; UTC_ARGS: --enable ; TEST 5.4 unounwind invoke instruction replaced by a call and a branch instruction put after it. define i32 @invoke_nounwind_phi(i32 %a) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { @@ -370,7 +370,7 @@ cleanup: ret i32 0 } -; UTC_ARGS: --turn off +; UTC_ARGS: --disable ; TEST 6: Undefined behvior, taken from LangRef. ; FIXME: Should be able to detect undefined behavior. @@ -894,7 +894,7 @@ define void @useless_arg_ext_int_ext(i32* %a) { ret void } -; UTC_ARGS: --turn on +; UTC_ARGS: --enable ; FIXME: We should fold terminators. @@ -956,7 +956,8 @@ define i32 @switch_default_dead_caller() { %call2 = tail call i32 @switch_default_dead(i64 0) ret i32 %call2 } -; UTC_ARGS: --turn off + +; UTC_ARGS: --disable ; Allow blockaddress users ; ALL_BUT_OLD_CGSCCC-NOT @dead_with_blockaddress_users diff --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/argument_name_reuse.ll.expected b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/argument_name_reuse.ll.expected index ee95826..461a8b6a 100644 --- a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/argument_name_reuse.ll.expected +++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/argument_name_reuse.ll.expected @@ -1,4 +1,4 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature ; RUN: opt < %s -S | FileCheck %s define i32 @reuse_arg_names(i32 %X, i32 %Y) { diff --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/basic.ll.funcsig.expected b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/basic.ll.funcsig.expected index 103b581..d97d1b8 100644 --- a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/basic.ll.funcsig.expected +++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/basic.ll.funcsig.expected @@ -1,4 +1,4 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature ; Example input for update_llc_test_checks (taken from test/Transforms/InstSimplify/add.ll) ; RUN: opt < %s -instsimplify -S | FileCheck %s diff --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/on_the_fly_arg_change.ll b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/on_the_fly_arg_change.ll new file mode 100644 index 0000000..7c54aca --- /dev/null +++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/on_the_fly_arg_change.ll @@ -0,0 +1,30 @@ +; RUN: opt -S < %s | FileCheck %s + +declare void @foo() + +define void @check_lines_1() { + ret void +} + +; UTC_ARGS: --disable + +; A check line that would not be auto generated. +; CHECK: define void @no_check_lines() { +define void @no_check_lines() { + ret void +} + +; UTC_ARGS: --enable + +define void @check_lines_2() { + ret void +} + +define void @scrub() { + call void @foo() readnone + ret void +} + +define i32 @signature(i32 %arg) { + ret i32 %arg +} diff --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/on_the_fly_arg_change.ll.expected b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/on_the_fly_arg_change.ll.expected new file mode 100644 index 0000000..b76f62c --- /dev/null +++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/on_the_fly_arg_change.ll.expected @@ -0,0 +1,45 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes +; RUN: opt -S < %s | FileCheck %s + +declare void @foo() + +define void @check_lines_1() { +; CHECK-LABEL: define {{[^@]+}}@check_lines_1() +; CHECK-NEXT: ret void +; + ret void +} + +; UTC_ARGS: --disable + +; A check line that would not be auto generated. +; CHECK: define void @no_check_lines() { +define void @no_check_lines() { + ret void +} + +; UTC_ARGS: --enable + +define void @check_lines_2() { +; CHECK-LABEL: define {{[^@]+}}@check_lines_2() +; CHECK-NEXT: ret void +; + ret void +} + +define void @scrub() { +; CHECK-LABEL: define {{[^@]+}}@scrub() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: ret void +; + call void @foo() readnone + ret void +} + +define i32 @signature(i32 %arg) { +; CHECK-LABEL: define {{[^@]+}}@signature +; CHECK-SAME: (i32 [[ARG:%.*]]) +; CHECK-NEXT: ret i32 [[ARG]] +; + ret i32 %arg +} diff --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/scrub_attrs.ll.scrub.expected b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/scrub_attrs.ll.scrub.expected index cbea04a..0674a89 100644 --- a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/scrub_attrs.ll.scrub.expected +++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/scrub_attrs.ll.scrub.expected @@ -1,4 +1,4 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --scrub-attributes ; RUN: opt -S < %s | FileCheck %s declare void @foo() diff --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/basic.test b/llvm/test/tools/UpdateTestChecks/update_test_checks/basic.test index 023cccc..2227ead 100644 --- a/llvm/test/tools/UpdateTestChecks/update_test_checks/basic.test +++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/basic.test @@ -8,6 +8,9 @@ ## Also try the --function-signature flag # RUN: %update_test_checks %t.ll --function-signature # RUN: diff -u %t.ll %S/Inputs/basic.ll.funcsig.expected -## Verify that running without the --function-signature flag removes the -SAME: lines: +## Verify that running without the --function-signature flag does not removes +## the -SAME: lines since the generated file will have --function-signature in +## an UTC_ARGS: comment in the first line (from the invocation above) which is +## added to the update invocation below. # RUN: %update_test_checks %t.ll -# RUN: diff -u %t.ll %S/Inputs/basic.ll.expected +# RUN: diff -u %t.ll %S/Inputs/basic.ll.funcsig.expected diff --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/on_the_fly_arg_change.test b/llvm/test/tools/UpdateTestChecks/update_test_checks/on_the_fly_arg_change.test new file mode 100644 index 0000000..bb5f636 --- /dev/null +++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/on_the_fly_arg_change.test @@ -0,0 +1,6 @@ +# RUN: cp -f %S/Inputs/on_the_fly_arg_change.ll %t.ll +# RUN: %update_test_checks %t.ll --function-signature --scrub-attributes +# RUN: diff -u %t.ll %S/Inputs/on_the_fly_arg_change.ll.expected +## Check that running the script again does not change the result: +# RUN: %update_test_checks %t.ll +# RUN: diff -u %t.ll %S/Inputs/on_the_fly_arg_change.ll.expected diff --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/scrub_attrs.test b/llvm/test/tools/UpdateTestChecks/update_test_checks/scrub_attrs.test index 0adfb84..63a5c9c 100644 --- a/llvm/test/tools/UpdateTestChecks/update_test_checks/scrub_attrs.test +++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/scrub_attrs.test @@ -1,9 +1,9 @@ ## scrub_attrs test checking that update_test_checks.py works correctly # RUN: cp -f %S/Inputs/scrub_attrs.ll %t.ll && %update_test_checks %t.ll # RUN: diff -u %t.ll %S/Inputs/scrub_attrs.ll.plain.expected -## Check that running the script again does not change the result: -# RUN: %update_test_checks %t.ll -# RUN: diff -u %t.ll %S/Inputs/scrub_attrs.ll.plain.expected ## Also try the --scrub-attributes flag # RUN: %update_test_checks %t.ll --scrub-attributes # RUN: diff -u %t.ll %S/Inputs/scrub_attrs.ll.scrub.expected +## Check that running the script again does not change the result: +# RUN: %update_test_checks %t.ll +# RUN: diff -u %t.ll %S/Inputs/scrub_attrs.ll.scrub.expected diff --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py index ae4621c..f3a87a0 100644 --- a/llvm/utils/UpdateTestChecks/common.py +++ b/llvm/utils/UpdateTestChecks/common.py @@ -63,6 +63,9 @@ CHECK_PREFIX_RE = re.compile(r'--?check-prefix(?:es)?[= ](\S+)') PREFIX_RE = re.compile('^[a-zA-Z0-9_-]+$') CHECK_RE = re.compile(r'^\s*(?://|[;#])\s*([^:]+?)(?:-NEXT|-NOT|-DAG|-LABEL|-SAME|-EMPTY)?:') +UTC_ARGS_KEY = 'UTC_ARGS:' +UTC_ARGS_CMD = re.compile(r'.*' + UTC_ARGS_KEY + '\s*(?P.*)\s*$') + OPT_FUNCTION_RE = re.compile( r'^\s*define\s+(?:internal\s+)?[^@]*@(?P[\w-]+?)\s*' r'(?P\((\)|(.*?[\w\.\-]+?)\))[^{]*)\{\n(?P.*?)^\}$', @@ -396,3 +399,26 @@ def verify_filecheck_prefixes(fc_cmd): check_prefix(prefix) if prefixes.count(prefix) > 1: warn("Supplied prefix '%s' is not unique in the prefix list." % (prefix,)) + +def get_autogennote_suffix(parser, args): + autogenerated_note_args = '' + for k, v in args._get_kwargs(): + if parser.get_default(k) == v or k == 'tests' or k == 'update_only' or k == 'opt_binary': + continue + k = k.replace('_', '-') + if type(v) is bool: + autogenerated_note_args += '--%s ' % (k) + else: + autogenerated_note_args += '--%s %s ' % (k, v) + if autogenerated_note_args: + autogenerated_note_args = ' %s %s' % (UTC_ARGS_KEY, autogenerated_note_args[:-1]) + return autogenerated_note_args + + +def check_for_command(line, parser, args, argv): + cmd_m = UTC_ARGS_CMD.match(line) + if cmd_m: + cmd = cmd_m.group('cmd').strip().split(' ') + argv = argv + cmd + args = parser.parse_args(filter(lambda arg: arg not in args.tests, argv)) + return args, argv diff --git a/llvm/utils/update_test_checks.py b/llvm/utils/update_test_checks.py index 94e3fef..a54cbbb 100755 --- a/llvm/utils/update_test_checks.py +++ b/llvm/utils/update_test_checks.py @@ -66,6 +66,10 @@ def main(): help='Keep function signature information around for the check line') parser.add_argument('--scrub-attributes', action='store_true', help='Remove attribute annotations (#0) from the end of check line') + parser.add_argument('--enable', action='store_true', dest='enabled', default=True, + help='Activate CHECK line generation from this point forward') + parser.add_argument('--disable', action='store_false', dest='enabled', + help='Deativate CHECK line generation from this point forward') parser.add_argument('tests', nargs='+') args = common.parse_commandline_args(parser) @@ -86,6 +90,8 @@ def main(): # On Windows we must expand the patterns ourselves. test_paths = [test for pattern in args.tests for test in glob.glob(pattern)] for test in test_paths: + argv = sys.argv[:] + args = parser.parse_args() with open(test) as f: input_lines = [l.rstrip() for l in f] @@ -93,6 +99,9 @@ def main(): if 'autogenerated' in first_line and script_name not in first_line: common.warn("Skipping test which wasn't autogenerated by " + script_name, test) continue + if first_line and 'autogenerated' in first_line: + args, argv = common.check_for_command(first_line, parser, args, argv) + test_autogenerated_note = autogenerated_note + common.get_autogennote_suffix(parser, args) if args.update_only: if not first_line or 'autogenerated' not in first_line: @@ -154,9 +163,17 @@ def main(): prefix_set = set([prefix for prefixes, _ in prefix_list for prefix in prefixes]) common.debug('Rewriting FileCheck prefixes:', str(prefix_set)) output_lines = [] - output_lines.append(autogenerated_note) + output_lines.append(test_autogenerated_note) for input_line in input_lines: + # Discard any previous script advertising. + if input_line.startswith(ADVERT): + continue + + args, argv = common.check_for_command(input_line, parser, args, argv) + if not args.enabled: + output_lines.append(input_line) + continue if is_in_function_start: if input_line == '': continue @@ -183,10 +200,6 @@ def main(): is_in_function = False continue - # Discard any previous script advertising. - if input_line.startswith(ADVERT): - continue - # If it's outside a function, it just gets copied to the output. output_lines.append(input_line) -- 2.7.4