When one operand is a user of another in a promoted binary operation
we may replace and delete the returned value before returning
triggering an assertion. Reorder node replacements to prevent this.
Fixes PR34137.
Differential D36581
[DAG] Fix Node Replacement in PromoteIntBinOp niravd on Aug 10 2017, 8:04 AM. Authored by
Details When one operand is a user of another in a promoted binary operation Fixes PR34137.
Diff Detail
Event TimelineComment Actions This is why I hate DAGCombine; you have to constantly worry about the CSE map invalidating pointers you care about, and I'm never confident I'm handling it correctly. Could we simplify this code using makeEquivalentMemoryOrdering to insert the loads into the right spot in the DAG? Or does that introduce its own RAUW problems? Comment Actions No, this is a close but unrelated problem. This has been latent for a long while. I'm a little surprised that it required rL297695 to expose this. FWIW I've found that the way to deal with CSE invalidation from multiple replacements is to calculate which nodes need to be replaced upfront (either trivially or checking if there's more than one use) and replacing user nodes before their operands. Clunkier than I'd like, but straightforward. I also have a patch that more aggressively causes invalidation-based assertions where latent bugs may lie; I think it'll catch the lion share of the latent bugs. Comment Actions Okay, that makes sense. Is it possible for N0 to be an ancestor of N1? If it is, do we need to replace N1 before N0?
Comment Actions Let me know if you need to run assertion patch through random testing (which finds all this cases I'm filing as bugs). Comment Actions Similarly, is there anything that we could add to EXPENSIVE_CHECKS builds to help identify these? Comment Actions LGTM.
|
Calling isPredecessorOf is a little risky; it's usually cheap, but the cost blows up for large DAGs. Hopefully this doesn't cause problems in practice.