is createCFGSimplificationPass unused?

It looks like createCFGSimplificationPass was disabled on 2006/09/04.
This causes some problems for architectures that use conditional moves
to implement select (alpha and ARM). For example, on 2006/09/03 a "if
(a) return 0; else return 1;" compiled to

Please don't do that. Instead, please implement the TargetInstrInfo branch analysis hooks so that the branch folding pass can do this. Given info about branches, the pass already does various things to optimize away many of the things that simplify cfg does.

I'm planning several extensions to the pass, in particular to support limited forms of "predication" (PPC's conditional return for sure, perhaps some better cmov formation, etc). This may be generalizable for IA64/ARM, but it depends on how much time I have to work on it.

If there are specific cases like this where simplify cfg produces better code than branch folding (with the hooks implemented) please file bugzilla bugs to track them.

Long term, I'd like to get the code generator to the point where running the code generator doesn't modify from the input LLVM IR. Running llvm->llvm passes breaks this property.

Thanks,

-Chris

Please don't do that. Instead, please implement the TargetInstrInfo
branch analysis hooks so that the branch folding pass can do this.
Given info about branches, the pass already does various things to
optimize away many of the things that simplify cfg does.

I'm planning several extensions to the pass, in particular to support
limited forms of "predication" (PPC's conditional return for sure, perhaps
some better cmov formation, etc). This may be generalizable for IA64/ARM,
but it depends on how much time I have to work on it.

If there are specific cases like this where simplify cfg produces better
code than branch folding (with the hooks implemented) please file
bugzilla bugs to track them.

The branch folding works after instruction selection, right? It looks
strange to me that it will be able to convert a branch sequence into a
select. IMHO this transformation can be better performed with a higher
level representation.

Long term, I'd like to get the code generator to the point where running
the code generator doesn't modify from the input LLVM IR. Running
llvm->llvm passes breaks this property.

I see that this is a desired property. If I recall correctly, you need
this to remove the remaining annotations.

Maybe llvm-gcc should run CFGSimplification. It would then compile "if
(a) return 0; else return 1" into

%tmp = seteq int %a, 0
%tmp1 = select bool %tmp, int 0, int 1
ret int %tmp1

Thanks,
Rafael

This is not because of how it handles select. For example:

int %foo(int %x) {
%b = seteq int %x, 5
%r = select bool %b, int 3, int 7
ret int %r
}

int %bar(int %x) {
%b = seteq int %x, 5
br bool %b, label %t, label %f
t:
ret int 1
f:
ret int 2
}

compiles to:
foo:
        lda $0,3($31)
        zapnot $16,15,$1
        cmpeq $1,5,$1
        cmoveq $1,7,$0
        ret $31,($26),1
bar:
        zapnot $16,15,$0
        cmpeq $0,5,$0
        beq $0,$BB2_2 #f
$BB2_1: #t
        lda $0,1($31)
        ret $31,($26),1
$BB2_2: #f
        lda $0,2($31)
        ret $31,($26),1

Which is not a problem with the instruction selector's use of cmov.
It is that the IR is using a branch not a select. SimplifyCFG was
creating selects in the IR, which instruction select to cmovs. I
guess the question is is SimplifyCFG not run by default? It seems it
should be at the end of normal optimization chain, as it should be
much easier to lower selects to branches and optimize that (for those
targets that don't use cmov) than try to raise branches to selects at
isel time (for those that do use cmov).

Andrew

If there are specific cases like this where simplify cfg produces better
code than branch folding (with the hooks implemented) please file
bugzilla bugs to track them.

The branch folding works after instruction selection, right? It looks
strange to me that it will be able to convert a branch sequence into a
select. IMHO this transformation can be better performed with a higher
level representation.

Yes, for this specific one, you're right. Simplifycfg is run multiple times in the standard llvm-gcc -Ox pipeline. We don't expect the code generator to magically produce optimal code for random .ll fragments, we expect that it has been optimized a bit first. :slight_smile:

If there is a specific example like this that isn't picked up by -O2, please let me know.

Long term, I'd like to get the code generator to the point where running
the code generator doesn't modify from the input LLVM IR. Running
llvm->llvm passes breaks this property.

I see that this is a desired property. If I recall correctly, you need
this to remove the remaining annotations.

The desire is driven more by my abstract notion of purity than anything practical :). However, it is needed to do a credible job of reoptimization in a JIT context, is needed if you want to codegen to multiple target variants at once, etc. These are all things that LLVM can and should do, but I personally don't have a short term driver for them.

Maybe llvm-gcc should run CFGSimplification. It would then compile "if
(a) return 0; else return 1" into

%tmp = seteq int %a, 0
%tmp1 = select bool %tmp, int 0, int 1
ret int %tmp1

Yep, it definitely does. Make sure you're using llvm-gcc4 and passing -O2 or higher.

-Chris

If you write this in C and compile it with -O2, you should get the code you expect. If not, *please* file a bug.

-Chris

> Maybe llvm-gcc should run CFGSimplification. It would then compile "if
> (a) return 0; else return 1" into
>
> %tmp = seteq int %a, 0
> %tmp1 = select bool %tmp, int 0, int 1
> ret int %tmp1

Yep, it definitely does. Make sure you're using llvm-gcc4 and passing -O2
or higher.

Strange. I have run it now on my desktop, and it produces very good
code. I believe that the copy of llvm-gcc that I have in the laptop is
very old. I will check that latter.

-Chris

Thanks,
Rafael