LoopUtils.cpp contains a utility that splits an loop exit block, so that the new block contains only edges coming from the loop. In the case of nested loops, the exit path for the inner loop might also be the back-edge of the outer loop. The new block which is inserted on this path, is now a latch for the outer loop, and it needs to hold the loop metadata for the outer loop. (The test case gives a more concrete view of the situation.)
Details
Diff Detail
Event Timeline
lib/Transforms/Utils/LoopUtils.cpp | ||
---|---|---|
83 | { } not needed here. | |
85 | Dot in the end of sentence. | |
96 | Is it possible that their loops don't match? If no, please turn it into an assert. If yes, please add a test on this situation. | |
test/Transforms/LoopSimplify/preserve-llvm-loop-metadata2.ll | ||
35 | Can the test be reduced to make it clear that it's only supposed to test metadata and not fp computations? I think it can be just reduced to having just blocks with counters. Maybe also makes sense to rename blocks to smth like outer.loop, inner.loop. |
lib/Transforms/Utils/LoopUtils.cpp | ||
---|---|---|
39 | These should be in order. I think running clang-format on the patch will do that for you. | |
test/Transforms/LoopSimplify/preserve-llvm-loop-metadata2.ll | ||
7 | Is it worth-while to make sure the LOOPMD is the correct of the two metadata nodes (still "llvm.loop.unroll_and_jam.count")? And that the inner loops still has nounroll? | |
64 | You can probably remove the tbaa info too, to make things simpler. |
Rewrote comments, fixed formatting, simplified test and added checks for specific metadata
Thank you for the thorough review. I have one more request to the reviewers on this list: could someone give a hand to commit the code? I don't have write access to the repo yet.
Thanks for the patch!
In case it comes ever up and is actually still relevant (I haven't checked), there are similar problems all over the place.
The one I tried to fix at some point but never actually did can be found here: https://reviews.llvm.org/D5344
I think this broke the windows selfhost:
http://lab.llvm.org:8011/builders/clang-x64-windows-msvc/builds/1457/steps/stage%202%20build/logs/stdio
Assertion failed: TI->getMetadata(LLVMContext::MD_loop) == OuterLoopMD && "exit edge to other loop doesn't contain expected metadata", file C:\b\slave\clang-x64-windows-msvc\build\llvm.src\lib\Transforms\Utils\LoopUtils.cpp, line 105 #0 0x00007ff647c07f05 HandleAbort c:\b\slave\clang-x64-windows-msvc\build\llvm.src\lib\support\windows\signals.inc:409:0 #1 0x00007ff99ee4dc17 (C:\windows\SYSTEM32\ucrtbase.DLL+0x6dc17) #2 0x00007ff99ee4eaa1 (C:\windows\SYSTEM32\ucrtbase.DLL+0x6eaa1) #3 0x00007ff99ee50751 (C:\windows\SYSTEM32\ucrtbase.DLL+0x70751) #4 0x00007ff99ee50a5f (C:\windows\SYSTEM32\ucrtbase.DLL+0x70a5f) #5 0x00007ff647cf0c9e <lambda_e0b0a017e173a90c4e1e4410b36fad3c>::operator() c:\b\slave\clang-x64-windows-msvc\build\llvm.src\lib\transforms\utils\looputils.cpp:106:0 #6 0x00007ff647cf329a llvm::formDedicatedExitBlocks(class llvm::Loop *,class llvm::DominatorTree *,class llvm::LoopInfo *,bool) c:\b\slave\clang-x64-windows-msvc\build\llvm.src\lib\transforms\utils\looputils.cpp:135:0 #7 0x00007ff647c749d8 simplifyOneLoop c:\b\slave\clang-x64-windows-msvc\build\llvm.src\lib\transforms\utils\loopsimplify.cpp:535:0 #8 0x00007ff647c73d4a llvm::simplifyLoop(class llvm::Loop *,class llvm::DominatorTree *,class llvm::LoopInfo *,class llvm::ScalarEvolution *,class llvm::AssumptionCache *,bool) c:\b\slave\clang-x64-windows-msvc\build\llvm.src\lib\transforms\utils\loopsimplify.cpp:706:0 #9 0x00007ff647c72b6a `anonymous namespace'::LoopSimplify::runOnFunction c:\b\slave\clang-x64-windows-msvc\build\llvm.src\lib\transforms\utils\loopsimplify.cpp:776:0 ...
I'll get in a revert.
It went green with my change here:
http://lab.llvm.org:8011/builders/clang-x64-windows-msvc/builds/1463
Can you gather the reproducer? I'm a bit busy for that right now.
Remove duplicate blocks from the list of exit predecessors. This happens when the predecessor inst is a switch with duplicate targets. Avoids block double-processing and maintains the metadata consistency assertion.
lib/Transforms/Utils/LoopUtils.cpp | ||
---|---|---|
72 | You're calling std::sort on a list of pointers; the result is non-deterministic, which could affect the compiler output. |
Maybe add a separate testcase, instead of modifying an existing testcase? Otherwise looks fine, although maybe wait for @mkazantsev to look again.
Did not include the reverted part of the code (the important part :) ) in the new patch. Added separate testcase for switch-backedge. Thanks for the fix suggestions.
@mkazantsev, would you mind taking one more look at this patch? One significant fix was made since your last review, to handle duplicate edges from SwitchInsts. The patch has now been rebased to latest (which hasn't changed it much). Thanks!
I think yes, together with all the other places were loop metadata is not preserved, such as D66892.
I'm trying to make sense of the history here. It looks like I commited it in November last year. Then it got reverted. So I reopened it but maybe didn't move it to changes required and instead it stayed in accepted. Then @clin1 updated it, but it never got re-reviewed. Then it was rebased in January. And I guess sat in accepted state until today when phabricator lost its mind and closed it to the original commit? And probably erased the January version of the diff and went back to November 18?
The patch was closed by Phabricator since it discovered a "new" commit from git for this patch while assuming that the committed version is the most recent one. Eli re-opened it suspecting that we still might want to fix this.
lib/Transforms/Utils/LoopUtils.cpp | ||
---|---|---|
67 | Can we use 'if (PushBlocks.insert(PredBB).second)' |
These should be in order. I think running clang-format on the patch will do that for you.