https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89679
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |ebotcazou at gcc dot gnu.org, | |law at gcc dot gnu.org --- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- If I change inside of the debugger that 0xffff in REG_EQUAL note to constm1_rtx, then the testcase is not miscompiled. The REG_EQUAL note is initially added by expand_mult_const: if (SCALAR_INT_MODE_P (mode)) { /* Write a REG_EQUAL note on the last insn so that we can cse multiplication sequences. Note that if ACCUM is a SUBREG, we've set the inner register and must properly indicate that. */ tem = op0, nmode = mode; accum_inner = accum; if (GET_CODE (accum) == SUBREG) { accum_inner = SUBREG_REG (accum); nmode = GET_MODE (accum_inner); tem = gen_lowpart (nmode, op0); } insn = get_last_insn (); wide_int wval_so_far = wi::uhwi (val_so_far, GET_MODE_PRECISION (as_a <scalar_mode> (nmode))); rtx c = immed_wide_int_const (wval_so_far, nmode); set_dst_reg_note (insn, REG_EQUAL, gen_rtx_MULT (nmode, tem, c), accum_inner); } As accum is a (subreg:HI (reg:SI 140) 0), it emits a REG_EQUAL note with paradoxical subreg in it: (insn 17 16 18 2 (set (reg:SI 140) (plus:SI (subreg:SI (reg:HI 138) 0) (subreg:SI (reg:HI 136) 0))) "pr89679.c":16:3 -1 (expr_list:REG_EQUAL (mult:SI (subreg:SI (reg:HI 136) 0) (const_int 257 [0x101])) (nil))) the note is already quite questionable, because the SImode register is not necessarily equal to that, the high 16 bits can be anything. If it is not valid, then we either must make sure not to emit a REG_EQUAL note in that case or emit it on some insn that sets a HImode reg rather than SImode. Note we emit that that way for quite a long time, I think since https://gcc.gnu.org/ml/gcc-patches/2000-12/msg00837.html This is related to the https://gcc.gnu.org/ml/gcc-patches/2016-04/msg00418.html change, though in this case we already have such a REG_EQUAL note that before the change can be at least determined to have a paradoxical subreg in it and so REG_EQUAL note consumers could take that into account. But if we simplify it into a CONST_INT or whatever else that doesn't have the paradoxical subreg in there anymore, this info is lost. We could e.g. do: --- gcc/fwprop.c.jj 2019-01-01 12:37:21.190908780 +0100 +++ gcc/fwprop.c 2019-03-12 17:24:14.623863160 +0100 @@ -1327,7 +1327,12 @@ forward_propagate_and_simplify (df_ref u { rtx note = find_reg_note (use_insn, REG_EQUAL, NULL_RTX); if (DF_REF_FLAGS (use) & DF_REF_IN_NOTE) - loc = &XEXP (note, 0); + { + loc = &XEXP (note, 0); + /* Don't simplify a paradoxical SUBREG in a REG_EQUAL note. */ + if (paradoxical_subreg_p (DF_REF_REG (use))) + return false; + } else loc = &SET_SRC (use_set); and thus not really simplify paradoxical subregs in REG_EQUAL notes, the notes will be then removed if we DCE the setters of corresponding pseudos. Thoughts on this?