diff options
Diffstat (limited to 'llvm/utils')
17 files changed, 428 insertions, 369 deletions
| diff --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py index 8cd200c9..b6b80ea 100644 --- a/llvm/utils/UpdateTestChecks/common.py +++ b/llvm/utils/UpdateTestChecks/common.py @@ -2396,244 +2396,6 @@ def add_analyze_checks(      ) -IR_FUNC_NAME_RE = re.compile( -    r"^\s*define\s+(?:internal\s+)?[^@]*@(?P<func>[A-Za-z0-9_.]+)\s*\(" -) -IR_PREFIX_DATA_RE = re.compile(r"^ *(;|$)") -MIR_FUNC_NAME_RE = re.compile(r" *name: *(?P<func>[A-Za-z0-9_.-]+)") -MIR_BODY_BEGIN_RE = re.compile(r" *body: *\|") -MIR_BASIC_BLOCK_RE = re.compile(r" *bb\.[0-9]+.*:$") -MIR_PREFIX_DATA_RE = re.compile(r"^ *(;|bb.[0-9].*: *$|[a-z]+:( |$)|$)") - - -def find_mir_functions_with_one_bb(lines, verbose=False): -    result = [] -    cur_func = None -    bbs = 0 -    for line in lines: -        m = MIR_FUNC_NAME_RE.match(line) -        if m: -            if bbs == 1: -                result.append(cur_func) -            cur_func = m.group("func") -            bbs = 0 -        m = MIR_BASIC_BLOCK_RE.match(line) -        if m: -            bbs += 1 -    if bbs == 1: -        result.append(cur_func) -    return result - - -def add_mir_checks_for_function( -    test, -    output_lines, -    run_list, -    func_dict, -    func_name, -    single_bb, -    print_fixed_stack, -    first_check_is_next, -    at_the_function_name, -): -    printed_prefixes = set() -    for run in run_list: -        for prefix in run[0]: -            if prefix in printed_prefixes: -                break -            if not func_dict[prefix][func_name]: -                continue -            if printed_prefixes: -                # Add some space between different check prefixes. -                indent = len(output_lines[-1]) - len(output_lines[-1].lstrip(" ")) -                output_lines.append(" " * indent + ";") -            printed_prefixes.add(prefix) -            add_mir_check_lines( -                test, -                output_lines, -                prefix, -                ("@" if at_the_function_name else "") + func_name, -                single_bb, -                func_dict[prefix][func_name], -                print_fixed_stack, -                first_check_is_next, -            ) -            break -        else: -            warn( -                "Found conflicting asm for function: {}".format(func_name), -                test_file=test, -            ) -    return output_lines - - -def add_mir_check_lines( -    test, -    output_lines, -    prefix, -    func_name, -    single_bb, -    func_info, -    print_fixed_stack, -    first_check_is_next, -): -    func_body = str(func_info).splitlines() -    if single_bb: -        # Don't bother checking the basic block label for a single BB -        func_body.pop(0) - -    if not func_body: -        warn( -            "Function has no instructions to check: {}".format(func_name), -            test_file=test, -        ) -        return - -    first_line = func_body[0] -    indent = len(first_line) - len(first_line.lstrip(" ")) -    # A check comment, indented the appropriate amount -    check = "{:>{}}; {}".format("", indent, prefix) - -    output_lines.append("{}-LABEL: name: {}".format(check, func_name)) - -    if print_fixed_stack: -        output_lines.append("{}: fixedStack:".format(check)) -        for stack_line in func_info.extrascrub.splitlines(): -            filecheck_directive = check + "-NEXT" -            output_lines.append("{}: {}".format(filecheck_directive, stack_line)) - -    first_check = not first_check_is_next -    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 -        filecheck_directive = check if first_check else check + "-NEXT" -        first_check = False -        check_line = "{}: {}".format(filecheck_directive, func_line[indent:]).rstrip() -        output_lines.append(check_line) - - -def should_add_mir_line_to_output(input_line, prefix_set): -    # Skip any check lines that we're handling as well as comments -    m = CHECK_RE.match(input_line) -    if (m and m.group(1) in prefix_set) or input_line.strip() == ";": -        return False -    return True - - -def add_mir_checks( -    input_lines, -    prefix_set, -    autogenerated_note, -    test, -    run_list, -    func_dict, -    print_fixed_stack, -    first_check_is_next, -    at_the_function_name, -): -    simple_functions = find_mir_functions_with_one_bb(input_lines) - -    output_lines = [] -    output_lines.append(autogenerated_note) - -    func_name = None -    state = "toplevel" -    for input_line in input_lines: -        if input_line == autogenerated_note: -            continue - -        if state == "toplevel": -            m = IR_FUNC_NAME_RE.match(input_line) -            if m: -                state = "ir function prefix" -                func_name = m.group("func") -            if input_line.rstrip("| \r\n") == "---": -                state = "document" -            output_lines.append(input_line) -        elif state == "document": -            m = MIR_FUNC_NAME_RE.match(input_line) -            if m: -                state = "mir function metadata" -                func_name = m.group("func") -            if input_line.strip() == "...": -                state = "toplevel" -                func_name = None -            if should_add_mir_line_to_output(input_line, prefix_set): -                output_lines.append(input_line) -        elif state == "mir function metadata": -            if should_add_mir_line_to_output(input_line, prefix_set): -                output_lines.append(input_line) -            m = MIR_BODY_BEGIN_RE.match(input_line) -            if m: -                if func_name in simple_functions: -                    # If there's only one block, put the checks inside it -                    state = "mir function prefix" -                    continue -                state = "mir function body" -                add_mir_checks_for_function( -                    test, -                    output_lines, -                    run_list, -                    func_dict, -                    func_name, -                    single_bb=False, -                    print_fixed_stack=print_fixed_stack, -                    first_check_is_next=first_check_is_next, -                    at_the_function_name=at_the_function_name, -                ) -        elif state == "mir function prefix": -            m = MIR_PREFIX_DATA_RE.match(input_line) -            if not m: -                state = "mir function body" -                add_mir_checks_for_function( -                    test, -                    output_lines, -                    run_list, -                    func_dict, -                    func_name, -                    single_bb=True, -                    print_fixed_stack=print_fixed_stack, -                    first_check_is_next=first_check_is_next, -                    at_the_function_name=at_the_function_name, -                ) - -            if should_add_mir_line_to_output(input_line, prefix_set): -                output_lines.append(input_line) -        elif state == "mir function body": -            if input_line.strip() == "...": -                state = "toplevel" -                func_name = None -            if should_add_mir_line_to_output(input_line, prefix_set): -                output_lines.append(input_line) -        elif state == "ir function prefix": -            m = IR_PREFIX_DATA_RE.match(input_line) -            if not m: -                state = "ir function body" -                add_mir_checks_for_function( -                    test, -                    output_lines, -                    run_list, -                    func_dict, -                    func_name, -                    single_bb=False, -                    print_fixed_stack=print_fixed_stack, -                    first_check_is_next=first_check_is_next, -                    at_the_function_name=at_the_function_name, -                ) - -            if should_add_mir_line_to_output(input_line, prefix_set): -                output_lines.append(input_line) -        elif state == "ir function body": -            if input_line.strip() == "}": -                state = "toplevel" -                func_name = None -            if should_add_mir_line_to_output(input_line, prefix_set): -                output_lines.append(input_line) -    return output_lines - -  def build_global_values_dictionary(glob_val_dict, raw_tool_output, prefixes, ginfo):      for nameless_value in ginfo.get_nameless_values():          if nameless_value.global_ir_rhs_regexp is None: diff --git a/llvm/utils/UpdateTestChecks/mir.py b/llvm/utils/UpdateTestChecks/mir.py new file mode 100644 index 0000000..24bb8b3 --- /dev/null +++ b/llvm/utils/UpdateTestChecks/mir.py @@ -0,0 +1,362 @@ +"""MIR test utility functions for UpdateTestChecks scripts.""" + +import re +import sys +from UpdateTestChecks import common +from UpdateTestChecks.common import ( +    CHECK_RE, +    warn, +) + +IR_FUNC_NAME_RE = re.compile( +    r"^\s*define\s+(?:internal\s+)?[^@]*@(?P<func>[A-Za-z0-9_.]+)\s*\(" +) +IR_PREFIX_DATA_RE = re.compile(r"^ *(;|$)") +MIR_FUNC_NAME_RE = re.compile(r" *name: *(?P<func>[A-Za-z0-9_.-]+)") +MIR_BODY_BEGIN_RE = re.compile(r" *body: *\|") +MIR_BASIC_BLOCK_RE = re.compile(r" *bb\.[0-9]+.*:$") +MIR_PREFIX_DATA_RE = re.compile(r"^ *(;|bb.[0-9].*: *$|[a-z]+:( |$)|$)") + +VREG_RE = re.compile(r"(%[0-9]+)(?:\.[a-z0-9_]+)?(?::[a-z0-9_]+)?(?:\([<>a-z0-9 ]+\))?") +MI_FLAGS_STR = ( +    r"(frame-setup |frame-destroy |nnan |ninf |nsz |arcp |contract |afn " +    r"|reassoc |nuw |nsw |exact |nofpexcept |nomerge |unpredictable " +    r"|noconvergent |nneg |disjoint |nusw |samesign |inbounds )*" +) +VREG_DEF_FLAGS_STR = r"(?:dead |undef )*" + +# Pattern to match the defined vregs and the opcode of an instruction that +# defines vregs. Opcodes starting with a lower-case 't' are allowed to match +# ARM's thumb instructions, like tADDi8 and t2ADDri. +VREG_DEF_RE = re.compile( +    r"^ *(?P<vregs>{2}{0}(?:, {2}{0})*) = " +    r"{1}(?P<opcode>[A-Zt][A-Za-z0-9_]+)".format( +        VREG_RE.pattern, MI_FLAGS_STR, VREG_DEF_FLAGS_STR +    ) +) + +MIR_FUNC_RE = re.compile( +    r"^---$" +    r"\n" +    r"^ *name: *(?P<func>[A-Za-z0-9_.-]+)$" +    r".*?" +    r"(?:^ *fixedStack: *(\[\])? *\n" +    r"(?P<fixedStack>.*?)\n?" +    r"^ *stack:" +    r".*?)?" +    r"^ *body: *\|\n" +    r"(?P<body>.*?)\n" +    r"^\.\.\.$", +    flags=(re.M | re.S), +) + + +def build_function_info_dictionary( +    test, raw_tool_output, triple, prefixes, func_dict, verbose +): +    for m in MIR_FUNC_RE.finditer(raw_tool_output): +        func = m.group("func") +        fixedStack = m.group("fixedStack") +        body = m.group("body") +        if verbose: +            print("Processing function: {}".format(func), file=sys.stderr) +            for l in body.splitlines(): +                print("  {}".format(l), file=sys.stderr) + +        # 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")): +                    if vreg.group(1) in vreg_map: +                        name = vreg_map[vreg.group(1)] +                    else: +                        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: +            info = common.function_body( +                body, fixedStack, None, None, None, None, ginfo=None +            ) +            if func in func_dict[prefix]: +                if ( +                    not func_dict[prefix][func] +                    or func_dict[prefix][func].scrub != info.scrub +                    or func_dict[prefix][func].extrascrub != info.extrascrub +                ): +                    func_dict[prefix][func] = None +            else: +                func_dict[prefix][func] = info + + +def mangle_vreg(opcode, current_names): +    base = opcode +    # Simplify some common prefixes and suffixes +    if opcode.startswith("G_"): +        base = base[len("G_") :] +    if opcode.endswith("_PSEUDO"): +        base = base[: len("_PSEUDO")] +    # Shorten some common opcodes with long-ish names +    base = dict( +        IMPLICIT_DEF="DEF", +        GLOBAL_VALUE="GV", +        CONSTANT="C", +        FCONSTANT="C", +        MERGE_VALUES="MV", +        UNMERGE_VALUES="UV", +        INTRINSIC="INT", +        INTRINSIC_W_SIDE_EFFECTS="INT", +        INSERT_VECTOR_ELT="IVEC", +        EXTRACT_VECTOR_ELT="EVEC", +        SHUFFLE_VECTOR="SHUF", +    ).get(base, base) +    # Avoid ambiguity when opcodes end in numbers +    if len(base.rstrip("0123456789")) < len(base): +        base += "_" + +    i = 0 +    for name in current_names: +        if name.rstrip("0123456789") == base: +            i += 1 +    if i: +        return "{}{}".format(base, i) +    return base + + +def find_mir_functions_with_one_bb(lines, verbose=False): +    result = [] +    cur_func = None +    bbs = 0 +    for line in lines: +        m = MIR_FUNC_NAME_RE.match(line) +        if m: +            if bbs == 1: +                result.append(cur_func) +            cur_func = m.group("func") +            bbs = 0 +        m = MIR_BASIC_BLOCK_RE.match(line) +        if m: +            bbs += 1 +    if bbs == 1: +        result.append(cur_func) +    return result + + +def add_mir_checks_for_function( +    test, +    output_lines, +    run_list, +    func_dict, +    func_name, +    single_bb, +    print_fixed_stack, +    first_check_is_next, +    at_the_function_name, +): +    printed_prefixes = set() +    for run in run_list: +        for prefix in run[0]: +            if prefix in printed_prefixes: +                break +            if not func_dict[prefix][func_name]: +                continue +            if printed_prefixes: +                # Add some space between different check prefixes. +                indent = len(output_lines[-1]) - len(output_lines[-1].lstrip(" ")) +                output_lines.append(" " * indent + ";") +            printed_prefixes.add(prefix) +            add_mir_check_lines( +                test, +                output_lines, +                prefix, +                ("@" if at_the_function_name else "") + func_name, +                single_bb, +                func_dict[prefix][func_name], +                print_fixed_stack, +                first_check_is_next, +            ) +            break +        else: +            warn( +                "Found conflicting asm for function: {}".format(func_name), +                test_file=test, +            ) +    return output_lines + + +def add_mir_check_lines( +    test, +    output_lines, +    prefix, +    func_name, +    single_bb, +    func_info, +    print_fixed_stack, +    first_check_is_next, +): +    func_body = str(func_info).splitlines() +    if single_bb: +        # Don't bother checking the basic block label for a single BB +        func_body.pop(0) + +    if not func_body: +        warn( +            "Function has no instructions to check: {}".format(func_name), +            test_file=test, +        ) +        return + +    first_line = func_body[0] +    indent = len(first_line) - len(first_line.lstrip(" ")) +    # A check comment, indented the appropriate amount +    check = "{:>{}}; {}".format("", indent, prefix) + +    output_lines.append("{}-LABEL: name: {}".format(check, func_name)) + +    if print_fixed_stack: +        output_lines.append("{}: fixedStack:".format(check)) +        for stack_line in func_info.extrascrub.splitlines(): +            filecheck_directive = check + "-NEXT" +            output_lines.append("{}: {}".format(filecheck_directive, stack_line)) + +    first_check = not first_check_is_next +    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 +        filecheck_directive = check if first_check else check + "-NEXT" +        first_check = False +        check_line = "{}: {}".format(filecheck_directive, func_line[indent:]).rstrip() +        output_lines.append(check_line) + + +def should_add_mir_line_to_output(input_line, prefix_set): +    # Skip any check lines that we're handling as well as comments +    m = CHECK_RE.match(input_line) +    if (m and m.group(1) in prefix_set) or input_line.strip() == ";": +        return False +    return True + + +def add_mir_checks( +    input_lines, +    prefix_set, +    autogenerated_note, +    test, +    run_list, +    func_dict, +    print_fixed_stack, +    first_check_is_next, +    at_the_function_name, +): +    simple_functions = find_mir_functions_with_one_bb(input_lines) + +    output_lines = [] +    output_lines.append(autogenerated_note) + +    func_name = None +    state = "toplevel" +    for input_line in input_lines: +        if input_line == autogenerated_note: +            continue + +        if state == "toplevel": +            m = IR_FUNC_NAME_RE.match(input_line) +            if m: +                state = "ir function prefix" +                func_name = m.group("func") +            if input_line.rstrip("| \r\n") == "---": +                state = "document" +            output_lines.append(input_line) +        elif state == "document": +            m = MIR_FUNC_NAME_RE.match(input_line) +            if m: +                state = "mir function metadata" +                func_name = m.group("func") +            if input_line.strip() == "...": +                state = "toplevel" +                func_name = None +            if should_add_mir_line_to_output(input_line, prefix_set): +                output_lines.append(input_line) +        elif state == "mir function metadata": +            if should_add_mir_line_to_output(input_line, prefix_set): +                output_lines.append(input_line) +            m = MIR_BODY_BEGIN_RE.match(input_line) +            if m: +                if func_name in simple_functions: +                    # If there's only one block, put the checks inside it +                    state = "mir function prefix" +                    continue +                state = "mir function body" +                add_mir_checks_for_function( +                    test, +                    output_lines, +                    run_list, +                    func_dict, +                    func_name, +                    single_bb=False, +                    print_fixed_stack=print_fixed_stack, +                    first_check_is_next=first_check_is_next, +                    at_the_function_name=at_the_function_name, +                ) +        elif state == "mir function prefix": +            m = MIR_PREFIX_DATA_RE.match(input_line) +            if not m: +                state = "mir function body" +                add_mir_checks_for_function( +                    test, +                    output_lines, +                    run_list, +                    func_dict, +                    func_name, +                    single_bb=True, +                    print_fixed_stack=print_fixed_stack, +                    first_check_is_next=first_check_is_next, +                    at_the_function_name=at_the_function_name, +                ) + +            if should_add_mir_line_to_output(input_line, prefix_set): +                output_lines.append(input_line) +        elif state == "mir function body": +            if input_line.strip() == "...": +                state = "toplevel" +                func_name = None +            if should_add_mir_line_to_output(input_line, prefix_set): +                output_lines.append(input_line) +        elif state == "ir function prefix": +            m = IR_PREFIX_DATA_RE.match(input_line) +            if not m: +                state = "ir function body" +                add_mir_checks_for_function( +                    test, +                    output_lines, +                    run_list, +                    func_dict, +                    func_name, +                    single_bb=False, +                    print_fixed_stack=print_fixed_stack, +                    first_check_is_next=first_check_is_next, +                    at_the_function_name=at_the_function_name, +                ) + +            if should_add_mir_line_to_output(input_line, prefix_set): +                output_lines.append(input_line) +        elif state == "ir function body": +            if input_line.strip() == "}": +                state = "toplevel" +                func_name = None +            if should_add_mir_line_to_output(input_line, prefix_set): +                output_lines.append(input_line) +    return output_lines diff --git a/llvm/utils/git/code-format-helper.py b/llvm/utils/git/code-format-helper.py index dff7f78..f6b28f4 100755 --- a/llvm/utils/git/code-format-helper.py +++ b/llvm/utils/git/code-format-helper.py @@ -486,8 +486,6 @@ def hook_main():          if fmt.has_tool():              if not fmt.run(args.changed_files, args):                  failed_fmts.append(fmt.name) -            if fmt.comment: -                comments.append(fmt.comment)          else:              print(f"Couldn't find {fmt.name}, can't check " + fmt.friendly_name.lower()) diff --git a/llvm/utils/lit/lit/TestRunner.py b/llvm/utils/lit/lit/TestRunner.py index 9fba96a..3176b1a 100644 --- a/llvm/utils/lit/lit/TestRunner.py +++ b/llvm/utils/lit/lit/TestRunner.py @@ -600,18 +600,33 @@ def executeBuiltinUmask(cmd, shenv):  def executeBuiltinUlimit(cmd, shenv):      """executeBuiltinUlimit - Change the current limits.""" -    if os.name != "posix": +    try: +        # Try importing the resource module (available on POSIX systems) and +        # emit an error where it does not exist (e.g., Windows). +        import resource +    except ImportError:          raise InternalShellError(cmd, "'ulimit' not supported on this system")      if len(cmd.args) != 3:          raise InternalShellError(cmd, "'ulimit' requires two arguments")      try: -        new_limit = int(cmd.args[2]) +        if cmd.args[2] == "unlimited": +            new_limit = resource.RLIM_INFINITY +        else: +            new_limit = int(cmd.args[2])      except ValueError as err:          raise InternalShellError(cmd, "Error: 'ulimit': %s" % str(err))      if cmd.args[1] == "-v": -        shenv.ulimit["RLIMIT_AS"] = new_limit * 1024 +        if new_limit != resource.RLIM_INFINITY: +            new_limit = new_limit * 1024 +        shenv.ulimit["RLIMIT_AS"] = new_limit      elif cmd.args[1] == "-n":          shenv.ulimit["RLIMIT_NOFILE"] = new_limit +    elif cmd.args[1] == "-s": +        if new_limit != resource.RLIM_INFINITY: +            new_limit = new_limit * 1024 +        shenv.ulimit["RLIMIT_STACK"] = new_limit +    elif cmd.args[1] == "-f": +        shenv.ulimit["RLIMIT_FSIZE"] = new_limit      else:          raise InternalShellError(              cmd, "'ulimit' does not support option: %s" % cmd.args[1] @@ -811,6 +826,10 @@ def _executeShCmd(cmd, shenv, results, timeoutHelper):          not_args = []          not_count = 0          not_crash = False + +        # Expand all late substitutions. +        args = _expandLateSubstitutions(j, args, cmd_shenv.cwd) +          while True:              if args[0] == "env":                  # Create a copy of the global environment and modify it for @@ -860,9 +879,6 @@ def _executeShCmd(cmd, shenv, results, timeoutHelper):          # Ensure args[0] is hashable.          args[0] = expand_glob(args[0], cmd_shenv.cwd)[0] -        # Expand all late substitutions. -        args = _expandLateSubstitutions(j, args, cmd_shenv.cwd) -          inproc_builtin = inproc_builtins.get(args[0], None)          if inproc_builtin and (args[0] != "echo" or len(cmd.commands) == 1):              # env calling an in-process builtin is useless, so we take the safe diff --git a/llvm/utils/lit/lit/builtin_commands/_launch_with_limit.py b/llvm/utils/lit/lit/builtin_commands/_launch_with_limit.py index 33d2d59..a9dc259 100644 --- a/llvm/utils/lit/lit/builtin_commands/_launch_with_limit.py +++ b/llvm/utils/lit/lit/builtin_commands/_launch_with_limit.py @@ -17,6 +17,10 @@ def main(argv):                  resource.setrlimit(resource.RLIMIT_AS, limit)              elif limit_str == "RLIMIT_NOFILE":                  resource.setrlimit(resource.RLIMIT_NOFILE, limit) +            elif limit_str == "RLIMIT_STACK": +                resource.setrlimit(resource.RLIMIT_STACK, limit) +            elif limit_str == "RLIMIT_FSIZE": +                resource.setrlimit(resource.RLIMIT_FSIZE, limit)      process_output = subprocess.run(command_args)      sys.exit(process_output.returncode) diff --git a/llvm/utils/lit/tests/Inputs/shtest-readfile/env.txt b/llvm/utils/lit/tests/Inputs/shtest-readfile/env.txt new file mode 100644 index 0000000..3e19373 --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/shtest-readfile/env.txt @@ -0,0 +1,6 @@ +## Tests that readfile works with the env builtin. +# RUN: echo -n "hello" > %t.1 +# RUN: env TEST=%{readfile:%t.1} %{python} -c "import os; print(os.environ['TEST'])" + +## Fail the test so we can assert on the output. +# RUN: not echo return
\ No newline at end of file diff --git a/llvm/utils/lit/tests/Inputs/shtest-readfile/lit.cfg b/llvm/utils/lit/tests/Inputs/shtest-readfile/lit.cfg index ee49667..80af27f 100644 --- a/llvm/utils/lit/tests/Inputs/shtest-readfile/lit.cfg +++ b/llvm/utils/lit/tests/Inputs/shtest-readfile/lit.cfg @@ -10,6 +10,7 @@ use_lit_shell = lit.util.pythonize_bool(lit_shell_env)  config.test_format = lit.formats.ShTest(execute_external=not use_lit_shell)  config.test_source_root = None  config.test_exec_root = None +config.substitutions.append(("%{python}", '"%s"' % (sys.executable)))  # If we are testing with the external shell, remove the fake-externals from  # PATH so that we use mkdir in the tests. diff --git a/llvm/utils/lit/tests/Inputs/shtest-ulimit-nondarwin/ulimit_okay.txt b/llvm/utils/lit/tests/Inputs/shtest-ulimit-nondarwin/ulimit_okay.txt index dbdd003..a5fac7b 100644 --- a/llvm/utils/lit/tests/Inputs/shtest-ulimit-nondarwin/ulimit_okay.txt +++ b/llvm/utils/lit/tests/Inputs/shtest-ulimit-nondarwin/ulimit_okay.txt @@ -1,4 +1,5 @@  # RUN: ulimit -v 1048576 +# RUN: ulimit -s 256  # RUN: %{python} %S/../shtest-ulimit/print_limits.py  # Fail the test so that we can assert on the output.  # RUN: not echo return diff --git a/llvm/utils/lit/tests/Inputs/shtest-ulimit-nondarwin/ulimit_unlimited.txt b/llvm/utils/lit/tests/Inputs/shtest-ulimit-nondarwin/ulimit_unlimited.txt new file mode 100644 index 0000000..4c687e3 --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/shtest-ulimit-nondarwin/ulimit_unlimited.txt @@ -0,0 +1,6 @@ +# RUN: ulimit -f 5 +# RUN: %{python} %S/../shtest-ulimit/print_limits.py +# RUN: ulimit -f unlimited +# RUN: %{python} %S/../shtest-ulimit/print_limits.py +# Fail the test so that we can assert on the output. +# RUN: not echo return diff --git a/llvm/utils/lit/tests/Inputs/shtest-ulimit/print_limits.py b/llvm/utils/lit/tests/Inputs/shtest-ulimit/print_limits.py index 632f954..c732c04 100644 --- a/llvm/utils/lit/tests/Inputs/shtest-ulimit/print_limits.py +++ b/llvm/utils/lit/tests/Inputs/shtest-ulimit/print_limits.py @@ -2,3 +2,5 @@ import resource  print("RLIMIT_AS=" + str(resource.getrlimit(resource.RLIMIT_AS)[0]))  print("RLIMIT_NOFILE=" + str(resource.getrlimit(resource.RLIMIT_NOFILE)[0])) +print("RLIMIT_STACK=" + str(resource.getrlimit(resource.RLIMIT_STACK)[0])) +print("RLIMIT_FSIZE=" + str(resource.getrlimit(resource.RLIMIT_FSIZE)[0])) diff --git a/llvm/utils/lit/tests/Inputs/shtest-ulimit/ulimit_okay.txt b/llvm/utils/lit/tests/Inputs/shtest-ulimit/ulimit_okay.txt index 4edf1c3..b1f2396b 100644 --- a/llvm/utils/lit/tests/Inputs/shtest-ulimit/ulimit_okay.txt +++ b/llvm/utils/lit/tests/Inputs/shtest-ulimit/ulimit_okay.txt @@ -1,4 +1,5 @@  # RUN: ulimit -n 50 +# RUN: ulimit -f 5  # RUN: %{python} %S/print_limits.py  # Fail the test so that we can assert on the output.  # RUN: not echo return diff --git a/llvm/utils/lit/tests/shtest-readfile-external.py b/llvm/utils/lit/tests/shtest-readfile-external.py index c00bff4..6fe1088 100644 --- a/llvm/utils/lit/tests/shtest-readfile-external.py +++ b/llvm/utils/lit/tests/shtest-readfile-external.py @@ -6,7 +6,7 @@  # UNSUPPORTED: system-windows  # RUN: env LIT_USE_INTERNAL_SHELL=0 not %{lit} -a -v %{inputs}/shtest-readfile | FileCheck -match-full-lines -DTEMP_PATH=%S/Inputs/shtest-readfile/Output %s -# CHECK: -- Testing: 4 tests{{.*}} +# CHECK: -- Testing: 5 tests{{.*}}  # CHECK-LABEL: FAIL: shtest-readfile :: absolute-paths.txt ({{[^)]*}})  # CHECK: echo $(cat [[TEMP_PATH]]/absolute-paths.txt.tmp) && test -e [[TEMP_PATH]]/absolute-paths.txt.tmp {{.*}} diff --git a/llvm/utils/lit/tests/shtest-readfile.py b/llvm/utils/lit/tests/shtest-readfile.py index 66e3a04..218da22 100644 --- a/llvm/utils/lit/tests/shtest-readfile.py +++ b/llvm/utils/lit/tests/shtest-readfile.py @@ -5,12 +5,16 @@  # RUN: env LIT_USE_INTERNAL_SHELL=1  not %{lit} -a -v %{inputs}/shtest-readfile | FileCheck -match-full-lines -DTEMP_PATH=%S%{fs-sep}Inputs%{fs-sep}shtest-readfile%{fs-sep}Output %s -# CHECK: -- Testing: 4 tests{{.*}} +# CHECK: -- Testing: 5 tests{{.*}}  # CHECK-LABEL: FAIL: shtest-readfile :: absolute-paths.txt ({{[^)]*}})  # CHECK: echo hello  # CHECK: # executed command: echo '%{readfile:[[TEMP_PATH]]{{[\\\/]}}absolute-paths.txt.tmp}' +# CHECK-LABEL: FAIL: shtest-readfile :: env.txt ({{[^)]*}}) +# CHECK: env TEST=hello {{.*}} -c "import os; print(os.environ['TEST'])" +# CHECK: # | hello +  # CHECK-LABEL: FAIL: shtest-readfile :: file-does-not-exist.txt ({{[^)]*}})  # CHECK: # executed command: @echo 'echo %{readfile:/file/does/not/exist}'  # CHECK: # | File specified in readfile substitution does not exist: {{.*}}/file/does/not/exist diff --git a/llvm/utils/lit/tests/shtest-ulimit-nondarwin.py b/llvm/utils/lit/tests/shtest-ulimit-nondarwin.py index 2d96fea..286fd3d 100644 --- a/llvm/utils/lit/tests/shtest-ulimit-nondarwin.py +++ b/llvm/utils/lit/tests/shtest-ulimit-nondarwin.py @@ -2,12 +2,20 @@  # ulimit does not work on non-POSIX platforms.  # These tests are specific to options that Darwin does not support. -# UNSUPPORTED: system-windows, system-darwin, system-aix +# UNSUPPORTED: system-windows, system-darwin, system-aix, system-solaris  # RUN: not %{lit} -a -v %{inputs}/shtest-ulimit-nondarwin | FileCheck %s -# CHECK: -- Testing: 1 tests{{.*}} +# CHECK: -- Testing: 2 tests{{.*}}  # CHECK-LABEL: FAIL: shtest-ulimit :: ulimit_okay.txt ({{[^)]*}})  # CHECK: ulimit -v 1048576 +# CHECK: ulimit -s 256  # CHECK: RLIMIT_AS=1073741824 +# CHECK: RLIMIT_STACK=262144 + +# CHECK-LABEL: FAIL: shtest-ulimit :: ulimit_unlimited.txt ({{[^)]*}}) +# CHECK: ulimit -f 5 +# CHECK: RLIMIT_FSIZE=5 +# CHECK: ulimit -f unlimited +# CHECK: RLIMIT_FSIZE=-1 diff --git a/llvm/utils/lit/tests/shtest-ulimit.py b/llvm/utils/lit/tests/shtest-ulimit.py index 09cd475..21e5a5e 100644 --- a/llvm/utils/lit/tests/shtest-ulimit.py +++ b/llvm/utils/lit/tests/shtest-ulimit.py @@ -19,7 +19,9 @@  # CHECK-LABEL: FAIL: shtest-ulimit :: ulimit_okay.txt ({{[^)]*}})  # CHECK: ulimit -n 50 +# CHECK: ulimit -f 5  # CHECK: RLIMIT_NOFILE=50 +# CHECK: RLIMIT_FSIZE=5  # CHECK-LABEL: FAIL: shtest-ulimit :: ulimit_reset.txt ({{[^)]*}})  # CHECK: RLIMIT_NOFILE=[[BASE_NOFILE_LIMIT]] diff --git a/llvm/utils/update_givaluetracking_test_checks.py b/llvm/utils/update_givaluetracking_test_checks.py index 49b068a..9ad0f3e 100755 --- a/llvm/utils/update_givaluetracking_test_checks.py +++ b/llvm/utils/update_givaluetracking_test_checks.py @@ -19,6 +19,7 @@ import re  import sys  from UpdateTestChecks import common +from UpdateTestChecks import mir  VT_FUNCTION_RE = re.compile(      r"\s*name:\s*@(?P<func>[A-Za-z0-9_-]+)" @@ -92,7 +93,7 @@ def update_test(ti: common.TestInfo):      func_dict = builder.finish_and_get_func_dict()      prefix_set = set([prefix for p in run_list for prefix in p[0]])      common.debug("Rewriting FileCheck prefixes:", str(prefix_set)) -    output_lines = common.add_mir_checks( +    output_lines = mir.add_mir_checks(          ti.input_lines,          prefix_set,          ti.test_autogenerated_note, diff --git a/llvm/utils/update_mir_test_checks.py b/llvm/utils/update_mir_test_checks.py index c4ee052..ba70249 100755 --- a/llvm/utils/update_mir_test_checks.py +++ b/llvm/utils/update_mir_test_checks.py @@ -31,39 +31,7 @@ import subprocess  import sys  from UpdateTestChecks import common - -VREG_RE = re.compile(r"(%[0-9]+)(?:\.[a-z0-9_]+)?(?::[a-z0-9_]+)?(?:\([<>a-z0-9 ]+\))?") -MI_FLAGS_STR = ( -    r"(frame-setup |frame-destroy |nnan |ninf |nsz |arcp |contract |afn " -    r"|reassoc |nuw |nsw |exact |nofpexcept |nomerge |unpredictable " -    r"|noconvergent |nneg |disjoint |nusw |samesign |inbounds )*" -) -VREG_DEF_FLAGS_STR = r"(?:dead |undef )*" - -# Pattern to match the defined vregs and the opcode of an instruction that -# defines vregs. Opcodes starting with a lower-case 't' are allowed to match -# ARM's thumb instructions, like tADDi8 and t2ADDri. -VREG_DEF_RE = re.compile( -    r"^ *(?P<vregs>{2}{0}(?:, {2}{0})*) = " -    r"{1}(?P<opcode>[A-Zt][A-Za-z0-9_]+)".format( -        VREG_RE.pattern, MI_FLAGS_STR, VREG_DEF_FLAGS_STR -    ) -) - -MIR_FUNC_RE = re.compile( -    r"^---$" -    r"\n" -    r"^ *name: *(?P<func>[A-Za-z0-9_.-]+)$" -    r".*?" -    r"(?:^ *fixedStack: *(\[\])? *\n" -    r"(?P<fixedStack>.*?)\n?" -    r"^ *stack:" -    r".*?)?" -    r"^ *body: *\|\n" -    r"(?P<body>.*?)\n" -    r"^\.\.\.$", -    flags=(re.M | re.S), -) +from UpdateTestChecks import mir  class LLC: @@ -143,89 +111,6 @@ def build_run_list(test, run_lines, verbose=False):      return run_list -def build_function_info_dictionary( -    test, raw_tool_output, triple, prefixes, func_dict, verbose -): -    for m in MIR_FUNC_RE.finditer(raw_tool_output): -        func = m.group("func") -        fixedStack = m.group("fixedStack") -        body = m.group("body") -        if verbose: -            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")): -                    if vreg.group(1) in vreg_map: -                        name = vreg_map[vreg.group(1)] -                    else: -                        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: -            info = common.function_body( -                body, fixedStack, None, None, None, None, ginfo=None -            ) -            if func in func_dict[prefix]: -                if ( -                    not func_dict[prefix][func] -                    or func_dict[prefix][func].scrub != info.scrub -                    or func_dict[prefix][func].extrascrub != info.extrascrub -                ): -                    func_dict[prefix][func] = None -            else: -                func_dict[prefix][func] = info - - -def mangle_vreg(opcode, current_names): -    base = opcode -    # Simplify some common prefixes and suffixes -    if opcode.startswith("G_"): -        base = base[len("G_") :] -    if opcode.endswith("_PSEUDO"): -        base = base[: len("_PSEUDO")] -    # Shorten some common opcodes with long-ish names -    base = dict( -        IMPLICIT_DEF="DEF", -        GLOBAL_VALUE="GV", -        CONSTANT="C", -        FCONSTANT="C", -        MERGE_VALUES="MV", -        UNMERGE_VALUES="UV", -        INTRINSIC="INT", -        INTRINSIC_W_SIDE_EFFECTS="INT", -        INSERT_VECTOR_ELT="IVEC", -        EXTRACT_VECTOR_ELT="EVEC", -        SHUFFLE_VECTOR="SHUF", -    ).get(base, base) -    # Avoid ambiguity when opcodes end in numbers -    if len(base.rstrip("0123456789")) < len(base): -        base += "_" - -    i = 0 -    for name in current_names: -        if name.rstrip("0123456789") == base: -            i += 1 -    if i: -        return "{}{}".format(base, i) -    return base - -  def update_test_file(args, test, autogenerated_note):      with open(test) as fd:          input_lines = [l.rstrip() for l in fd] @@ -247,7 +132,7 @@ def update_test_file(args, test, autogenerated_note):              common.warn("No triple found: skipping file", test_file=test)              return -        build_function_info_dictionary( +        mir.build_function_info_dictionary(              test,              raw_tool_output,              triple_in_cmd or triple_in_ir, @@ -259,7 +144,7 @@ def update_test_file(args, test, autogenerated_note):      prefix_set = set([prefix for run in run_list for prefix in run[0]])      log("Rewriting FileCheck prefixes: {}".format(prefix_set), args.verbose) -    output_lines = common.add_mir_checks( +    output_lines = mir.add_mir_checks(          input_lines,          prefix_set,          autogenerated_note, | 
