From patchwork Thu Jan 12 19:14:36 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Uros Bizjak X-Patchwork-Id: 135682 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 17C09B6F9D for ; Fri, 13 Jan 2012 06:14:57 +1100 (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=1327000498; h=Comment: DomainKey-Signature:Received:Received:Received:Received: MIME-Version:Received:Received:Date:Message-ID:Subject:From:To: Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=KbvSa74 hCBmVKXNTKICljGMeUXU=; b=ULTJgdc/pOuCbJoxPrJrLNjwRgvbIetTBw+gs/q PFw4MsJMU1MfY6wPQMOY7NSfRLsVgEGdz7rFJypBJagMQOzO1ymNHQj2DNaIrQr2 Rcc5PTnALRDBWxYl87FP8H73SX0hnjZp86dnHgR/YpH/FWRUI+Wnpxc84GmzDn3M dWVs= 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:MIME-Version:Received:Received:Date:Message-ID:Subject:From:To:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=E6FnXclRs00y0HR1J/RDFfGz6si7982Prak536T86wIbU3JeZwMdyinWvZ9H6K 5R7Vz1cTcmOgJ8nlqyVWIS9A8UfQy1/Q7DcY3pxHLxTY4XtnBMVEs3rAnXbufzEX N1T3zdW85nUlZ8UV5Ykfw7dEdxH6MY3nNJhiLHYYhucw8=; Received: (qmail 19666 invoked by alias); 12 Jan 2012 19:14:54 -0000 Received: (qmail 19656 invoked by uid 22791); 12 Jan 2012 19:14:53 -0000 X-SWARE-Spam-Status: No, hits=-2.3 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, TW_ZJ X-Spam-Check-By: sourceware.org Received: from mail-yw0-f47.google.com (HELO mail-yw0-f47.google.com) (209.85.213.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 12 Jan 2012 19:14:36 +0000 Received: by yhjj72 with SMTP id j72so1143599yhj.20 for ; Thu, 12 Jan 2012 11:14:36 -0800 (PST) MIME-Version: 1.0 Received: by 10.236.46.232 with SMTP id r68mr7987503yhb.80.1326395676178; Thu, 12 Jan 2012 11:14:36 -0800 (PST) Received: by 10.146.124.2 with HTTP; Thu, 12 Jan 2012 11:14:36 -0800 (PST) Date: Thu, 12 Jan 2012 20:14:36 +0100 Message-ID: Subject: [PATCH, rtl-optimization]: Fix PR 51821, 64bit > 32bit conversion produces incorrect results with optimizations From: Uros Bizjak To: gcc-patches@gcc.gnu.org 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! As discussed in the PR, attached testcase uncovers problem with the way peephole2 pas determines free registers to allocate temporary register. The problem was with the pattern such as: (insn 7 19 16 2 (parallel [ (set (reg:DI 0 ax [65]) (ashift:DI (const_int -1 [0xffffffffffffffff]) (reg:QI 2 cx [orig:63 shift_size ] [63]))) (clobber (reg:CC 17 flags)) ]) pr51821.c:8 489 {*ashldi3_doubleword} (expr_list:REG_DEAD (reg:QI 2 cx [orig:63 shift_size ] [63]) (expr_list:REG_UNUSED (reg:CC 17 flags) (expr_list:REG_UNUSED (reg:SI 1 dx) (expr_list:REG_EQUAL (ashift:DI (const_int -1 [0xffffffffffffffff]) (subreg:QI (reg/v:SI 2 cx [orig:63 shift_size ] [63]) 0)) (nil)))))) where DImode ax/dx register pair gets defined, while at the same time, one of the registers from the register pair gets marked as unused. Currently, peephole2 pass determines clobbered registers from DF life analysis, as the difference of registers, live before the insn sequence and after insn sequence. Unfortunately, as shown by attached testcase in the PR, this approach is not correct. In the above pattern, dx is considered "dead" due to (REG_UNUSED dx) note. The solution is to fix the scanning loop to look into the insn pattern itself for all set and clobbered hard registers. This way, all registers, clobbered by the pattern, will be correctly marked in the "live" bitmap, including FLAGS register that is ignored by current approach. 2012-01-12 Uros Bizjak * recog.c (peep2_find_free_register): Determine clobbered registers from insn pattern. testsuite/ChangeLog: 2012-01-12 Uros Bizjak * gcc.dg/pr51821.c: New test. Patch was bootstrapped and regression tested on x86_64-pc-linux-gnu. OK for mainline and release branches? Uros. Index: recog.c =================================================================== --- recog.c (revision 183130) +++ recog.c (working copy) @@ -3038,6 +3038,7 @@ peep2_find_free_register (int from, int to, const static int search_ofs; enum reg_class cl; HARD_REG_SET live; + df_ref *def_rec; int i; gcc_assert (from < MAX_INSNS_PER_PEEP2 + 1); @@ -3051,12 +3052,14 @@ peep2_find_free_register (int from, int to, const while (from != to) { - HARD_REG_SET this_live; + gcc_assert (peep2_insn_data[from].insn != NULL_RTX); + /* Don't use registers set or clobbered by the insn. */ + for (def_rec = DF_INSN_DEFS (peep2_insn_data[from].insn); + *def_rec; def_rec++) + SET_HARD_REG_BIT (live, DF_REF_REGNO (*def_rec)); + from = peep2_buf_position (from + 1); - gcc_assert (peep2_insn_data[from].insn != NULL_RTX); - REG_SET_TO_HARD_REG_SET (this_live, peep2_insn_data[from].live_before); - IOR_HARD_REG_SET (live, this_live); } cl = (class_str[0] == 'r' ? GENERAL_REGS Index: testsuite/gcc.dg/pr51821.c =================================================================== --- testsuite/gcc.dg/pr51821.c (revision 0) +++ testsuite/gcc.dg/pr51821.c (revision 0) @@ -0,0 +1,24 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -msse" { target { i?86-*-* x86_64-*-* } } } */ +/* { dg-require-effective-target sse_runtime { target { i?86-*-* x86_64-*-* } } } */ + +extern void abort (void); + +unsigned int __attribute__((noinline)) +test (int shift_size) +{ + unsigned long long res = ~0; + + return res << shift_size; +} + +int +main () +{ + int dst = 32; + + if (test (dst) != 0) + abort (); + + return 0; +}