Does LLVM optimize rudimentary i16 -> i32 conversions

In my language there are a lot of i16 definitions, but almost all of the time they are upgraded to i32 because my add operations only happen on i32.

So to be representative to my language definition, I have a lots of Sext/Zext and Truncs pretty much every time I add or subtract.

As soon as I pass through InstCombine things look much nicer, all the upcasts and downcasts go away, but my test cases are simple.

Is InstCombine pretty good about finding most/all such cases?

In general, yes. Other passes may catch cases InstCombine doesn’t. You may find some corner cases here and there. Bug reports or patches are very welcome. The largest area of potential concern is likely to be widdening/narrowing for induction variables in loops. I know we’ve hit one such issue recently.

I’m assuming you’re compiling for a 32 bit or 64 bit architecture. If not, the answer might be extremely different.


An important data point is if your uses are i16 also. trunc(sext(a) +
sext(b)) == a + b == trunc(zext(a) + zext(b)) always, so instcombine
should always be able to remove the truncs, sexts and zexts in these

However, if your uses are i32 uses (i.e. you compute sext(a) + sext(b)
and use that i32 value) then getting rid one of the sexts and
optimizing sext(a)+sext(b) to sext(a + b) cannot be done unless LLVM
has some extra information about the relative ranges of a and b (via
the nsw flag, via control flow etc.). Similar arguments apply for

-- Sanjoy