https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91860
Jim Wilson <wilson at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |ASSIGNED Last reconfirmed| |2019-10-08 Assignee|unassigned at gcc dot gnu.org |wilson at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #8 from Jim Wilson <wilson at gcc dot gnu.org> --- The third and fourth testcases are i2src problems, just like the first testcase. Since fixing this in combine looks complicated, I took a look at the RTL simplifier. Using the fourth testcase as my example, the problem here is that we are trying to substitute (sign_extend:DI (const_int 8160 [0x1fe0])) as the value for (reg:DI 78 [ _9 ]) in the debug insn (debug_insn 29 28 30 2 (var_location:QI d (subreg:QI (reg:DI 78 [ _9 ]) 0)) "tm\ p4.c":11:5 -1 (nil)) The place where this starts to go wrong is in simplify_truncation, where it tries to compare the size of the original mode (VOIDmode) with the subreg mode (QI) and decides that we need to sign extend the constant to convert it from VOIDmode to QImode. We actually need a truncation not a extension here. This then goes even further wrong in simplify_const_unary_operation which does scalar_int_mode imode = (op_mode == VOIDmode ? result_mode : as_a <scalar_int_mode> (op_mode)); which treats the CONST_INT as a QImode value, but it isn't a valid QImode CONST_INT valid due to lack of QImode sign-extension, so the following wide_int::from call triggers an consistency check and we abort. I see a number of places in simplify-rtx where it assumes that if an input is VOIDmode then it should use MAX_MODE_INT instead as a CONST_INT should always be already extended in canonical form. This seems to be the correct fix, which I want to put in simplify_truncation so that we aren't passing VOIDmode to GET_MODE_UNIT_PRECISION. I verified that this works for all four testcases.