Unnecessary i16 -> i32 type promotion

If I have an ‘&’ operator inside an ‘if’ statement, LLVM seems to always promote a 16 bit integer type to a 32 bit integer type. I don’t want this to happen because my back-end only supports 16 bit types. Why is this happening? Where might this be happening, so I can fix it? It doesn’t seem to happen with the ‘|’ operator, only ‘&’. Thanks!

Code is below. Relevant code highlighted in bold.

C Function:

If I have an '&' operator inside an 'if' statement, LLVM seems to always
promote a 16 bit integer type to a 32 bit integer type.

The front-end does the promotion because the semantics of C require
it. In some cases, LLVM is smart enough to eliminate the promotion,
but it doesn't happen to catch this case.

I don't want this
to happen because my back-end only supports 16 bit types. Why is this
happening? Where might this be happening, so I can fix it? It doesn't seem
to happen with the '|' operator, only '&'. Thanks!

In that case, you should be telling the front-end to compile code for
a target which defines "int" to a 16-bit type. "i386-pc-linux-gnu" is
not such a target. Note that you might want to look into using clang;
from what I know, it's relatively easier to add a new target to clang
compared to llvm-gcc.

Also,you might want to look into using the LLVM CodeGen
infrastructure, among other things, it provides a "legalization" pass
which transforms operations using types which the target doesn't
support into operations using types which the target supports.

-Eli

Hello, Marc

If I have an '&' operator inside an 'if' statement, LLVM seems to
always promote a 16 bit integer type to a 32 bit integer type. I
don't want this to happen because my back-end only supports 16 bit
types. Why is this happening?

Because 1 is a 32-bit constant

Where might this be happening, so I can fix it?

Is you 'int' type 16 or 32 bit? If 16 bit - you cannot use the IR in
question, since it was generated for the 32-bit target. Otherwise - you
cannot do anything - these are C language rules.

It doesn't seem to happen with the '|' operator, only '&'.

Right, because this effectively clears top 16 bit.