The machine operation performed in `casesi_internal_mips16_<mode>'s assembly is SLTU, which just like the `ltu' RTL operation expresses the less-than operation rather than less-than-or-equal usually performed by `casesi' patterns. This is because there is no suitable single MIPS16 hardware instruction for the less-than-or-equal operation. This however is already taken into account by the caller, `casesi', by incrementing operand 1 before calling `casesi_internal_mips16_<mode>', so the overall calculation is equivalent.
So the generated assembly and consequently hardware operations are right and it is only the `casesi_internal_mips16_<mode>' insn whose RTL pattern does not match code produced. Also this insn is only ever emitted with an explicit call to `emit_jump_insn' from `casesi' and it is a solid assembly code block, so the mismatch does not affect code produced. Correct the RTL pattern then and use `ltu' rather than `leu' here. gcc/ * config/mips/mips.md (casesi_internal_mips16_<mode>): Use the `ltu' rather than `leu' operation in the RTL pattern --- OK to apply? Maciej gcc-mips16-casesi-ltu.diff Index: gcc/gcc/config/mips/mips.md =================================================================== --- gcc.orig/gcc/config/mips/mips.md 2016-11-09 18:57:01.883156298 +0000 +++ gcc/gcc/config/mips/mips.md 2016-11-09 20:15:10.392159385 +0000 @@ -6401,7 +6401,7 @@ (define_insn "casesi_internal_mips16_<mode>" [(set (pc) (if_then_else - (leu (match_operand:SI 0 "register_operand" "d") + (ltu (match_operand:SI 0 "register_operand" "d") (match_operand:SI 1 "arith_operand" "dI")) (unspec:P [(match_dup 0)