From patchwork Tue Jun 29 19:12:46 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: RFC: PR rtl-optimization/44695: [4.6 Regression] ice in simplify_subreg, at simplify-rtx.c:5117 Date: Tue, 29 Jun 2010 09:12:46 -0000 From: H.J. Lu X-Patchwork-Id: 57300 Message-Id: <20100629191246.GA2770@intel.com> To: gcc-patches@gcc.gnu.org After revision 161329, x86 backend may generate: (ior:HI (ashift:HI (zero_extend:HI (umod:QI (reg:HI 68) (reg:QI 61 [ D.2750 ]))) (const_int 8 [0x8])) (zero_extend:HI (udiv:QI (reg:HI 68) (reg:QI 61 [ D.2750 ])))) combine calls simplify_subreg and leads to #2 0x00000000009ad621 in simplify_subreg (outermode=HImode, op=0x7ffff7facd40, innermode=QImode, byte=0) at /space/rguenther/src/svn/trunk/gcc/simplify-rtx.c:5116 5116 gcc_assert (GET_MODE (op) == innermode 5117 || GET_MODE (op) == VOIDmode); (gdb) call debug_rtx (op) (reg:HI 68) This patch adds simplify_gen_subreg_for_combine to deal with invalid combination of outermode, op and innermode generated by combine. Any comments? Thanks. H.J. --- gcc/ 2010-06-29 H.J. Lu PR rtl-optimization/44695 * combine.c (simplify_gen_subreg_for_combine): New. (if_then_else_cond): Replace simplify_gen_subreg with simplify_gen_subreg_for_combine. gcc/testsuite/ 2010-06-29 H.J. Lu PR rtl-optimization/44695 * gcc.dg/torture/pr44695.c: New. diff --git a/gcc/combine.c b/gcc/combine.c index d3305cb..0f1d315 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -423,6 +423,9 @@ static rtx simplify_shift_const_1 (enum rtx_code, enum machine_mode, rtx, int); static rtx simplify_shift_const (rtx, enum rtx_code, enum machine_mode, rtx, int); static int recog_for_combine (rtx *, rtx, rtx *); +static rtx simplify_gen_subreg_for_combine (enum machine_mode, rtx, + enum machine_mode, + unsigned int); static rtx gen_lowpart_for_combine (enum machine_mode, rtx); static enum rtx_code simplify_comparison (enum rtx_code, rtx *, rtx *); static void update_table_tick (rtx); @@ -7482,6 +7485,20 @@ canon_reg_for_combine (rtx x, rtx reg) return x; } +/* Like simplify_gen_subreg but for use by combine. Return NULL_RTX + if it is called with invalid combination of OUTERMODE, OP and + INNERMODE. */ + +static rtx +simplify_gen_subreg_for_combine (enum machine_mode outermode, rtx op, + enum machine_mode innermode, + unsigned int byte) +{ + if (GET_MODE (op) != innermode && GET_MODE (op) != VOIDmode) + return NULL_RTX; + return simplify_gen_subreg (outermode, op, innermode, byte); +} + /* Return X converted to MODE. If the value is already truncated to MODE we can just return a subreg even though in the general case we would need an explicit truncation. */ @@ -8222,10 +8239,12 @@ if_then_else_cond (rtx x, rtx *ptrue, rtx *pfalse) && 0 != (cond0 = if_then_else_cond (SUBREG_REG (x), &true0, &false0))) { - true0 = simplify_gen_subreg (mode, true0, - GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x)); - false0 = simplify_gen_subreg (mode, false0, - GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x)); + true0 = simplify_gen_subreg_for_combine (mode, true0, + GET_MODE (SUBREG_REG (x)), + SUBREG_BYTE (x)); + false0 = simplify_gen_subreg_for_combine (mode, false0, + GET_MODE (SUBREG_REG (x)), + SUBREG_BYTE (x)); if (true0 && false0) { *ptrue = true0; --- /dev/null 2010-06-16 10:11:06.602750711 -0700 +++ gcc/gcc/testsuite/gcc.dg/torture/pr44695.c 2010-06-29 11:49:12.186942482 -0700 @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +typedef unsigned char uint8_t; + +static uint8_t +safe_div_func_uint8_t_u_u (uint8_t ui1, uint8_t ui2) +{ + return ui2 ? ui2 : (ui1 / ui2); +} + +int +int81 (int x) +{ + return safe_div_func_uint8_t_u_u (1, 8 & x); +}