I was looking through the InstCombine pass, and I was wondering why signed division is not considered a valid operation to combine in the canEvaluateTruncated function. This means, given the following code:

%conv = sext i16 %0 to i32
%conv1 = sext i16 %1 to i32
%div = sdiv i32 %conv, %conv1
%conv2 = trunc i32 %div to i16

Assume %0 and %1 are registers created from simple 16-bit loads.

We cannot reduce the sequence to:
%div = sdiv i16 %0 %1

What is the reason for the exclusion of sdiv from the operations considered valid for execution in a truncated format.

Just to verify, a 16-bit divion of INT16_MIN by -1 results in INT16_MIN again?

If the issue only occurs in this case, why arenâ€™t there checks to see if we can simplify sdiv in cases where we know that numerator is not INT16_MIN or the denominator is not -1. For example, we could simplify divides involving one operand constants. Is it because this case is most likely rare?

Just to verify, a 16-bit divion of INT16_MIN by -1 results in INT16_MIN
again?

No, "sdiv i16 -32768, -1" is undefined behaviour. The version with an
"sext" and "trunc" avoids the undefined behaviour and does return
-32768.

If the issue only occurs in this case, why aren't there checks to see if we
can simplify sdiv in cases where we know that numerator is not INT16_MIN or
the denominator is not -1. For example, we could simplify divides involving
one operand constants. Is it because this case is most likely rare?

It's probably just that no-one has bothered to implement it, I'd
actually expect the code to be reasonably common from C compilation.
Another factor is that RISC CPUs mostly won't care (they tend to only
have natural width division anyway), so that removes a large swathe of
people who might be interested.

Ohh, duh. Just did the math in my head. All makes sense now. Probably had the same thought process you were having when I initially thought it should be zero.