From patchwork Mon Oct 27 20:47:20 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 403927 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42433140077 for ; Tue, 28 Oct 2014 07:48:37 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type; q=dns; s=default; b=fnVH0iq1aLlMXSegGq2Asv/57r/Jr GLywYJVIoTRVg55/4QKIXib6KzC8nUyQ2RK3PRFRdGqGWUkq6wrfNs3rIB21aaWn 2ZEe/4vqukW2iUDOfHXPySWWZwaSZLifucxSBX2qEZdpHM4IM89HN80dtZiF7aWI InzK9kIyfruCRY= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type; s=default; bh=KFDxGUnrfnqM4tY/6QSpjTgGmzs=; b=eAJ tFTpEMZiWoTW9/ud/C0o4fpTkfZbqDho/6xKcHOz6ObddxoXOzAqaGzGpC4SyYEH lkSHCyESHneQO+5zotgbFPml+qcluFuwEm7VouzHxNYdXeZls784swE6NMfxo/h0 VS/Ih0RYpS0sJ7vYbyEzyzc++vxcSQ/seeDqO1y4= Received: (qmail 1971 invoked by alias); 27 Oct 2014 20:47:29 -0000 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 Received: (qmail 1869 invoked by uid 89); 27 Oct 2014 20:47:28 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.5 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Mon, 27 Oct 2014 20:47:26 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s9RKlPOf011193 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Mon, 27 Oct 2014 16:47:25 -0400 Received: from tucnak.zalov.cz (ovpn-116-116.ams2.redhat.com [10.36.116.116]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s9RKlNB6027956 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Mon, 27 Oct 2014 16:47:24 -0400 Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.14.9/8.14.9) with ESMTP id s9RKlM8x011022; Mon, 27 Oct 2014 21:47:22 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.14.9/8.14.9/Submit) id s9RKlKGm009345; Mon, 27 Oct 2014 21:47:20 +0100 Date: Mon, 27 Oct 2014 21:47:20 +0100 From: Jakub Jelinek To: Jeff Law Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] Adjust/remove REG_EQ{UAL, UIV} notes in REE (PR rtl-optimization/63659) Message-ID: <20141027204720.GZ10376@tucnak.redhat.com> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-IsSubscribed: yes Hi! The following testcase is miscompiled in 4.8+ on x86_64 at -O2+, because REE widens for ZERO_EXTEND mode on (set (reg:QI ax) (const_int -1)) instruction to SImode, but doesn't adjust REG_EQUAL note of (const_int -1) also to (const_int 0xff) like it changes the pattern. The following patch attempts to adjust the notes if they are CONST_INT, or drop otherwise (not sure if it would be desirable to emit a ZERO_EXTEND of the previous content of the note), and both through validate_change, so that if we give up later on, it is undone. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? What about 4.9.2 (after release) and 4.8.x? 2014-10-27 Jakub Jelinek PR rtl-optimization/63659 * ree.c (update_reg_equal_equiv_notes): New function. (combine_set_extension, transform_ifelse): Use it. * gcc.c-torture/execute/pr63659.c: New test. Jakub --- gcc/ree.c.jj 2014-10-22 15:52:18.000000000 +0200 +++ gcc/ree.c 2014-10-27 19:18:37.287412478 +0100 @@ -266,6 +266,50 @@ typedef struct ext_cand static int max_insn_uid; +/* Update or remove REG_EQUAL or REG_EQUIV notes for INSN. */ + +static bool +update_reg_equal_equiv_notes (rtx_insn *insn, enum machine_mode new_mode, + enum machine_mode old_mode, enum rtx_code code) +{ + rtx *loc = ®_NOTES (insn); + while (*loc) + { + enum reg_note kind = REG_NOTE_KIND (*loc); + if (kind == REG_EQUAL || kind == REG_EQUIV) + { + rtx orig_src = XEXP (*loc, 0); + /* Update equivalency constants. Recall that RTL constants are + sign-extended. */ + if (GET_CODE (orig_src) == CONST_INT + && HOST_BITS_PER_WIDE_INT >= GET_MODE_BITSIZE (new_mode)) + { + if (INTVAL (orig_src) >= 0 || code == SIGN_EXTEND) + /* Nothing needed. */; + else + { + /* Zero-extend the negative constant by masking out the + bits outside the source mode. */ + rtx new_const_int + = gen_int_mode (INTVAL (orig_src) + & GET_MODE_MASK (old_mode), + new_mode); + if (!validate_change (insn, &XEXP (*loc, 0), + new_const_int, true)) + return false; + } + loc = &XEXP (*loc, 1); + } + /* Drop all other notes, they assume a wrong mode. */ + else if (!validate_change (insn, loc, XEXP (*loc, 1), true)) + return false; + } + else + loc = &XEXP (*loc, 1); + } + return true; +} + /* Given a insn (CURR_INSN), an extension candidate for removal (CAND) and a pointer to the SET rtx (ORIG_SET) that needs to be modified, this code modifies the SET rtx to a new SET rtx that extends the @@ -287,6 +331,7 @@ static bool combine_set_extension (ext_cand *cand, rtx_insn *curr_insn, rtx *orig_set) { rtx orig_src = SET_SRC (*orig_set); + enum machine_mode orig_mode = GET_MODE (SET_DEST (*orig_set)); rtx new_set; rtx cand_pat = PATTERN (cand->insn); @@ -323,9 +368,8 @@ combine_set_extension (ext_cand *cand, r { /* Zero-extend the negative constant by masking out the bits outside the source mode. */ - enum machine_mode src_mode = GET_MODE (SET_DEST (*orig_set)); rtx new_const_int - = gen_int_mode (INTVAL (orig_src) & GET_MODE_MASK (src_mode), + = gen_int_mode (INTVAL (orig_src) & GET_MODE_MASK (orig_mode), GET_MODE (new_reg)); new_set = gen_rtx_SET (VOIDmode, new_reg, new_const_int); } @@ -364,7 +408,9 @@ combine_set_extension (ext_cand *cand, r /* This change is a part of a group of changes. Hence, validate_change will not try to commit the change. */ - if (validate_change (curr_insn, orig_set, new_set, true)) + if (validate_change (curr_insn, orig_set, new_set, true) + && update_reg_equal_equiv_notes (curr_insn, cand->mode, orig_mode, + cand->code)) { if (dump_file) { @@ -414,7 +460,9 @@ transform_ifelse (ext_cand *cand, rtx_in ifexpr = gen_rtx_IF_THEN_ELSE (cand->mode, cond, map_srcreg, map_srcreg2); new_set = gen_rtx_SET (VOIDmode, map_dstreg, ifexpr); - if (validate_change (def_insn, &PATTERN (def_insn), new_set, true)) + if (validate_change (def_insn, &PATTERN (def_insn), new_set, true) + && update_reg_equal_equiv_notes (def_insn, cand->mode, GET_MODE (dstreg), + cand->code)) { if (dump_file) { --- gcc/testsuite/gcc.c-torture/execute/pr63659.c.jj 2014-10-27 19:26:57.720902738 +0100 +++ gcc/testsuite/gcc.c-torture/execute/pr63659.c 2014-10-27 19:26:36.000000000 +0100 @@ -0,0 +1,29 @@ +/* PR rtl-optimization/63659 */ + +int a, b, c, *d = &b, g, h, i; +unsigned char e; +char f; + +int +main () +{ + while (a) + { + for (a = 0; a; a++) + for (; c; c++) + ; + if (i) + break; + } + + char j = c, k = -1, l; + l = g = j >> h; + f = l == 0 ? k : k % l; + e = 0 ? 0 : f; + *d = e; + + if (b != 255) + __builtin_abort (); + + return 0; +}