[LLVMdev] Incorrect Simple pattern matching in lib/CodeGen/IfConversion.cpp
Stefan Hepp
stefan at stefant.org
Wed Feb 6 08:12:03 PST 2013
Hello!
The if-converter tries to match 'Simple' patterns looking like this:
// Simple (split, no rejoin):
// EBB
// | \_
// | |
// | TBB---> exit
// |
// FBB
The IfConverter::ValidSimple method (lib/CodeGen/IfConversion.cpp:461)
checks if TBB matches this pattern. It basically does this by simply
checking if AnalyseBranch fails on that block (IfConversion.cpp:640).
This fails if TBB contains something that AnalyseBranch is not able to
understand but is still a branch and may have fallthrough edges.
In my case, TBB ends with a predicated indirect branch, which comes from
a jumptable-jump that has been if-converted into TBB, i.e., TBB can
either jump to some computed address or fall through to the next block.
AnalyzeBranch returns true on that block since it is not a simple
conditional jump. ValidSimple however assumes that since IsBrAnalysable
is false, TBB does not branch and does not fall through, therefore the
if-converter merges EBB and TBB, adding FBB as fall-through to the new
block, and the fallthrough block of TBB is no longer reached. This
causes the compiled program to execute FBB instead of the
fallthrough-block of TBB, leading to incorrect behaviour.
I added the following check to IfConverter::ValidSimple(), which fixes
my problems:
if (!TrueBBI.BB->succ_empty())
return false;
but I have no idea if there is a less conservative way of checking for
the Simple pattern (e.g., an unconditional indirect jump might still be
allowed at the end of TBB).
I use the code from the LLVM 3.2 release, but it is basically the same
in LLVM 3.1 and in head.
Regards,
Stefan
More information about the llvm-dev
mailing list