[LLVMdev] Optimisation of select/cmp/br

Pete Calvert
Wed, 05 Feb 2014 04:37:48 -0000

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.

As way of justification, the code in question essentially comes from a C
function similar to:

   foo *check_for_data() {
     if(flag == FULL) {
       return data;
     } else {
       return NULL;
     }
   }

which is called by code that branches on whether the result is NULL.
After inlining and other optimisation passes I'm getting code like that
above.

Best,
Pete