@@ -2270,6 +2270,244 @@ def add_analyze_checks(
22702270 )
22712271
22722272
2273+ IR_FUNC_NAME_RE = re .compile (
2274+ r"^\s*define\s+(?:internal\s+)?[^@]*@(?P<func>[A-Za-z0-9_.]+)\s*\("
2275+ )
2276+ IR_PREFIX_DATA_RE = re .compile (r"^ *(;|$)" )
2277+ MIR_FUNC_NAME_RE = re .compile (r" *name: *(?P<func>[A-Za-z0-9_.-]+)" )
2278+ MIR_BODY_BEGIN_RE = re .compile (r" *body: *\|" )
2279+ MIR_BASIC_BLOCK_RE = re .compile (r" *bb\.[0-9]+.*:$" )
2280+ MIR_PREFIX_DATA_RE = re .compile (r"^ *(;|bb.[0-9].*: *$|[a-z]+:( |$)|$)" )
2281+
2282+
2283+ def find_mir_functions_with_one_bb (lines , verbose = False ):
2284+ result = []
2285+ cur_func = None
2286+ bbs = 0
2287+ for line in lines :
2288+ m = MIR_FUNC_NAME_RE .match (line )
2289+ if m :
2290+ if bbs == 1 :
2291+ result .append (cur_func )
2292+ cur_func = m .group ("func" )
2293+ bbs = 0
2294+ m = MIR_BASIC_BLOCK_RE .match (line )
2295+ if m :
2296+ bbs += 1
2297+ if bbs == 1 :
2298+ result .append (cur_func )
2299+ return result
2300+
2301+
2302+ def add_mir_checks_for_function (
2303+ test ,
2304+ output_lines ,
2305+ run_list ,
2306+ func_dict ,
2307+ func_name ,
2308+ single_bb ,
2309+ print_fixed_stack ,
2310+ first_check_is_next ,
2311+ at_the_function_name ,
2312+ ):
2313+ printed_prefixes = set ()
2314+ for run in run_list :
2315+ for prefix in run [0 ]:
2316+ if prefix in printed_prefixes :
2317+ break
2318+ if not func_dict [prefix ][func_name ]:
2319+ continue
2320+ if printed_prefixes :
2321+ # Add some space between different check prefixes.
2322+ indent = len (output_lines [- 1 ]) - len (output_lines [- 1 ].lstrip (" " ))
2323+ output_lines .append (" " * indent + ";" )
2324+ printed_prefixes .add (prefix )
2325+ add_mir_check_lines (
2326+ test ,
2327+ output_lines ,
2328+ prefix ,
2329+ ("@" if at_the_function_name else "" ) + func_name ,
2330+ single_bb ,
2331+ func_dict [prefix ][func_name ],
2332+ print_fixed_stack ,
2333+ first_check_is_next ,
2334+ )
2335+ break
2336+ else :
2337+ warn (
2338+ "Found conflicting asm for function: {}" .format (func_name ),
2339+ test_file = test ,
2340+ )
2341+ return output_lines
2342+
2343+
2344+ def add_mir_check_lines (
2345+ test ,
2346+ output_lines ,
2347+ prefix ,
2348+ func_name ,
2349+ single_bb ,
2350+ func_info ,
2351+ print_fixed_stack ,
2352+ first_check_is_next ,
2353+ ):
2354+ func_body = str (func_info ).splitlines ()
2355+ if single_bb :
2356+ # Don't bother checking the basic block label for a single BB
2357+ func_body .pop (0 )
2358+
2359+ if not func_body :
2360+ warn (
2361+ "Function has no instructions to check: {}" .format (func_name ),
2362+ test_file = test ,
2363+ )
2364+ return
2365+
2366+ first_line = func_body [0 ]
2367+ indent = len (first_line ) - len (first_line .lstrip (" " ))
2368+ # A check comment, indented the appropriate amount
2369+ check = "{:>{}}; {}" .format ("" , indent , prefix )
2370+
2371+ output_lines .append ("{}-LABEL: name: {}" .format (check , func_name ))
2372+
2373+ if print_fixed_stack :
2374+ output_lines .append ("{}: fixedStack:" .format (check ))
2375+ for stack_line in func_info .extrascrub .splitlines ():
2376+ filecheck_directive = check + "-NEXT"
2377+ output_lines .append ("{}: {}" .format (filecheck_directive , stack_line ))
2378+
2379+ first_check = not first_check_is_next
2380+ for func_line in func_body :
2381+ if not func_line .strip ():
2382+ # The mir printer prints leading whitespace so we can't use CHECK-EMPTY:
2383+ output_lines .append (check + "-NEXT: {{" + func_line + "$}}" )
2384+ continue
2385+ filecheck_directive = check if first_check else check + "-NEXT"
2386+ first_check = False
2387+ check_line = "{}: {}" .format (filecheck_directive , func_line [indent :]).rstrip ()
2388+ output_lines .append (check_line )
2389+
2390+
2391+ def should_add_mir_line_to_output (input_line , prefix_set ):
2392+ # Skip any check lines that we're handling as well as comments
2393+ m = CHECK_RE .match (input_line )
2394+ if (m and m .group (1 ) in prefix_set ) or input_line .strip () == ";" :
2395+ return False
2396+ return True
2397+
2398+
2399+ def add_mir_checks (
2400+ input_lines ,
2401+ prefix_set ,
2402+ autogenerated_note ,
2403+ test ,
2404+ run_list ,
2405+ func_dict ,
2406+ print_fixed_stack ,
2407+ first_check_is_next ,
2408+ at_the_function_name ,
2409+ ):
2410+ simple_functions = find_mir_functions_with_one_bb (input_lines )
2411+
2412+ output_lines = []
2413+ output_lines .append (autogenerated_note )
2414+
2415+ func_name = None
2416+ state = "toplevel"
2417+ for input_line in input_lines :
2418+ if input_line == autogenerated_note :
2419+ continue
2420+
2421+ if state == "toplevel" :
2422+ m = IR_FUNC_NAME_RE .match (input_line )
2423+ if m :
2424+ state = "ir function prefix"
2425+ func_name = m .group ("func" )
2426+ if input_line .rstrip ("| \r \n " ) == "---" :
2427+ state = "document"
2428+ output_lines .append (input_line )
2429+ elif state == "document" :
2430+ m = MIR_FUNC_NAME_RE .match (input_line )
2431+ if m :
2432+ state = "mir function metadata"
2433+ func_name = m .group ("func" )
2434+ if input_line .strip () == "..." :
2435+ state = "toplevel"
2436+ func_name = None
2437+ if should_add_mir_line_to_output (input_line , prefix_set ):
2438+ output_lines .append (input_line )
2439+ elif state == "mir function metadata" :
2440+ if should_add_mir_line_to_output (input_line , prefix_set ):
2441+ output_lines .append (input_line )
2442+ m = MIR_BODY_BEGIN_RE .match (input_line )
2443+ if m :
2444+ if func_name in simple_functions :
2445+ # If there's only one block, put the checks inside it
2446+ state = "mir function prefix"
2447+ continue
2448+ state = "mir function body"
2449+ add_mir_checks_for_function (
2450+ test ,
2451+ output_lines ,
2452+ run_list ,
2453+ func_dict ,
2454+ func_name ,
2455+ single_bb = False ,
2456+ print_fixed_stack = print_fixed_stack ,
2457+ first_check_is_next = first_check_is_next ,
2458+ at_the_function_name = at_the_function_name ,
2459+ )
2460+ elif state == "mir function prefix" :
2461+ m = MIR_PREFIX_DATA_RE .match (input_line )
2462+ if not m :
2463+ state = "mir function body"
2464+ add_mir_checks_for_function (
2465+ test ,
2466+ output_lines ,
2467+ run_list ,
2468+ func_dict ,
2469+ func_name ,
2470+ single_bb = True ,
2471+ print_fixed_stack = print_fixed_stack ,
2472+ first_check_is_next = first_check_is_next ,
2473+ at_the_function_name = at_the_function_name ,
2474+ )
2475+
2476+ if should_add_mir_line_to_output (input_line , prefix_set ):
2477+ output_lines .append (input_line )
2478+ elif state == "mir function body" :
2479+ if input_line .strip () == "..." :
2480+ state = "toplevel"
2481+ func_name = None
2482+ if should_add_mir_line_to_output (input_line , prefix_set ):
2483+ output_lines .append (input_line )
2484+ elif state == "ir function prefix" :
2485+ m = IR_PREFIX_DATA_RE .match (input_line )
2486+ if not m :
2487+ state = "ir function body"
2488+ add_mir_checks_for_function (
2489+ test ,
2490+ output_lines ,
2491+ run_list ,
2492+ func_dict ,
2493+ func_name ,
2494+ single_bb = False ,
2495+ print_fixed_stack = print_fixed_stack ,
2496+ first_check_is_next = first_check_is_next ,
2497+ at_the_function_name = at_the_function_name ,
2498+ )
2499+
2500+ if should_add_mir_line_to_output (input_line , prefix_set ):
2501+ output_lines .append (input_line )
2502+ elif state == "ir function body" :
2503+ if input_line .strip () == "}" :
2504+ state = "toplevel"
2505+ func_name = None
2506+ if should_add_mir_line_to_output (input_line , prefix_set ):
2507+ output_lines .append (input_line )
2508+ return output_lines
2509+
2510+
22732511def build_global_values_dictionary (glob_val_dict , raw_tool_output , prefixes , ginfo ):
22742512 for nameless_value in ginfo .get_nameless_values ():
22752513 if nameless_value .global_ir_rhs_regexp is None :
0 commit comments