http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50696
--- Comment #5 from H.J. Lu <hjl.tools at gmail dot com> 2011-10-11 23:29:05 UTC --- This patch changes combine not to generate: (plus:DI (subreg:DI (mult:SI (reg/v:SI 85 [ i ]) (const_int 4 [0x4])) 0) (subreg:DI (reg:SI 100) 0)) and changes const_32bit_mask to match what combine may generate: diff --git a/gcc/combine.c b/gcc/combine.c index 6c3b17c..147d158 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -6905,10 +6905,17 @@ expand_compound_operation (rtx x) tem = gen_lowpart (mode, XEXP (x, 0)); if (!tem || GET_CODE (tem) == CLOBBER) return x; - tem = simplify_shift_const (NULL_RTX, ASHIFT, mode, - tem, modewidth - pos - len); - tem = simplify_shift_const (NULL_RTX, unsignedp ? LSHIFTRT : ASHIFTRT, - mode, tem, modewidth - len); + if (GET_CODE (x) == ZERO_EXTEND) + tem = gen_rtx_AND (mode, tem, + GEN_INT (GET_MODE_MASK (GET_MODE (XEXP (x, 0))))); + else + { + tem = simplify_shift_const (NULL_RTX, ASHIFT, mode, + tem, modewidth - pos - len); + tem = simplify_shift_const (NULL_RTX, + unsignedp ? LSHIFTRT : ASHIFTRT, + mode, tem, modewidth - len); + } } else if (unsignedp && len < HOST_BITS_PER_WIDE_INT) tem = simplify_and_const_int (NULL_RTX, GET_MODE (x), diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 349f5b0..03da1fb 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -600,8 +600,8 @@ ;; Match exactly 0x0FFFFFFFF in anddi as a zero-extension operation (define_predicate "const_32bit_mask" (and (match_code "const_int") - (match_test "trunc_int_for_mode (INTVAL (op), DImode) - == (HOST_WIDE_INT) 0xffffffff"))) + (match_test "(trunc_int_for_mode (INTVAL (op), DImode) & (HOST_WIDE_INT) 0xffffff00) + == (HOST_WIDE_INT) 0xffffff00"))) ;; Match 2, 4, or 8. Used for leal multiplicands. (define_predicate "const248_operand"