Disabling select instructions

Hi,

I would like to know if there’s a way to avoid select instructions during the IR generation. What are the optimization passes that can result in a select instruction?
i.e. I want to preserve branches in my code without disabling any other optimizations applicable.

For example,
void foo(int* x, int* y){
if(*x > 0){
*y = *x + 10;
}
else{
*y = *x + 20;
}
}

with O1 I get,

define void @foo(i32* nocapture readonly, i32* nocapture) local_unnamed_addr #0 {
%3 = load i32, i32* %0, align 4, !tbaa !2
%4 = icmp sgt i32 %3, 0
%5 = select i1 %4, i32 10, i32 20
%6 = add nsw i32 %5, %3
store i32 %6, i32* %1, align 4, !tbaa !2
ret void
}

But with O0,

define void @foo(i32*, i32*) #0 {
%3 = alloca i32*, align 8
%4 = alloca i32*, align 8
store i32* %0, i32** %3, align 8
store i32* %1, i32** %4, align 8
%5 = load i32*, i32** %3, align 8
%6 = load i32, i32* %5, align 4
%7 = icmp sgt i32 %6, 0
br i1 %7, label %8, label %13

; :8: ; preds = %2
%9 = load i32*, i32** %3, align 8
%10 = load i32, i32* %9, align 4
%11 = add nsw i32 %10, 10
%12 = load i32*, i32** %4, align 8
store i32 %11, i32* %12, align 4
br label %18

; :13: ; preds = %2
%14 = load i32*, i32** %3, align 8
%15 = load i32, i32* %14, align 4
%16 = add nsw i32 %15, 20
%17 = load i32*, i32** %4, align 8
store i32 %16, i32* %17, align 4
br label %18

; :18: ; preds = %13, %8
ret void
}

Thanks,
Charitha

Several different passes introduce select instructions, such as InstCombine, SimplifyCFG, and SROA. Searching for calls to "CreateSelect" in the source tree should give you a fairly complete list.

It may be better to let the optimization pipeline proceed undisturbed, but then run a custom pass at the end that turns selects back into control flow. This would be an easy pass to write.

John

I agree with John; also, if you decide to go this route, you can reuse the code from CodeGenPrepare::optimizeSelectInst:

https://github.com/llvm/llvm-project/blob/master/llvm/lib/CodeGen/CodeGenPrepare.cpp#L6065

Alexey

I highly appreciate your suggestions*.* can someone explain how to add this type of pass to the optimization pipeline (probably point to code where optimization pipeline is built). Or can I do this using LLVM opt?

This will answer most of your questions:

http://llvm.org/docs/WritingAnLLVMPass.html

The easy way to go here is to write your pass out-of-tree and load it dynamically.

John