--- a/gcc/bbb-opts.c +++ b/gcc/bbb-opts.c @@ -325,7 +325,17 @@ if (GET_CODE(src) == CONST_INT && (mode == HImode || mode == QImode)) { unsigned iv = UINTVAL(src); - setMask(regno, iv, mode); + /* output_move_himode and output_move_qimode load a data register's + word or byte constant in -128..127 with moveq, which writes all 32 + bits sign-extended, where a strict_low_part move keeps the upper + ones. A negative one (but a byte's -1, which is st) may so leave + the upper bits set: keeping their old mask let opt_elim_dead_assign2 + delete a later zero-extension's clear as superfluous. */ + if (regno < 8 && INTVAL(src) >= -128 && INTVAL(src) < 0 + && !(mode == QImode && INTVAL(src) == -1)) + setMask(regno, iv, SImode); + else + setMask(regno, iv, mode); value[regno] = gen_rtx_CONST_INT(mode, 0x100000000000000LL | ((long long int ) (regno) << 32) | index); used[regno] = 1 << FIRST_PSEUDO_REGISTER; clearRefsByMask(1<