[LLVMdev] Optimisation of select/cmp/br

James Courtier-Dutton
Wed, 05 Feb 2014 08:42:28 -0000

On 5 February 2014 04:37, Pete Calvert <prc33 at cam.ac.uk>
wrote:
> Hi,
>
> Is there anyway I can coerce LLVM into performing the following
> transformation?
>
>   %1 = icmp eq i32 %flag, 1
>   %2 = select i1 %1, %foo* %data, %struct.cell_t* null
>   %3 = icmp eq %foo* %2, null
>   br i1 %3, label %failure, label %success
>
> Into:
>
>   %1 = icmp eq i32 %flag, 1
>   br i1 %1, label %success, label %failure
>
> With %data substituted for %2 in %success and its successors, and null for
> %2 in %failure. The way that code generation deals with the select means
> that this is actually making a small but noticeable difference to
> performance due to the number of branches involved.
>

I think the first step in optimization here is to be able to convert:
%1 = icmp eq i32 %flag, 1
%2 = select i1 %1, %foo* %data, %struct.cell_t* null
%3 = icmp eq %foo* %2, null
br i1 %3, label %failure, label %success

to
%1 = icmp eq i32 %flag, 1
%2 = select i1 %1, %foo* %data, %struct.cell_t* null
%3 = icmp eq i32 %flag, 1
br i1 %3, label %failure, label %success

This would then permit instruction %2 to move down past the br.
This could also be achieved, in the short term, by changing your
source code to base  the if after return on "flag" instead of the
returned value being NULL.