From patchwork Mon Dec 19 21:39:19 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 132316 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 94737B7008 for ; Tue, 20 Dec 2011 08:39:39 +1100 (EST) Received: (qmail 17297 invoked by alias); 19 Dec 2011 21:39:37 -0000 Received: (qmail 17287 invoked by uid 22791); 19 Dec 2011 21:39:37 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM X-Spam-Check-By: sourceware.org Received: from mail-ww0-f51.google.com (HELO mail-ww0-f51.google.com) (74.125.82.51) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 19 Dec 2011 21:39:23 +0000 Received: by wgbdr1 with SMTP id dr1so10143683wgb.8 for ; Mon, 19 Dec 2011 13:39:22 -0800 (PST) Received: by 10.227.59.203 with SMTP id m11mr13486539wbh.18.1324330762261; Mon, 19 Dec 2011 13:39:22 -0800 (PST) Received: from localhost (rsandifo.gotadsl.co.uk. [82.133.89.107]) by mx.google.com with ESMTPS id ff1sm27257962wbb.5.2011.12.19.13.39.20 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 19 Dec 2011 13:39:21 -0800 (PST) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, rdsandiford@googlemail.com Subject: Restore widening madd optimisation for fixed-point types Date: Mon, 19 Dec 2011 21:39:19 +0000 Message-ID: <87ty4w8cmw.fsf@firetop.home> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 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 recent(ish) improvements to widening multiplication support have disabled madd and msub for fixed-point types. The problem is that the optab is now chosen based on: optype = build_nonstandard_integer_type (from_mode, from_unsigned1); which is specific to integer types. The only time optype differs from type1 is when we've switched to using unsigned types, possibly with a wider mode. As written, the handling of mixed signedness really is only suitable for integer types, so this patch enforces that and makes the call above conditional on it. It also fixes the first argument to be the precision rather than the mode. (As the argument mismatch proved, the precision doesn't actually matter here; only the signedness does. I think an equivalent fix would be to call: optype = unsigned_type_for (type1); That ought to work for fixed point types too, but is a little less obvious and a little less future-proof. Since the rest of the block hasn't been adapted to fixed point types, it didn't seem worth the confusion.) Tested on mips-sde-elf, where it fixes gcc.target/mips/dpaq_sa_l_w.c and gcc.target/mips/dpsq_sa_l_w.c. OK to install? Richard gcc/ * tree-ssa-math-opts.c (convert_plusminus_to_widen): Restrict handling of signedness differences to integer types. Only build a new optype if type1 isn't correct. Index: gcc/tree-ssa-math-opts.c =================================================================== --- gcc/tree-ssa-math-opts.c 2011-12-19 21:18:43.000000000 +0000 +++ gcc/tree-ssa-math-opts.c 2011-12-19 21:23:12.000000000 +0000 @@ -2304,10 +2304,13 @@ convert_plusminus_to_widen (gimple_stmt_ from_mode = TYPE_MODE (type1); from_unsigned1 = TYPE_UNSIGNED (type1); from_unsigned2 = TYPE_UNSIGNED (type2); + optype = type1; /* There's no such thing as a mixed sign madd yet, so use a wider mode. */ if (from_unsigned1 != from_unsigned2) { + if (TREE_CODE (type) != INTEGER_TYPE) + return false; /* We can use a signed multiply with unsigned types as long as there is a wider mode to use, or it is the smaller of the two types that is unsigned. Note that type1 >= type2, always. */ @@ -2322,6 +2325,8 @@ convert_plusminus_to_widen (gimple_stmt_ } from_unsigned1 = from_unsigned2 = false; + optype = build_nonstandard_integer_type (GET_MODE_PRECISION (from_mode), + false); } /* If there was a conversion between the multiply and addition @@ -2355,7 +2360,6 @@ convert_plusminus_to_widen (gimple_stmt_ /* Verify that the machine can perform a widening multiply accumulate in this mode/signedness combination, otherwise this transformation is likely to pessimize code. */ - optype = build_nonstandard_integer_type (from_mode, from_unsigned1); this_optab = optab_for_tree_code (wmult_code, optype, optab_default); handler = find_widening_optab_handler_and_mode (this_optab, to_mode, from_mode, 0, &actual_mode);