@@ -80,23 +80,23 @@ def write_to_script(text, filename):
8080 os .chmod (filename , os .stat (filename ).st_mode | stat .S_IEXEC )
8181
8282
83- def extract_opt_level (args_list : List [str ]) -> Optional [ str ] :
83+ def extract_opt_level (args_list : List [str ]) -> str :
8484 """
8585 Finds the last optimization flag (-O...) from a list of arguments.
8686
8787 Args:
8888 args_list: A list of string arguments passed to the compiler.
8989
9090 Returns:
91- The last matching optimization flag string if found, otherwise None .
91+ The last matching optimization flag string if found, otherwise -O2 .
9292 """
93- valid_opt_flags = {"-O0" , "-O1" , "-O2" , "-O3" , "-Os" , "-Oz" , "-Og" , "-Ofast" }
93+ valid_opt_flags = {"-O0" , "-O1" , "-O2" , "-O3" , "-Os" , "-Oz" }
9494
9595 # Iterate in reverse to find the last occurrence
9696 for arg in reversed (args_list ):
9797 if arg in valid_opt_flags :
9898 return arg
99- return None
99+ return "-O2"
100100
101101
102102def remove_first_line (file_path ):
@@ -237,16 +237,10 @@ def skip_function(func_name):
237237
238238 self .expected_output = result
239239
240- def check_expected_output (self , cmd = None , args = None , filename = None ):
241- if not cmd :
242- cmd = self .clang
243- if not args :
244- args = self .clang_args
245- if not filename :
246- filename = self .file_to_reduce
247-
240+ def check_expected_output (self , cmd , args , filename ):
241+ cmd = self .get_crash_cmd (cmd = cmd , args = args , filename = filename )
248242 p = subprocess .Popen (
249- self . get_crash_cmd ( cmd = cmd , args = args , filename = filename ) ,
243+ cmd ,
250244 stdout = subprocess .PIPE ,
251245 stderr = subprocess .STDOUT ,
252246 )
@@ -300,7 +294,7 @@ def check_interestingness(self, cmd, use_llvm_reduce=False):
300294 with tempfile .NamedTemporaryFile () as empty_file :
301295 new_args = cmd [1 :] if use_llvm_reduce else cmd [1 :- 1 ]
302296 is_interesting = self .check_expected_output (
303- cmd = cmd [0 ], args = new_args , filename = empty_file .name
297+ cmd [0 ], new_args , empty_file .name
304298 )
305299 if is_interesting :
306300 sys .exit ("The interestingness test passes for an empty file." )
@@ -312,12 +306,16 @@ def clang_preprocess(self):
312306 cmd_preprocess_no_lines = cmd_preprocess + ["-P" ]
313307 try :
314308 subprocess .check_call (cmd_preprocess_no_lines )
315- if self .check_expected_output (filename = tmpfile .name ):
309+ if self .check_expected_output (
310+ self .clang , self .clang_args , tmpfile .name
311+ ):
316312 print ("Successfully preprocessed with line markers removed" )
317313 shutil .copy (tmpfile .name , self .file_to_reduce )
318314 else :
319315 subprocess .check_call (cmd_preprocess )
320- if self .check_expected_output (filename = tmpfile .name ):
316+ if self .check_expected_output (
317+ self .clang , self .clang_args , tmpfile .name
318+ ):
321319 print ("Successfully preprocessed without removing line markers" )
322320 shutil .copy (tmpfile .name , self .file_to_reduce )
323321 else :
@@ -356,7 +354,9 @@ def try_remove_args(self, args, msg=None, extra_arg=None, **kwargs):
356354 new_args .remove (extra_arg )
357355 new_args .append (extra_arg )
358356
359- if new_args != args and self .check_expected_output (args = new_args ):
357+ if new_args != args and self .check_expected_output (
358+ self .clang , new_args , self .file_to_reduce
359+ ):
360360 if msg :
361361 verbose_print (msg )
362362 return new_args
@@ -372,7 +372,7 @@ def try_remove_arg_by_index(self, args, index):
372372 del new_args [index ]
373373 removed_arg += " " + args [index + 1 ]
374374
375- if self .check_expected_output (args = new_args ):
375+ if self .check_expected_output (self . clang , new_args , self . file_to_reduce ):
376376 verbose_print ("Removed" , removed_arg )
377377 return new_args , index
378378 return args , index + 1
@@ -507,13 +507,15 @@ def run_llvm_reduce(self):
507507
508508 def classify_crash (self ) -> FailureType :
509509 print ("Classifying crash ..." )
510- if self .check_expected_output (args = self .clang_args + ["-fsyntax-only" ]):
510+ if self .check_expected_output (
511+ self .clang , self .clang_args + ["-fsyntax-only" ], self .file_to_reduce
512+ ):
511513 print ("Found Frontend Crash" )
512514 return FailureType .FrontEnd
513515
514516 print ("Found Middle/Backend failure" )
515517
516- self .opt_level = extract_opt_level (self .clang_args ) or "-O2"
518+ self .opt_level = extract_opt_level (self .clang_args )
517519 backend_result = self .check_backend ()
518520 if backend_result == FailureType .BackEnd :
519521 return backend_result
@@ -524,12 +526,14 @@ def classify_crash(self) -> FailureType:
524526
525527 def check_llc_failure (self ) -> bool :
526528 return self .check_expected_output (
527- cmd = self .llc , args = [self .opt_level , "-filetype=obj" ], filename = self .ir_file
529+ self .llc , [self .opt_level , "-filetype=obj" ], self .ir_file
528530 )
529531
530532 def extract_backend_ir (self ) -> bool :
531533 return not self .check_expected_output (
532- args = self .clang_args + ["-emit-llvm" , "-o" , self .ir_file ]
534+ self .clang ,
535+ self .clang_args + ["-emit-llvm" , "-o" , self .ir_file ],
536+ self .file_to_reduce ,
533537 )
534538
535539 def check_backend (self ) -> Optional [FailureType ]:
@@ -539,38 +543,67 @@ def check_backend(self) -> Optional[FailureType]:
539543 print ("Checking llc for failure" )
540544 if self .check_llc_failure ():
541545 print ("Found BackEnd Crash" )
546+ self .new_cmd = [self .llc , self .opt_level , "-filetype=obj" ]
542547 return FailureType .BackEnd
543548
544- def extract_crashing_ir (self ):
549+ def extract_crashing_ir (self , use_print_on_crash = False ):
545550 """
546551 Extract IR just before the crash using --print-on-crash
547552 """
548- args = self .clang_args + [
549- "-mllvm" ,
550- "--print-on-crash" ,
551- "-mllvm" ,
552- f"--print-on-crash-path={ self .ir_file } " ,
553- "-mllvm" ,
554- "--print-module-scope" ,
555- ]
553+ if use_print_on_crash :
554+ args = self .clang_args + [
555+ "-mllvm" ,
556+ "--print-on-crash" ,
557+ "-mllvm" ,
558+ f"--print-on-crash-path={ self .ir_file } " ,
559+ "-mllvm" ,
560+ "--print-module-scope" ,
561+ ]
556562
557- if not self .check_expected_output (args = args ):
558- sys .exit ("The interestingness test does not pass with '--print-on-crash'." )
563+ if not self .check_expected_output (self .clang , args , self .file_to_reduce ):
564+ sys .exit (
565+ "The interestingness test does not pass with '--print-on-crash'."
566+ )
559567
560- # The output from --print-on-crash has an invalid first line (pass name).
561- remove_first_line (self .ir_file )
568+ # The output from --print-on-crash has an invalid first line (pass name).
569+ remove_first_line (self .ir_file )
570+ return
571+ args = self .clang_args + [
572+ "-disable-llvm-passes" ,
573+ "-S" ,
574+ "-emit-llvm" ,
575+ "-o" ,
576+ self .ir_file ,
577+ ]
578+ if self .check_expected_output (self .clang , args , self .file_to_reduce ):
579+ sys .exit ("The interestingness test does not pass when generating llvm ir." )
580+ # print(quote_cmd(self.get_crash_cmd(self.clang, args, self.file_to_reduce)))
562581
563582 def check_middle_end (self ) -> FailureType :
564583 # TODO: parse the exact pass from the backtrace and set the pass
565584 # pipeline directly via -passes="...".
566585 print ("Checking opt for failure" )
586+ args = [self .opt_level , "-disable-output" ]
587+ if self .check_expected_output (
588+ self .opt ,
589+ args ,
590+ self .ir_file ,
591+ ):
592+ print ("Found MiddleEnd Crash" )
593+ self .new_cmd = [self .opt ] + args
594+ return FailureType .MiddleEnd
595+
596+ print ("Check clang on IR file" )
597+ args = self .clang_args [:- 1 ] + ["ir" ]
567598 if self .check_expected_output (
568- cmd = self .opt ,
569- args = [ self . opt_level , "-disable-output" ] ,
570- filename = self .ir_file ,
599+ self .clang ,
600+ args ,
601+ self .ir_file ,
571602 ):
572603 print ("Found MiddleEnd Crash" )
604+ self .new_cmd = [self .clang ] + args
573605 return FailureType .MiddleEnd
606+
574607 print (
575608 "Could not automatically detect crash type, falling back to creduce/cvise."
576609 )
@@ -671,12 +704,10 @@ def main():
671704 print ("Starting reduction with creduce/cvise" )
672705 pass
673706 case FailureType .MiddleEnd :
674- new_cmd = [opt_cmd , "-disable-output" , r .opt_level ]
675- r .reduce_ir_crash (new_cmd )
707+ r .reduce_ir_crash (r .new_cmd )
676708 return
677709 case FailureType .BackEnd :
678- new_cmd = [llc_cmd , "-filetype=obj" , r .opt_level ]
679- r .reduce_ir_crash (new_cmd )
710+ r .reduce_ir_crash (r .new_cmd )
680711 return
681712
682713 r .simplify_clang_args ()
0 commit comments