[llvm-dev] Glued nodes from legalization lead to cycle after combine2

Friedman, Eli via llvm-dev llvm-dev at lists.llvm.org
Wed Oct 10 12:15:35 PDT 2018


On 10/10/2018 8:43 AM, Tim Neumann via llvm-dev wrote:
> Hi all,
>
> TL;DR: Legalization introduces 2 glued nodes, combine2 creates a 
> pseudo-cycle because the glue edge is only unidirectional, the 
> scheduler merges the glued nodes ==> cycle between SUnits ==> 
> Assertion triggers.
>
> Background: I've been experiment with Rust & AVR and ran into the 
> following issue. The original source was Rust, the IR of the reduced 
> test [0] case was generated by LLVM at 341010 [1] with some Rust specific 
> [2] and an unrelated local patch [3]. The reduced test case reproduces 
> the problem on LLVM HEAD.
>
> To reproduce: Run `llc -O1 reduced.ll [0]`.
>
> What happens: The assertion `(Node2Index[SU.NodeNum] > 
> Node2Index[PD.getSUnit()->NodeNum] && "Wrong topological sorting"` 
> triggers in `ScheduleDAG.cpp:506`.
>
> Consider the graphs before [4] and after [5] combine2: `t28` and `t29` 
> are glued together and have been created by 
> `DAGTypeLegalizer::ExpandIntRes_ADDSUB`. In 
> `DAGCombiner::CombineToPostIndexedLoadStore`, LLVM considers `t21` and 
> `t35` and decides that they can be combined to `t40`. This creates a 
> "pseudo-cycle": If the glued nodes `t28` and `t29` were combined (or 
> the glue edge reversed) there would be an actual cycle.
>
> A comment in `CombineToPostIndexedLoadStore` states that "Op must be 
> independent of N, i.e. Op is neither a predecessor nor a successor of 
> N. Otherwise, if Op is folded that would create a cycle", which is, of 
> course, correct. To verify the two nodes' (Op and N) independence, 
> LLVM checks if they are predecessors of each other. This check returns 
> `false` in the case at hand, which is correct if one only follows the 
> edges actually present in the graph. However, the way the two glue 
> nodes are handled later by the scheduler means that the edge between 
> them would need to be treated as bidirectional to get the desired 
> result. (Note that if you flip the glue edge, you have the dependency 
> `t35` -> `t28` -> `t29` -> `t22` -> `t21`).
>
> The schedule later combines the two nodes (graph at [6]), leading to a 
> cycle. That cycle then causes the assertion error when verifying the 
> topological ordering.
>
> Even though I only found this bug on an experimental target, I feel 
> like the core issue is target independent.
>
> *I would appreciate your thoughts on the matter, especially regarding 
> a potential solution.*
> *
> *
> I can see three places where to attempt a solution:
>
> (1) Change the TypeLegalizer to no longer generate the glue.

This is probably viable; the legalizer only generates 
ISD::ADDC/ISD::ADDE if your target marks them "Legal".  We've been 
gradually switching other targets to use ISD::UADDO/ISD::ADDCARRY 
instead, which don't use glue.

> (2) Change the Combiner to better handle glue links.

This is probably a good idea in any case.

-Eli

-- 
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20181010/151aec26/attachment.html>


More information about the llvm-dev mailing list