From patchwork Tue Jun 22 10:42:22 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bernd Schmidt X-Patchwork-Id: 56455 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 36078B6EF3 for ; Tue, 22 Jun 2010 20:42:39 +1000 (EST) Received: (qmail 8001 invoked by alias); 22 Jun 2010 10:42:37 -0000 Received: (qmail 7989 invoked by uid 22791); 22 Jun 2010 10:42:36 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 22 Jun 2010 10:42:32 +0000 Received: (qmail 15581 invoked from network); 22 Jun 2010 10:42:30 -0000 Received: from unknown (HELO ?84.152.254.46?) (bernds@127.0.0.2) by mail.codesourcery.com with ESMTPA; 22 Jun 2010 10:42:30 -0000 Message-ID: <4C20938E.2060606@codesourcery.com> Date: Tue, 22 Jun 2010 12:42:22 +0200 From: Bernd Schmidt User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.9) Gecko/20100618 Thunderbird/3.0.4 MIME-Version: 1.0 To: GCC Patches Subject: combine/dce patch for PR36003, PR42575 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 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);