It also adds a check making sure PHIs for operands are all in the same
block.
Patch by Daniel Berlin <dberlin@dberlin.org>
Differential D43865
[NewGVN] Split OpPHI detection and creation. fhahn on Feb 28 2018, 3:58 AM. Authored by
Details It also adds a check making sure PHIs for operands are all in the same Patch by Daniel Berlin <dberlin@dberlin.org>
Diff Detail Event TimelineComment Actions I don't understand how this can happen, since the value phi should be equivalent to an op phi in the same block. Comment Actions So, we are definitely "doing it wrong". This code is definitely broken in the case that multiple operands are defined by phi of ops, and they are not in the same block. It also badly needs refactoring because of how long it took to notice this. Here is what is happening: Let me start with context. The reason it differentiates the phi block from the instruction block is to catch the case the instruction operand is dependent on a dominating phi ie bb1: These are to transform valid phi of ops. The limitation on the code the way it is currently written, however, is that it assumes *all* phis for the instruction are in the same block. If you give it something like: br label %bb1 bb1: %tmp = phi i32 [ 0, %bb ], [ %tmp10, %bb6 ] bb6: %tmp7 = phi i32 [ 0, %bb1 ], [ 1, %bb4 ], [ 1, %bb5 ] %tmp9 = or i32 %tmp, %tmp7 It will try to evaluate tmp9 in the tmp1 block as or i32 <phi pred>, %tmp7, and either
At least as far as i've been able to reproduce, the only case #3 occurs is when we've made phi of ops for the operands, as you see in this case. The correct way to handle all of this is unfortunately recursive. This is unlikely to be worth it ATM, it seems incredibly uncommon. For now, safety wise, we should verify all phis for an op are in the same block and give up if not. Comment Actions There is also a case 4 here i forgot, which is get unlucky, find something (where all blocks have the same number of preds) and probably generate wrong code :) Comment Actions Thanks for tracking that down and for sending along a patch. As far as I can see, it splits up analysis and the phi creation, which makes it much easier to see what going on :) It also fixes the issue by checking if all phis for on op are in the same block Given that, I was wondering if there is anything left you want me to do or I should look into? :) Comment Actions At a minimum, the patch needs bootstrap and testing, i didn't test it except on this case and test/Transforms/NewGVN. Comment Actions Done! With and without this patch, bootstrapping clang/llvm fails with "value number changed after ..." assertions. I finally took the time and re-visited D42180. One case we seem to miss is when changes to the translated operands of the ValueOp cause us to find a leader for the ValueOp, for which we previously did not find a leader and returned early. In this case no additional users are added to trigger re-evaluation of the phi node. Together with D42180, bootstrapping passed. And also running the test-suite. Comment Actions So, just to put this on the review: the current code on this review definitely not the right fix compared to the patch i sent :) Comment Actions Yep, the diff in Phab is out-dated. I'll commit D42180 first, and then rebase your patch and do another bootstrap round and update the diff here. |