@@ -430,36 +430,81 @@ def collect_original_check_lines(ti: TestInfo, prefix_set: set):
430
430
result[func_name][prefix] is filled with a list of right-hand-sides of check
431
431
lines.
432
432
"""
433
- result = {}
434
433
434
+ # We need to detect check lines, and associate them with the correct functions and prefixes.
435
+ # There are two formats how IR and check lines are combined. In the standard format,
436
+ # they are interleaved, and it suffices to parse IR function definitions in order to keep
437
+ # track of the current function:
438
+ #
439
+ # define i32 @func1(i32 %x) {
440
+ # ; CHECK-LABEL: define i32 @func1(
441
+ # ; CHECK-NEXT: /* check lines */
442
+ # ;
443
+ # %1 = /* IR body of @func1 */
444
+ #
445
+ # define i32 @func2(i32 %x) {
446
+ # ; CHECK-LABEL: define i32 @func2(
447
+ # ; CHECK-NEXT: /* check lines */
448
+ # ;
449
+ # %1 = /* IR body of @func2 */
450
+ #
451
+ # However, with --include-generated-funcs, check lines are separate from IR function bodies,
452
+ # and we also need to parse CHECK lines of function definitions:
453
+ #
454
+ # define i32 @func1(i32 %x) {
455
+ # /* IR body */
456
+ #
457
+ # define i32 @func2(..) {
458
+ # /* IR body */
459
+ #
460
+ # ; CHECK-LABEL: define i32 @func1
461
+ # ; CHECK-NEXT /* check lines for func1 */
462
+ #
463
+ # ; CHECK-LABEL: define i32 @func2
464
+ # ; CHECK-NEXT /* check lines for func2 */
465
+
466
+ result = collections .defaultdict (dict )
435
467
current_function = None
468
+
469
+ def update_current_function (line ):
470
+ m = IR_FUNCTION_RE .match (line )
471
+ if m is None :
472
+ return
473
+ func_name = m .group (1 )
474
+ if ti .args .function is not None and func_name != ti .args .function :
475
+ # When filtering on a specific function, skip all others.
476
+ return
477
+
478
+ nonlocal current_function
479
+ current_function = result [func_name ]
480
+
436
481
for input_line_info in ti .ro_iterlines ():
437
482
input_line = input_line_info .line
438
- if current_function is not None :
439
- if input_line == "" :
440
- continue
441
- if input_line .lstrip ().startswith (";" ):
442
- m = CHECK_RE .match (input_line )
443
- if (
444
- m is not None
445
- and m .group (1 ) in prefix_set
446
- and m .group (2 ) not in ["LABEL" , "SAME" ]
447
- ):
448
- if m .group (1 ) not in current_function :
449
- current_function [m .group (1 )] = []
450
- current_function [m .group (1 )].append (input_line [m .end () :].strip ())
451
- continue
483
+ if input_line == "" :
484
+ continue
485
+ m = None
486
+ if input_line .lstrip ().startswith (";" ):
487
+ m = CHECK_RE .match (input_line )
488
+ if m is not None and m .group (2 ) == "LABEL" :
489
+ # Update current_function if the current line is a CHECK of a function definition
490
+ line_remainder = input_line [len (m .group (0 )) :]
491
+ update_current_function (line_remainder )
492
+ else :
452
493
current_function = None
453
494
454
- m = IR_FUNCTION_RE .match (input_line )
455
- if m is not None :
456
- func_name = m .group (1 )
457
- if ti .args .function is not None and func_name != ti .args .function :
458
- # When filtering on a specific function, skip all others.
459
- continue
495
+ if current_function is not None :
496
+ if (
497
+ m is not None
498
+ and m .group (1 ) in prefix_set
499
+ and m .group (2 ) not in ["LABEL" , "SAME" ]
500
+ ):
501
+ if m .group (1 ) not in current_function :
502
+ current_function [m .group (1 )] = []
503
+ current_function [m .group (1 )].append (input_line [m .end () :].strip ())
504
+ continue
460
505
461
- assert func_name not in result
462
- current_function = result [ func_name ] = {}
506
+ # Update current_function if the current line is an IR function definition
507
+ update_current_function ( input_line )
463
508
464
509
return result
465
510
0 commit comments