[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 
/// 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