11b55f1f8SVolkan Keles#!/usr/bin/env python 21b55f1f8SVolkan Keles 31b55f1f8SVolkan Keles"""Reduces GlobalISel failures. 41b55f1f8SVolkan Keles 51b55f1f8SVolkan KelesThis script is a utility to reduce tests that GlobalISel 61b55f1f8SVolkan Kelesfails to compile. 71b55f1f8SVolkan Keles 81b55f1f8SVolkan KelesIt runs llc to get the error message using a regex and creates 91b55f1f8SVolkan Kelesa custom command to check that specific error. Then, it runs bugpoint 101b55f1f8SVolkan Keleswith the custom command. 111b55f1f8SVolkan Keles 121b55f1f8SVolkan Keles""" 131b55f1f8SVolkan Kelesfrom __future__ import print_function 141b55f1f8SVolkan Kelesimport argparse 151b55f1f8SVolkan Kelesimport re 161b55f1f8SVolkan Kelesimport subprocess 171b55f1f8SVolkan Kelesimport sys 181b55f1f8SVolkan Kelesimport tempfile 191b55f1f8SVolkan Kelesimport os 201b55f1f8SVolkan Keles 211b55f1f8SVolkan Keles 221b55f1f8SVolkan Kelesdef log(msg): 231b55f1f8SVolkan Keles print(msg) 241b55f1f8SVolkan Keles 251b55f1f8SVolkan Keles 261b55f1f8SVolkan Kelesdef hr(): 27*b71edfaaSTobias Hieta log("-" * 50) 281b55f1f8SVolkan Keles 291b55f1f8SVolkan Keles 301b55f1f8SVolkan Kelesdef log_err(msg): 31*b71edfaaSTobias Hieta print("ERROR: {}".format(msg), file=sys.stderr) 321b55f1f8SVolkan Keles 331b55f1f8SVolkan Keles 341b55f1f8SVolkan Kelesdef check_path(path): 351b55f1f8SVolkan Keles if not os.path.exists(path): 36*b71edfaaSTobias Hieta log_err("{} does not exist.".format(path)) 371b55f1f8SVolkan Keles raise 381b55f1f8SVolkan Keles return path 391b55f1f8SVolkan Keles 401b55f1f8SVolkan Keles 411b55f1f8SVolkan Kelesdef check_bin(build_dir, bin_name): 42*b71edfaaSTobias Hieta file_name = "{}/bin/{}".format(build_dir, bin_name) 431b55f1f8SVolkan Keles return check_path(file_name) 441b55f1f8SVolkan Keles 451b55f1f8SVolkan Keles 461b55f1f8SVolkan Kelesdef run_llc(llc, irfile): 47*b71edfaaSTobias Hieta pr = subprocess.Popen( 48*b71edfaaSTobias Hieta [llc, "-o", "-", "-global-isel", "-pass-remarks-missed=gisel", irfile], 491b55f1f8SVolkan Keles stdout=subprocess.PIPE, 50*b71edfaaSTobias Hieta stderr=subprocess.PIPE, 51*b71edfaaSTobias Hieta ) 521b55f1f8SVolkan Keles out, err = pr.communicate() 531b55f1f8SVolkan Keles res = pr.wait() 541b55f1f8SVolkan Keles if res == 0: 551b55f1f8SVolkan Keles return 0 561b55f1f8SVolkan Keles re_err = re.compile( 57*b71edfaaSTobias Hieta r"LLVM ERROR: ([a-z\s]+):.*(G_INTRINSIC[_A-Z]* <intrinsic:@[a-zA-Z0-9\.]+>|G_[A-Z_]+)" 58*b71edfaaSTobias Hieta ) 591b55f1f8SVolkan Keles match = re_err.match(err) 601b55f1f8SVolkan Keles if not match: 611b55f1f8SVolkan Keles return 0 621b55f1f8SVolkan Keles else: 631b55f1f8SVolkan Keles return [match.group(1), match.group(2)] 641b55f1f8SVolkan Keles 651b55f1f8SVolkan Keles 661b55f1f8SVolkan Kelesdef run_bugpoint(bugpoint_bin, llc_bin, opt_bin, tmp, ir_file): 67*b71edfaaSTobias Hieta compileCmd = "-compile-command={} -c {} {}".format( 68*b71edfaaSTobias Hieta os.path.realpath(__file__), llc_bin, tmp 69*b71edfaaSTobias Hieta ) 70*b71edfaaSTobias Hieta pr = subprocess.Popen( 71*b71edfaaSTobias Hieta [ 72*b71edfaaSTobias Hieta bugpoint_bin, 73*b71edfaaSTobias Hieta "-compile-custom", 741b55f1f8SVolkan Keles compileCmd, 75*b71edfaaSTobias Hieta "-opt-command={}".format(opt_bin), 76*b71edfaaSTobias Hieta ir_file, 77*b71edfaaSTobias Hieta ] 78*b71edfaaSTobias Hieta ) 791b55f1f8SVolkan Keles res = pr.wait() 801b55f1f8SVolkan Keles if res != 0: 811b55f1f8SVolkan Keles log_err("Unable to reduce the test.") 821b55f1f8SVolkan Keles raise 831b55f1f8SVolkan Keles 841b55f1f8SVolkan Keles 851b55f1f8SVolkan Kelesdef run_bugpoint_check(): 861b55f1f8SVolkan Keles path_to_llc = sys.argv[2] 871b55f1f8SVolkan Keles path_to_err = sys.argv[3] 881b55f1f8SVolkan Keles path_to_ir = sys.argv[4] 89*b71edfaaSTobias Hieta with open(path_to_err, "r") as f: 901b55f1f8SVolkan Keles err = f.read() 911b55f1f8SVolkan Keles res = run_llc(path_to_llc, path_to_ir) 921b55f1f8SVolkan Keles if res == 0: 931b55f1f8SVolkan Keles return 0 94*b71edfaaSTobias Hieta log("GlobalISed failed, {}: {}".format(res[0], res[1])) 95*b71edfaaSTobias Hieta if res != err.split(";"): 961b55f1f8SVolkan Keles return 0 971b55f1f8SVolkan Keles else: 981b55f1f8SVolkan Keles return 1 991b55f1f8SVolkan Keles 1001b55f1f8SVolkan Keles 1011b55f1f8SVolkan Kelesdef main(): 1021b55f1f8SVolkan Keles # Check if this is called by bugpoint. 103*b71edfaaSTobias Hieta if len(sys.argv) == 5 and sys.argv[1] == "-c": 1041b55f1f8SVolkan Keles sys.exit(run_bugpoint_check()) 1051b55f1f8SVolkan Keles 1061b55f1f8SVolkan Keles # Parse arguments. 1071b55f1f8SVolkan Keles parser = argparse.ArgumentParser( 108*b71edfaaSTobias Hieta description=__doc__, formatter_class=argparse.RawTextHelpFormatter 109*b71edfaaSTobias Hieta ) 110*b71edfaaSTobias Hieta parser.add_argument("BuildDir", help="Path to LLVM build directory") 111*b71edfaaSTobias Hieta parser.add_argument("IRFile", help="Path to the input IR file") 1121b55f1f8SVolkan Keles args = parser.parse_args() 1131b55f1f8SVolkan Keles 1141b55f1f8SVolkan Keles # Check if the binaries exist. 1151b55f1f8SVolkan Keles build_dir = check_path(args.BuildDir) 1161b55f1f8SVolkan Keles ir_file = check_path(args.IRFile) 117*b71edfaaSTobias Hieta llc_bin = check_bin(build_dir, "llc") 118*b71edfaaSTobias Hieta opt_bin = check_bin(build_dir, "opt") 119*b71edfaaSTobias Hieta bugpoint_bin = check_bin(build_dir, "bugpoint") 1201b55f1f8SVolkan Keles 1211b55f1f8SVolkan Keles # Run llc to see if GlobalISel fails. 122*b71edfaaSTobias Hieta log("Running llc...") 1231b55f1f8SVolkan Keles res = run_llc(llc_bin, ir_file) 1241b55f1f8SVolkan Keles if res == 0: 1251b55f1f8SVolkan Keles log_err("Expected failure") 1261b55f1f8SVolkan Keles raise 1271b55f1f8SVolkan Keles hr() 128*b71edfaaSTobias Hieta log("GlobalISel failed, {}: {}.".format(res[0], res[1])) 1291b55f1f8SVolkan Keles tmp = tempfile.NamedTemporaryFile() 130*b71edfaaSTobias Hieta log("Writing error to {} for bugpoint.".format(tmp.name)) 131*b71edfaaSTobias Hieta tmp.write(";".join(res)) 1321b55f1f8SVolkan Keles tmp.flush() 1331b55f1f8SVolkan Keles hr() 1341b55f1f8SVolkan Keles 1351b55f1f8SVolkan Keles # Run bugpoint. 136*b71edfaaSTobias Hieta log("Running bugpoint...") 1371b55f1f8SVolkan Keles run_bugpoint(bugpoint_bin, llc_bin, opt_bin, tmp.name, ir_file) 1381b55f1f8SVolkan Keles hr() 139*b71edfaaSTobias Hieta log("Done!") 1401b55f1f8SVolkan Keles hr() 141*b71edfaaSTobias Hieta output_file = "bugpoint-reduced-simplified.bc" 142*b71edfaaSTobias Hieta log("Run llvm-dis to disassemble the output:") 143*b71edfaaSTobias Hieta log("$ {}/bin/llvm-dis -o - {}".format(build_dir, output_file)) 144*b71edfaaSTobias Hieta log("Run llc to reproduce the problem:") 145*b71edfaaSTobias Hieta log( 146*b71edfaaSTobias Hieta "$ {}/bin/llc -o - -global-isel " 147*b71edfaaSTobias Hieta "-pass-remarks-missed=gisel {}".format(build_dir, output_file) 148*b71edfaaSTobias Hieta ) 1491b55f1f8SVolkan Keles 1501b55f1f8SVolkan Keles 151*b71edfaaSTobias Hietaif __name__ == "__main__": 1521b55f1f8SVolkan Keles main() 153