[cfe-dev] Branches &,&&

Duncan P. N. Exon Smith dexonsmith at apple.com
Thu Jun 11 09:23:56 PDT 2015


> On 2015-Jun-11, at 06:06, Fisnik Kastrati <kastrati at informatik.uni-mannheim.de> wrote:
> I'm turning to you with regards to an unwanted optimization/un-optimization that clang++ (all versions that I tested, in the following link) is generating, see the code in the following link:
> http://goo.gl/oiTPX5
> The assembly code generated for both methods "amp", "ampamp" is the practically the same, when using the optimization       flag "-O3". However, I'm interested to have a single jump for the code in the method "amp", as branch misprediction penalty is very high otherwise. It should generate a single jump, when using single ampersand (&), something that icc13 is already doing (try it in the link above).
> Is there any optimization flag that I should set, in order to avoid this feature when using "-O3"?
> I made a similar question to the g++ community, however this seems to be a bug (performance bug) with g++.
> Thank you in advance
> F. 

For reference, here's the (slightly reduced) source code:
$ cat t.c
void foo(int x, int y);
void ampamp(int x, int y) {
  if (x < 3 && y > 10)
    foo(x, y);
void amp(int x, int y) {
  if ((x < 3) & (y > 10))
    foo(x, y);

This looks like an instruction selection issue.

The LLVM optimization passes reduce the `&&` case down to `&` --
neither case needs a branch here, since `y > 10` has no side effects
-- but then the instruction selector chooses a branchy instruction
sequence for some reason.

Note that -O0 and -O3 use completely different instruction selectors:
FastISel and SelectionDAG, respectively.  It looks like FastISel is
doing the obvious thing, but for some reason SelectionDAG reintroduces
a branch.

To answer the question you actually asked, I don't think there's a way
to choose FastISel at other optimization levels.

Perhaps you could file a PR?

More information about the cfe-dev mailing list