From patchwork Mon Jun 14 23:09:12 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Brook X-Patchwork-Id: 55595 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 614F91007D2 for ; Tue, 15 Jun 2010 09:09:26 +1000 (EST) Received: (qmail 2596 invoked by alias); 14 Jun 2010 23:09:24 -0000 Received: (qmail 2579 invoked by uid 22791); 14 Jun 2010 23:09:23 -0000 X-SWARE-Spam-Status: No, hits=-1.9 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; Mon, 14 Jun 2010 23:09:18 +0000 Received: (qmail 32319 invoked from network); 14 Jun 2010 23:09:16 -0000 Received: from unknown (HELO wren.localnet) (paul@127.0.0.2) by mail.codesourcery.com with ESMTPA; 14 Jun 2010 23:09:16 -0000 From: Paul Brook To: gcc-patches@gcc.gnu.org Subject: [PATCH] Fix CSE bogus RTL creation Date: Tue, 15 Jun 2010 00:09:12 +0100 User-Agent: KMail/1.13.3 (Linux/2.6.33-2-amd64; KDE/4.4.4; x86_64; ; ) MIME-Version: 1.0 Message-Id: <201006150009.13542.paul@codesourcery.com> 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 The patch below fixes a bug observed on an ARM target. The problematic code starts with (mem (plus (reg) (reg))). CSE then replaces the first REG by a CONST_INT. This results in invalid rtl: (plus (const_int) (reg)) - it is expected that the CONST_INT be the second argument of the PLUS. This works its way through the compiler and ends up confusing the assembly output patterns. The patch below fixes this by calling simplify_rtx if any substitutions are done. This should ensure that the result if canonical RTL. My original fix tested specifically for my example above. However it was suggested that I should use simplify_rtx instead, to catch similar latent bugs. Unfortunately the original testcase if very large and fragile. I am unable to construct a testcase to reproduce this reliably. Tested on arm-none-eabi and x86_64-linux. Ok? Paul 2010-06-14 Paul Brook gcc/ * cse.c (cse_process_notes_1): Call simplify_rtx is a substitution was made. Index: gcc/cse.c =================================================================== --- gcc/cse.c (revision 160724) +++ gcc/cse.c (working copy) @@ -5989,6 +5989,7 @@ cse_process_notes_1 (rtx x, rtx object, enum rtx_code code = GET_CODE (x); const char *fmt = GET_RTX_FORMAT (code); int i; + bool did_change = false; switch (code) { @@ -6057,7 +6058,18 @@ cse_process_notes_1 (rtx x, rtx object, for (i = 0; i < GET_RTX_LENGTH (code); i++) if (fmt[i] == 'e') validate_change (object, &XEXP (x, i), - cse_process_notes (XEXP (x, i), object, changed), 0); + cse_process_notes (XEXP (x, i), object, &did_change), 0); + + /* We may need to rebuild the expression after substitution. + e.g. if the first operand of a PLUS is replaced by a constant. */ + if (did_change) + { + rtx simplified; + *changed = true; + simplified = simplify_rtx(x); + if (simplified) + x = simplified; + } return x; }