3 """Reduces GlobalISel failures.
5 This script is a utility to reduce tests that GlobalISel
8 It runs llc to get the error message using a regex and creates
9 a custom command to check that specific error. Then, it runs bugpoint
10 with the custom command.
13 from __future__
import print_function
31 print('ERROR: {}'.format(msg
), file=sys
.stderr
)
35 if not os
.path
.exists(path
):
36 log_err('{} does not exist.'.format(path
))
41 def check_bin(build_dir
, bin_name
):
42 file_name
= '{}/bin/{}'.format(build_dir
, bin_name
)
43 return check_path(file_name
)
46 def run_llc(llc
, irfile
):
47 pr
= subprocess
.Popen([llc
,
51 '-pass-remarks-missed=gisel',
53 stdout
=subprocess
.PIPE
,
54 stderr
=subprocess
.PIPE
)
55 out
, err
= pr
.communicate()
60 r
'LLVM ERROR: ([a-z\s]+):.*(G_INTRINSIC[_A-Z]* <intrinsic:@[a-zA-Z0-9\.]+>|G_[A-Z_]+)')
61 match
= re_err
.match(err
)
65 return [match
.group(1), match
.group(2)]
68 def run_bugpoint(bugpoint_bin
, llc_bin
, opt_bin
, tmp
, ir_file
):
69 compileCmd
= '-compile-command={} -c {} {}'.format(
70 os
.path
.realpath(__file__
), llc_bin
, tmp
)
71 pr
= subprocess
.Popen([bugpoint_bin
,
74 '-opt-command={}'.format(opt_bin
),
78 log_err("Unable to reduce the test.")
82 def run_bugpoint_check():
83 path_to_llc
= sys
.argv
[2]
84 path_to_err
= sys
.argv
[3]
85 path_to_ir
= sys
.argv
[4]
86 with
open(path_to_err
, 'r') as f
:
88 res
= run_llc(path_to_llc
, path_to_ir
)
91 log('GlobalISed failed, {}: {}'.format(res
[0], res
[1]))
92 if res
!= err
.split(';'):
99 # Check if this is called by bugpoint.
100 if len(sys
.argv
) == 5 and sys
.argv
[1] == '-c':
101 sys
.exit(run_bugpoint_check())
104 parser
= argparse
.ArgumentParser(
105 description
=__doc__
, formatter_class
=argparse
.RawTextHelpFormatter
)
106 parser
.add_argument('BuildDir', help="Path to LLVM build directory")
107 parser
.add_argument('IRFile', help="Path to the input IR file")
108 args
= parser
.parse_args()
110 # Check if the binaries exist.
111 build_dir
= check_path(args
.BuildDir
)
112 ir_file
= check_path(args
.IRFile
)
113 llc_bin
= check_bin(build_dir
, 'llc')
114 opt_bin
= check_bin(build_dir
, 'opt')
115 bugpoint_bin
= check_bin(build_dir
, 'bugpoint')
117 # Run llc to see if GlobalISel fails.
118 log('Running llc...')
119 res
= run_llc(llc_bin
, ir_file
)
121 log_err("Expected failure")
124 log('GlobalISel failed, {}: {}.'.format(res
[0], res
[1]))
125 tmp
= tempfile
.NamedTemporaryFile()
126 log('Writing error to {} for bugpoint.'.format(tmp
.name
))
127 tmp
.write(';'.join(res
))
132 log('Running bugpoint...')
133 run_bugpoint(bugpoint_bin
, llc_bin
, opt_bin
, tmp
.name
, ir_file
)
137 output_file
= 'bugpoint-reduced-simplified.bc'
138 log('Run llvm-dis to disassemble the output:')
139 log('$ {}/bin/llvm-dis -o - {}'.format(build_dir
, output_file
))
140 log('Run llc to reproduce the problem:')
141 log('$ {}/bin/llc -o - -global-isel '
142 '-pass-remarks-missed=gisel {}'.format(build_dir
, output_file
))
145 if __name__
== '__main__':