From patchwork Thu Aug 9 11:13:44 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Belevantsev X-Patchwork-Id: 176054 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 966BE2C0085 for ; Thu, 9 Aug 2012 21:14:14 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1345115654; h=Comment: DomainKey-Signature:Received:Received:Received:Received: Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject: Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=XhLOUEi PKaen9WtVoMjchbOBUTs=; b=Dp7ZujNhHL3LCvIsNfV09R1Tw0lFr5U66NiVrm1 s/JXp9P1eRFSu61GPxTD56BrX7mvLJz3jg71oGDIlH7RIWdbDlKLOb4gPzL+FC/j CN6D+F6LLBE4bdglY3kYYf87ECyYjlYCvGjybuIqzOXzYFrHor6nwoi6R/JBlTj6 XqQw= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:Content-Type:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=ttw6fGni63T6s0Vu+DE2GKrwvhLWvs2I5Bhk2n2mKbYuezPLiGUO7JQpzejfqh t6BWvbNGtwD+xSdd60C7fiSZw3qeHGrXvdN1W6Y0J0kaMcQs7AZ49uB45gvrc/bs ueoJyqQ3i4hZ8MVGxgEBhAQjrMxC0snwBHQ+aq88le9lk=; Received: (qmail 5578 invoked by alias); 9 Aug 2012 11:14:10 -0000 Received: (qmail 5552 invoked by uid 22791); 9 Aug 2012 11:14:09 -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.ispras.ru (HELO mail.ispras.ru) (83.149.199.43) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 09 Aug 2012 11:13:50 +0000 Received: from [10.10.3.52] (unknown [83.149.199.44]) by mail.ispras.ru (Postfix) with ESMTP id 7E10A24F7BB; Thu, 9 Aug 2012 15:13:48 +0400 (MSK) Message-ID: <50239B68.1010208@ispras.ru> Date: Thu, 09 Aug 2012 15:13:44 +0400 From: Andrey Belevantsev User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:15.0) Gecko/20120731 Thunderbird/15.0 MIME-Version: 1.0 To: GCC Patches CC: Alexander Monakov Subject: Fix PR 53701 X-IsSubscribed: yes 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 Hello, The problem in question is uncovered by the recent speculation patch, it is in the handling of expressions blocked by bookkeeping. Those are expressions that become unavailable due to the newly created bookkeeping copies. In the original algorithm the supported insns and transformations cannot lead to this result, but when handling non-separable insns or creating speculative checks that unpredictably block certain insns the situation can arise. We just filter out all such expressions from the final availability set for correctness. The PR happens because the expression being filtered out can be transformed while being moved up, thus we need to look up not only its exact pattern but also all its previous forms saved in its history of changes. The patch does exactly that, I also clarified the comments w.r.t. this situation. Bootstrapped and tested on ia64 and x86-64, the PR testcase is minimized, too. OK for trunk? Also need to backport this to 4.7 with PR 53975, say on the next week. Yours, Andrey gcc: 2012-08-09 Andrey Belevantsev PR rtl-optimization/53701 * sel-sched.c (vinsn_vec_has_expr_p): Clarify function comment. Process not only expr's vinsns but all old vinsns from expr's history of changes. (update_and_record_unavailable_insns): Clarify comment. testsuite: 2012-08-09 Andrey Belevantsev PR rtl-optimization/53701 * gcc.dg/pr53701.c: New test. diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c index 3099b92..f0c6eaf 100644 --- a/gcc/sel-sched.c +++ b/gcc/sel-sched.c @@ -3564,29 +3564,41 @@ process_use_exprs (av_set_t *av_ptr) return NULL; } -/* Lookup EXPR in VINSN_VEC and return TRUE if found. */ +/* Lookup EXPR in VINSN_VEC and return TRUE if found. Also check patterns from + EXPR's history of changes. */ static bool vinsn_vec_has_expr_p (vinsn_vec_t vinsn_vec, expr_t expr) { - vinsn_t vinsn; + vinsn_t vinsn, expr_vinsn; int n; + unsigned i; - FOR_EACH_VEC_ELT (vinsn_t, vinsn_vec, n, vinsn) - if (VINSN_SEPARABLE_P (vinsn)) - { - if (vinsn_equal_p (vinsn, EXPR_VINSN (expr))) - return true; - } - else - { - /* For non-separable instructions, the blocking insn can have - another pattern due to substitution, and we can't choose - different register as in the above case. Check all registers - being written instead. */ - if (bitmap_intersect_p (VINSN_REG_SETS (vinsn), - VINSN_REG_SETS (EXPR_VINSN (expr)))) - return true; - } + /* Start with checking expr itself and then proceed with all the old forms + of expr taken from its history vector. */ + for (i = 0, expr_vinsn = EXPR_VINSN (expr); + expr_vinsn; + expr_vinsn = (i < VEC_length (expr_history_def, + EXPR_HISTORY_OF_CHANGES (expr)) + ? VEC_index (expr_history_def, + EXPR_HISTORY_OF_CHANGES (expr), + i++)->old_expr_vinsn + : NULL)) + FOR_EACH_VEC_ELT (vinsn_t, vinsn_vec, n, vinsn) + if (VINSN_SEPARABLE_P (vinsn)) + { + if (vinsn_equal_p (vinsn, expr_vinsn)) + return true; + } + else + { + /* For non-separable instructions, the blocking insn can have + another pattern due to substitution, and we can't choose + different register as in the above case. Check all registers + being written instead. */ + if (bitmap_intersect_p (VINSN_REG_SETS (vinsn), + VINSN_REG_SETS (expr_vinsn))) + return true; + } return false; } @@ -5694,8 +5706,8 @@ update_and_record_unavailable_insns (basic_block book_block) || EXPR_TARGET_AVAILABLE (new_expr) != EXPR_TARGET_AVAILABLE (cur_expr)) /* Unfortunately, the below code could be also fired up on - separable insns. - FIXME: add an example of how this could happen. */ + separable insns, e.g. when moving insns through the new + speculation check as in PR 53701. */ vinsn_vec_add (&vec_bookkeeping_blocked_vinsns, cur_expr); } diff --git a/gcc/testsuite/gcc.dg/pr53701.c b/gcc/testsuite/gcc.dg/pr53701.c new file mode 100644 index 0000000..2c85223 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr53701.c @@ -0,0 +1,59 @@ +/* { dg-do compile { target powerpc*-*-* ia64-*-* i?86-*-* x86_64-*-* } } */ +/* { dg-options "-O3 -fselective-scheduling2 -fsel-sched-pipelining" } */ +typedef unsigned short int uint16_t; +typedef unsigned long int uintptr_t; +typedef struct GFX_VTABLE +{ + int color_depth; + unsigned char *line[]; +} +BITMAP; +extern int _drawing_mode; +extern BITMAP *_drawing_pattern; +extern int _drawing_y_anchor; +extern unsigned int _drawing_x_mask; +extern unsigned int _drawing_y_mask; +extern uintptr_t bmp_write_line (BITMAP *, int); + void +_linear_hline15 (BITMAP * dst, int dx1, int dy, int dx2, int color) +{ + int w; + if (_drawing_mode == 0) + { + int x, curw; + unsigned short *sline = + (unsigned short *) (_drawing_pattern-> + line[((dy) - + _drawing_y_anchor) & _drawing_y_mask]); + unsigned short *s; + unsigned short *d = + ((unsigned short *) (bmp_write_line (dst, dy)) + (dx1)); + s = ((unsigned short *) (sline) + (x)); + if (_drawing_mode == 2) + { + } + else if (_drawing_mode == 3) + { + do + { + w -= curw; + do + { + unsigned long c = (*(s)); + if (!((unsigned long) (c) == 0x7C1F)) + { + (*((uint16_t *) ((uintptr_t) (d))) = ((color))); + } + ((s)++); + } + while (--curw > 0); + s = sline; + curw = + (((w) < + ((int) _drawing_x_mask + + 1)) ? (w) : ((int) _drawing_x_mask + 1)); + } + while (curw > 0); + } + } +}