• Francisco Jerez's avatar
    intel/ir: Fix CFG corruption in opt_predicated_break(). · 54fbc625
    Francisco Jerez authored
    Specifically the optimization of a conditional BREAK + WHILE sequence
    into a conditional WHILE seems pretty broken.  The list of successors
    of "earlier_block" (where the conditional BREAK was found) is emptied
    and then re-created with the same edges for no apparent reason.  On
    top of that the list of predecessors of the block immediately after
    the WHILE loop is emptied, but only one of the original edges will be
    added back, which means that potentially several blocks that still
    have it on their list of successors won't be on its list of
    predecessors anymore, causing all sorts of hilarity due to the
    inconsistency in the control flow graph.
    
    The solution is to remove the code that's removing valid edges from
    the CFG.  cfg_t::remove_block() will already clean up after itself.
    The assert in bblock_t::combine_with() also needs to be removed since
    we will be merging a block with multiple children into the first one
    of them.
    
    Found the issue on a hardware enabling branch originally, but
    apparently somebody reproduced the same problem independently on
    master in the meantime.
    
    Fixes: d13bcdb3 ("i965/fs: Extend predicated break pass to predicate WHILE.")
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=111009
    Cc: jiradet.jd@gmail.com
    Cc: Sergii Romantsov <sergii.romantsov@globallogic.com>
    Cc: Matt Turner <mattst88@gmail.com>
    Cc: mesa-stable@lists.freedesktop.org
    Tested-by: default avatarPaul Chelombitko <qamonstergl@gmail.com>
    Reviewed-by: default avatarMatt Turner <mattst88@gmail.com>
    54fbc625