[LLVMdev] A case where llvm created different cfg for same code
Sheng Zhou
zhousheng at autoesl.com
Thu Aug 14 02:46:05 PDT 2008
Duncan Sands 写道:
> Hi,
>
>
>> 7 for(i=0; i<j && i+j+1<N; i++) {
>>
>> 8 for(i=0; i<j && i<N-j-1; i++) {
>>
>
> the arithmetic might overflow in one of these
> but not in the other.
>
ok, finally I found the reason.
First, the llvm-gcc with -O0 will emit same cfg for the two forms of codes.
In the loop of Line 7/8, the "i<j" and "i+j+1<N or i < N-j-1" each
occupies one basic block with a exit edge to the same successor basic block.
hence the loop has two exit edges.
Several passes will optimize the cfg and the ll code.
The final difference of the two cfg is due to pass licm and simplifycfg.
The licm will move the common expression out of the loop, like "j+1" and
"N-j-1", thus the basic block for "i < N-j-1" will finally has only two
instruction: the cmp and the branchInst. basic block for "i+j+1<N" has
an addtional "adder" in it.
The pass simplifycfg has a process function :
static bool FoldBranchToCommonDest(BranchInst *BI)
Its comments :
"/// FoldBranchToCommonDest - If this basic block is ONLY a setcc and a
branch,
/// and if a predecessor branches to us and one of our successors, fold the
/// setcc into the predecessor and use logical operations to pick the right
/// destination."
So, as the basicblock for "i < N -j-1" has just has cmp and branchinst,
it will be folded, and hence get a better cfg.
The basicblock for "i+j+1<N", as having additional "adder", leaves.
So my question is: can we loose the constraint "ONLY a setcc and a
branch" ? why it's necessary?
> Best wishes,
>
> Duncan.
>
More information about the llvm-dev
mailing list