From patchwork Tue Jun 22 10:42:22 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: combine/dce patch for PR36003, PR42575 Date: Tue, 22 Jun 2010 00:42:22 -0000 From: Bernd Schmidt X-Patchwork-Id: 56455 Message-Id: <4C20938E.2060606@codesourcery.com> To: GCC Patches PR36003 is a problem where enabling pass_fast_rtl_byte_dce causes crashes in a cris compiler when the host is 64 bit. combine produces an insn of the form (set (cc0) (zero_extract:DI (subreg:SI (reg/v:DI 38 [ high ]) 0) (const_int 1 [0x1]) (const_int 0 [0x0]))) 16 {*btst} (nil)) The cris backend accepts this since it does not specify a mode for the zero_extract, but IMO this is invalid, as the documentation states If LOC is in a register, the mode to use is specified by the operand of the `insv' or `extv' pattern (*note Standard Names::) and is usually a full-word integer mode, which is the default if none is specified. [...] The mode M is the same as the mode that would be used for LOC if it were a register. which seems to imply that the zero_extract and its first operand should both have word_mode. The DImode zero_extract of a SImode value seems to confuse pass_fsat_rtl_byte_dce. In make_extraction, we have if (mode != VOIDmode && GET_MODE_SIZE (extraction_mode) < GET_MODE_SIZE (mode)) extraction_mode = mode; where extraction_mode will become the mode of the zero_extract, and mode is the mode of the object we're performing the extraction on. In this case, mode is DImode; we have (reg:DI 38) at this point - later in make_extraction we will create a subreg around it due to wanted_inner_reg_mode, which is SImode == word_mode. It seems to me that we shouldn't widen extraction_mode beyond wanted_inner_mode, so I've deleted the if statement quoted above. I've built various compilers (pa, m68k, arm, i686, cris) and compiled a large set of input files with and without this change, and I've not observed any differences in code generation. With this problem fixed, we can reenable byte DCE, which eliminates one insn in the PR42575 testcase. Bootstrap succeeded on i686-linux, regression tests in progress. Ok? Bernd PR middle-end/36003 PR rtl-optimization/42575 * combine.c (make_extraction): Don't widen extraction_mode to mode. * passes.c (init_optimization_passes): Reenable pass_fast_rtl_byte_dce. Index: combine.c =================================================================== --- combine.c (revision 161116) +++ combine.c (working copy) @@ -6835,12 +6835,6 @@ make_extraction (enum machine_mode mode, extraction_mode = mode_for_extraction (EP_extv, 0); } - /* Never narrow an object, since that might not be safe. */ - - if (mode != VOIDmode - && GET_MODE_SIZE (extraction_mode) < GET_MODE_SIZE (mode)) - extraction_mode = mode; - if (pos_rtx && GET_MODE (pos_rtx) != VOIDmode && GET_MODE_SIZE (pos_mode) < GET_MODE_SIZE (GET_MODE (pos_rtx))) pos_mode = GET_MODE (pos_rtx); Index: passes.c =================================================================== --- passes.c (revision 161116) +++ passes.c (working copy) @@ -1014,6 +1014,7 @@ init_optimization_passes (void) NEXT_PASS (pass_regmove); NEXT_PASS (pass_outof_cfg_layout_mode); NEXT_PASS (pass_split_all_insns); + NEXT_PASS (pass_fast_rtl_byte_dce); NEXT_PASS (pass_lower_subreg2); NEXT_PASS (pass_df_initialize_no_opt); NEXT_PASS (pass_stack_ptr_mod);