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 ---------------------------------------- zapnot $17,15,$1 zapnot $16,15,$2 bis $31,$31,$0 cmpeq $2,$1,$1 cmoveq $1,1,$0 ret $31,($26),1 ---------------------------------------- Now it compiles to ---------------------------------- zapnot $17,15,$0 zapnot $16,15,$1 cmpeq $1,$0,$0 beq $0,$BB1_2 #return $BB1_1: #cond_true bis $31,$31,$0 ret $31,($26),1 $BB1_2: #return lda $0,1($31) ret $31,($26),1 ---------------------------------- I have added createCFGSimplificationPass in ARMTargetMachine::addInstSelector to fix this problem. Is this the correct solution? I think that more architectures might benefit... Best Regards, Rafael
On Thu, 2 Nov 2006, [UTF-8] Rafael Esp?ndola wrote:> 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> I have added createCFGSimplificationPass in > ARMTargetMachine::addInstSelector to fix this problem. Is this the > correct solution? I think that more architectures might benefit...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 -- http://nondot.org/sabre/ http://llvm.org/
> 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
On 11/2/06, Rafael Espíndola <rafael.espindola at gmail.com> wrote:> 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 toThis 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
On Thu, 2 Nov 2006, Andrew Lenharth wrote:> On 11/2/06, Rafael Espíndola <rafael.espindola at gmail.com> wrote: >> 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 > > This is not because of how it handles select. For example: > int %bar(int %x) { > %b = seteq int %x, 5 > br bool %b, label %t, label %f > t: > ret int 1 > f: > ret int 2 > }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 -- http://nondot.org/sabre/ http://llvm.org/