https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66148
Thomas Preud'homme <thopre01 at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2015-05-25 Assignee|unassigned at gcc dot gnu.org |thopre01 at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #4 from Thomas Preud'homme <thopre01 at gcc dot gnu.org> --- The patch set out to use information from REG_EQUAL notes to get more accurate nonzero_bits value. When compiling the testcase with commit r223033 (the one just before the bug is seen) and options -O2 -fno-exceptions -fno-rtti -fasynchronous-unwind-tables I can see: (insn 360 358 361 27 (set (reg:DI 549) (const_int -822083584 [0xffffffffcf000000])) ../../gcc/gcc/genpreds.c:983 123 {*pa.md:4196} (expr_list:REG_EQUAL (const_int 3472883712 [0xcf000000]) (nil))) Here the REG_EQUAL does not match the value that is set: the 32 most significant bits are zero. Which is why combine decide that the set of zero_extract can be removed. Looking at the dumps of the various pass, everything looks fine until cse1 where instruction 360 is replaced from: (insn 360 359 361 32 (set (reg:DI 549) (lo_sum:DI (reg:DI 550) (const_int -822083584 [0xffffffffcf000000]))) ../../gcc/gcc/genpreds.c:983 93 {*pa.md:2773} (expr_list:REG_EQUAL (const_int 3472883712 [0xcf000000]) (nil))) to: (insn 360 359 361 32 (set (reg:DI 549) (const_int -822083584 [0xffffffffcf000000])) ../../gcc/gcc/genpreds.c:983 123 {*pa.md:4196} (expr_list:REG_DEAD (reg:DI 550) (expr_list:REG_EQUAL (const_int 3472883712 [0xcf000000]) (nil)))) without the REG_EQUAL note being updated. The replacement is made by the else if in cse.c with the following comment: /* Look for a substitution that makes a valid insn. */ I'm not sure what component is at fault here (my guess is that cse is not expected to update the note directly but probably some other function) and I am thus not very sure who to reassign this bug to.