@@ -1034,8 +1034,6 @@ static IR_NEVER_INLINE void ir_collect_irreducible_loops(ir_ctx *ctx, uint32_t *
10341034 do {
10351035 uint32_t pred = * p ;
10361036 if (ENTRY_TIME (pred ) > ENTRY_TIME (hdr ) && EXIT_TIME (pred ) < EXIT_TIME (hdr )) {
1037- IR_ASSERT (blocks [pred ].loop_header == 0 );
1038- // blocks[pred].loop_header = 0; /* support for merged loops */
10391037 ir_worklist_push (work , pred );
10401038 }
10411039 p ++ ;
@@ -1046,7 +1044,9 @@ static IR_NEVER_INLINE void ir_collect_irreducible_loops(ir_ctx *ctx, uint32_t *
10461044 uint32_t b = ir_worklist_pop (work );
10471045
10481046 bb = & blocks [b ];
1049- bb -> loop_header = hdr ;
1047+ if (!bb -> loop_header ) {
1048+ bb -> loop_header = hdr ;
1049+ }
10501050
10511051 uint32_t * p = & edges [bb -> predecessors ];
10521052 uint32_t n = bb -> predecessors_count ;
@@ -1175,8 +1175,6 @@ int ir_find_loops(ir_ctx *ctx)
11751175 if (!ir_worklist_len (& work )) {
11761176 ir_bitset_clear (work .visited , ir_bitset_len (ir_worklist_capasity (& work )));
11771177 }
1178- IR_ASSERT (!blocks [pred ].loop_header );
1179- // blocks[pred].loop_header = 0; /* support for merged loops */
11801178 ir_worklist_push (& work , pred );
11811179 } else {
11821180 /* Otherwise it's a back-edge of irreducible loop. */
@@ -1214,8 +1212,9 @@ int ir_find_loops(ir_ctx *ctx)
12141212 if (b != hdr ) {
12151213 ir_block * bb = & blocks [b ];
12161214
1217- IR_ASSERT (!bb -> loop_header );
1218- bb -> loop_header = hdr ;
1215+ if (!bb -> loop_header ) {
1216+ bb -> loop_header = hdr ;
1217+ }
12191218
12201219 uint32_t * p = & edges [bb -> predecessors ];
12211220 uint32_t n = bb -> predecessors_count ;
@@ -1479,6 +1478,19 @@ static void ir_dump_chains(ir_ctx *ctx, ir_chain *chains)
14791478 }
14801479 }
14811480}
1481+
1482+ static bool ir_is_merged_loop_back_edge (ir_ctx * ctx , uint32_t hdr , uint32_t b )
1483+ {
1484+ if (ctx -> cfg_blocks [hdr ].flags & IR_BB_LOOP_HEADER ) {
1485+ uint32_t loop_depth = ctx -> cfg_blocks [hdr ].loop_depth ;
1486+
1487+ while (ctx -> cfg_blocks [b ].loop_depth > loop_depth ) {
1488+ b = ctx -> cfg_blocks [b ].loop_header ;
1489+ }
1490+ return b == hdr ;
1491+ }
1492+ return 0 ;
1493+ }
14821494#endif
14831495
14841496static int ir_schedule_blocks_bottom_up (ir_ctx * ctx )
@@ -1535,7 +1547,8 @@ static int ir_schedule_blocks_bottom_up(ir_ctx *ctx)
15351547 }
15361548 } else if (b != predecessor && ctx -> cfg_blocks [predecessor ].loop_header != b ) {
15371549 /* not a loop back-edge */
1538- IR_ASSERT (b == predecessor || ctx -> cfg_blocks [predecessor ].loop_header == b );
1550+ IR_ASSERT (b == predecessor || ctx -> cfg_blocks [predecessor ].loop_header == b ||
1551+ ir_is_merged_loop_back_edge (ctx , b , predecessor ));
15391552 }
15401553 }
15411554 }
0 commit comments