The 'callbr' instruction doesn't have a good place to put values from a
split critical edge. This is similar to indirect branch and case switch
instructions.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
I guess the presence of the profile data makes it difficult to use bugpoint to reduce the test case more?
The error isn't in opt but in llc though. In fact, I don't think it's specific to PGO, but only triggered by it.
Patch LGTM; just curious about the comment, since that's not what's occurring in the test AFAICT. Thanks for the patch!
llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp | ||
---|---|---|
5594–5595 | Can this comment be made more precise, I don't think what's described is what's being tested? | |
llvm/test/CodeGen/Generic/callbr-critical-edge-splitting.ll | ||
21 ↗ | (On Diff #316193) | (I'm surprised we can refer to values in the IR before they've been assigned to). |
llvm/test/CodeGen/Generic/callbr-critical-edge-splitting.ll | ||
---|---|---|
1 ↗ | (On Diff #316193) | Can you write a opt -passes='loop(loop-reduce)' test? Checking a command returns 0 is not a useful test. Checking some desired instructions makes the test not only useful for one particular regression, but also useful for some other scenarios. |
This is a code-gen bug. I'm not sure how else to put this. If I run it through opt, it doesn't reproduce.
llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp | ||
---|---|---|
5594–5595 | It's pretty accurate as is. :) I'm not sure how else to word it. | |
llvm/test/CodeGen/Generic/callbr-critical-edge-splitting.ll | ||
1 ↗ | (On Diff #316193) | It replicates only with llc, not with opt. |
21 ↗ | (On Diff #316193) | Might be some PHI node weirdness. |
llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp | ||
---|---|---|
5594–5595 | The change only affects llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp, not any codegen part, so I hope this can be tested with opt. Usually this should check the produced instructions. If the resulting IR is correct but codegen somehow crashes, then it is probably a codegen bug which should be separately fixed. If the output IR is actually incorrect, then the IR verifier should be fixed instead. Anyway I think the test should be added in an appropriate place and if this uncovers other issues those other issues should be reported as well. |
llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp | ||
---|---|---|
5594–5595 | Ah, yes sorry, I was looking at the first phi thinking WTF; didn't notice the second phi until just now. |
llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp | ||
---|---|---|
5594–5595 | It appears that this pass is added only during code-gen: llvm/lib/CodeGen/TargetPassConfig.cpp: addPass(createLoopStrengthReducePass()); llvm/lib/Passes/PassBuilder.cpp:#include "llvm/Transforms/Scalar/LoopStrengthReduce.h" llvm/lib/Passes/PassRegistry.def:LOOP_PASS("loop-reduce", LoopStrengthReducePass()) llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp:/// (LoopStrengthReduce.cpp) and memory optimization for address mode llvm/lib/Target/NVPTX/NVPTXISelLowering.h: /// reduction (LoopStrengthReduce.cpp) and memory optimization for llvm/lib/Transforms/Scalar/CMakeLists.txt: LoopStrengthReduce.cpp llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp://===- LoopStrengthReduce.cpp - Strength Reduce IVs in Loops --------------===// llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:#include "llvm/Transforms/Scalar/LoopStrengthReduce.h" llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:class LoopStrengthReduce : public LoopPass { llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp: LoopStrengthReduce(); llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:LoopStrengthReduce::LoopStrengthReduce() : LoopPass(ID) { llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp: initializeLoopStrengthReducePass(*PassRegistry::getPassRegistry()); llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:void LoopStrengthReduce::getAnalysisUsage(AnalysisUsage &AU) const { llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:bool LoopStrengthReduce::runOnLoop(Loop *L, LPPassManager & /*LPM*/) { llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:PreservedAnalyses LoopStrengthReducePass::run(Loop &L, LoopAnalysisManager &AM, llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:char LoopStrengthReduce::ID = 0; llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:INITIALIZE_PASS_BEGIN(LoopStrengthReduce, "loop-reduce", llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:INITIALIZE_PASS_END(LoopStrengthReduce, "loop-reduce", llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:Pass *llvm::createLoopStrengthReducePass() { return new LoopStrengthReduce(); } llvm/lib/Transforms/Scalar/Scalar.cpp: initializeLoopStrengthReducePass(Registry); |
llvm/test/CodeGen/Generic/callbr-critical-edge-splitting.ll | ||
---|---|---|
1 ↗ | (On Diff #316193) | I'm also having trouble reproducing with opt. If this relies on CodeGen specific transforms, do we need a target triple for the module? https://lists.llvm.org/pipermail/llvm-dev/2020-July/143666.html seems to allude to this problem (I haven't read the whole thread yet to see whether/how it's been resolved). |
llvm/test/CodeGen/Generic/callbr-critical-edge-splitting.ll | ||
---|---|---|
1 ↗ | (On Diff #316193) | adding target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" allows opt -loop-reduce /tmp/foo.ll -S -o - to repro. |
llvm/test/CodeGen/Generic/callbr-critical-edge-splitting.ll | ||
---|---|---|
1 ↗ | (On Diff #316193) | opt -mcpu=alderlake -loop-reduce -S /tmp/foo.ll repros also works; guessing that cpu specifies a datalayout? |
llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp | ||
---|---|---|
5594–5595 | Sorry. Fixed. |
llvm/test/Transforms/LoopStrengthReduce/callbr-critical-edge-splitting.ll | ||
---|---|---|
10 | The exiting edge (%do.body.i.i.rdrand_int.exit.i_crit_edge -> %for.end) is a critical edge. SplitBlockPredecessors is called with LoopPreds being BBs other than TIBB. | |
24 | Perhaps simplify the BB names. For example _crit_edge can be dropped as it is the name introduced by a previous critical edge breaking step. |
llvm/test/Transforms/LoopStrengthReduce/callbr-critical-edge-splitting.ll | ||
---|---|---|
24 | No. Please stop. I'm not going to rename BB names. That's just busy work. |
@nathanchance also pointed out I had https://reviews.llvm.org/D88438 to fix a similar issue (I forgot about that patch, I should try it with this test case, too).
This patch also fixes the test case in D88438 (and D88438 also fixes this test case). So two different ways of solving similar bugs.
(ie. either would fix https://github.com/ClangBuiltLinux/linux/issues/1161 and https://github.com/ClangBuiltLinux/linux/issues/1252). I don't feel strongly either way; maybe reviewers could take a look at both approaches?
This patch also fixes the test case in D88438 (and D88438 also fixes this test case).
Does that other review fix this test case intrinsically -- in that this patch is definitely not necessary if that is committed? Or might it just be fixed by accident -- e.g. this particular test-case doesn't trigger the problem anymore, but something else might, without this patch?
From the github links posted above; both traces from the unwind post-failed-assertion look the same. I assume this patch terminates LoopReduce sooner than D88438 would (though SplitCriticalEdge is called from many other passes than just LoopReduce).
Can this comment be made more precise, I don't think what's described is what's being tested?