https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70687
Bug ID: 70687 Summary: Undefined shift in change_zero_ext in combine.c Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: hjl.tools at gmail dot com Target Milestone: --- change_zero_ext in combine.c has else if (GET_CODE (x) == ZERO_EXTEND && GET_CODE (XEXP (x, 0)) == SUBREG && GET_MODE (SUBREG_REG (XEXP (x, 0))) == mode && subreg_lowpart_p (XEXP (x, 0))) { size = GET_MODE_PRECISION (GET_MODE (XEXP (x, 0))); x = SUBREG_REG (XEXP (x, 0)); } else continue; unsigned HOST_WIDE_INT mask = 1; mask <<= size; mask--; x = gen_rtx_AND (mode, x, GEN_INT (mask)); For (gdb) call debug_rtx (*src) (zero_extend:TI (subreg:DI (reg/v:TI 91 [ ixi ]) 0)) we got (gdb) call debug_rtx (*src) (zero_extend:TI (subreg:DI (reg/v:TI 91 [ ixi ]) 0)) (gdb) p size $9 = 64 (gdb) p sizeof (mask) $10 = 8 mask <<= size; is wrong here, which leads to (and:TI (reg/v:TI 91 [ ixi ]) (const_int 0 [0]))