InstCombine "pessimizes" trunc i8 to i1?

Hi!

before InstCombine (llvm::createInstructionCombiningPass()) I have
a trunc from i8 to i1 and then a select:

%45 = load i8* @myGlobal, align 1
%tobool = trunc i8 %45 to i1
%cond = select i1 %tobool, float 1.000000e+00, float -1.000000e+00

after instCombine I have:

%29 = load i8* @myGlobal, align 1
%30 = and i8 %29, 1
%tobool = icmp ne i8 %30, 0
%cond = select i1 %tobool, float 1.000000e+00, float -1.000000e+00

is this a bug or intended? My version is 3.0 release.
Please tell me where I can remove this rule even if it is intended for mainline.

-Jochen

This is intentional: an 'and' must be done in both cases, so this transformation is exposing it to the optimizer.

Why do you consider this to be a pessimization? Does one produce inferior machine code?

-Chris

Hi!

before InstCombine (llvm::createInstructionCombiningPass()) I have
a trunc from i8 to i1 and then a select:

%45 = load i8* @myGlobal, align 1
%tobool = trunc i8 %45 to i1
%cond = select i1 %tobool, float 1.000000e+00, float -1.000000e+00

after instCombine I have:

%29 = load i8* @myGlobal, align 1
%30 = and i8 %29, 1
%tobool = icmp ne i8 %30, 0
%cond = select i1 %tobool, float 1.000000e+00, float -1.000000e+00

is this a bug or intended? My version is 3.0 release.
Please tell me where I can remove this rule even if it is intended for
mainline.

This is intentional: an 'and' must be done in both cases, so this transformation is exposing it to the optimizer.

Why do you consider this to be a pessimization? Does one produce inferior machine code?

I consider it a pessimization as it is one additional instruction and I'm mainly interested in target
independent optimizations because I regenerate highlevel code from it
("Exporting 3D scenes from Maya to WebGL using clang and llvm").
For example from the given code before the transformation I can easily regenerate
myGlobal ? 1.0f : -1.0f
while after the transformation I get
(myGlobal & 1) != 0 ? 1.0f : -1.0f
which is not good for shading languages.

So I can remove the transformation in my local copy (I found it by now) or if it would be possible to
move it into the optimizer that needs it this would be benificial for me.

-Jochen

I think Chris is saying that the and is necessary because with your i1 trunc you’re ignoring all of the high bits. The and implements that. If you don’t want this behavior, don’t generate the trunc in the first place and just compare the full width to zero.

Reid

I think Chris is saying that the and is necessary because with your i1 trunc you’re ignoring all of the high bits. The and implements that. If you don’t want this behavior, don’t generate the trunc in the first place and just compare the full width to zero.

Right. Turning this into “myGlobal ? 1.0f : -1.0f” is not correct.

-Chris

But if a backend sees trunc from i8 to i1 it should know about the and, therefore I think replacing it by and is not
a target independent transformation. I'm not saying the and is wrong, I just think InstCombine is the wrong place
if InstCombine is supposed to be target independent (which is my assumption that is possibly wrong).
By the way i8 and trunc come from clang as clang represents a bool as i8 in memory. of course it would
be a nice feature if I could tell clang to always use i1 for bool, this would also remove the problem.
Is this possible?

-Jochen

By the way i8 and trunc come from clang as clang represents a bool as i8

in memory. of course it would
be a nice feature if I could tell clang to always use i1 for bool, this
would also remove the problem.
Is this possible?

-Jochen

#include <stdbool.h> ?

Sure, since that would be a different ABI, you would want to define your own clang target. You probably want this for other reasons anyway (calling conventions).

-Chris

Clang does treat bools as i1 in the IR output if you include stdbool. I had an issue a while back where I needed a function to return an i1 after compilation, and moving to Clang and including stdbool solved it (and it was Samuel who suggested it then as well, so thanks again :slight_smile: )

-Gordon