From patchwork Thu Jul 13 09:03:43 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 107657 Delivered-To: patch@linaro.org Received: by 10.140.101.44 with SMTP id t41csp1945792qge; Thu, 13 Jul 2017 02:05:44 -0700 (PDT) X-Received: by 10.99.66.1 with SMTP id p1mr8120166pga.120.1499936744143; Thu, 13 Jul 2017 02:05:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1499936744; cv=none; d=google.com; s=arc-20160816; b=FF28XS3xS3bqHpeWdRgjz3HYXc8uEKvA72pgwNjaY1uHmU3SXr2AqOX0meJYF71J8E oIqXMaTgTFh0UwzLD+hqR4F5Xy2ZoBtPNOELdyUiaZTrIo5mbj8FmGekxOCmai51LLQk FfdVCvwQzDjyGPHIC3WoorV7Cwe2/SMQs+cncmiNpGIqdWyiJkyvWxBw2WeKfgouuoTh GfU/dmGM3d+dJeOMdAbqkLurB01ZI9BI6gf+8ul/smLbGjwU5OrkOyPng8H4PT3uivjl Xhyfx+F97ESH7xicqAnXbiJn4LvwwY6vIUQW4JjHG/9O8vH59TfMhkrXc8lv9sA1KLcl QNxQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:user-agent:message-id:in-reply-to:date:references :subject:mail-followup-to:to:from:delivered-to:sender:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence :mailing-list:dkim-signature:domainkey-signature :arc-authentication-results; bh=tdObLj8jtPjDnq8n5LIhpphulAJxntn0B5hm3OXn6cI=; b=V6Q2bwxjfP8yNErLGp1fa8S9BBUBrKZAWZ9A+1b7UQM1Wuy/BtIjWzHgVoeCueBXmI gVdCX/WjUVoMqEt72FQWylrE/IYAj3WgWrBAAMHcgDrW6yDwEyPg2xvBMqNgiBEqJDU9 prGnVSQYyQX5M9NSdCJAp6+QUHLdMSLg3EWFKzLzpLCKt5bKBh/t95JFwalFIbsOodM5 M7T4zsYXuhi8VmouTfpsJdN1Y8i2IgzasXZ1WOB9vwke2FFA2bBJZTK859Vqe3JNh7kx Z7P81bSr8VzLADHTyLKT3KH8/VevN0Ll6ZpkeidiyCIYPM8fWn1URpmcAhTBRqId9ejd jGWw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.b=nFxty090; spf=pass (google.com: domain of gcc-patches-return-458062-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-458062-patch=linaro.org@gcc.gnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id 91si4043207ply.316.2017.07.13.02.05.43 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 13 Jul 2017 02:05:44 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-458062-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.b=nFxty090; spf=pass (google.com: domain of gcc-patches-return-458062-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-458062-patch=linaro.org@gcc.gnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:references:date:in-reply-to:message-id:mime-version :content-type; q=dns; s=default; b=lH0WYrgfO3mgRyqpKvgefPiQTZTJ1 P0WRvyRPtKPeuVre5iykDby8RHmirIc068+Fxw+IZH9Cm/h7tWgZcohhekk4dLb3 /rTi64Y30IwddtH3lUOowb4YLR+iBzsrZ+Dzfsf0m08hKgUhMUuZ+uGnsV+ay3wz Mub9Es8QFxhNjo= 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:from :to:subject:references:date:in-reply-to:message-id:mime-version :content-type; s=default; bh=wzBau+cxEGc+Dw28ZiE3rKTSXpk=; b=nFx ty090YDi+/a3NhAmMmxOMJjUpL5uOPF7ZT7st8i60rTh/Zx72VyfBbZ4FdQivtru tnYwbqSjNBxsc5gchA9h9RqLn1hQZiuHypzx8qqCRgjOWpDaBJCoNH1UZJBTWn7o apMsXnrjgvkeSVypGKrRHo7WQOK+pPsGWUZ+gvmc= Received: (qmail 89108 invoked by alias); 13 Jul 2017 09:03:59 -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 87706 invoked by uid 89); 13 Jul 2017 09:03:58 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-11.1 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-wr0-f181.google.com Received: from mail-wr0-f181.google.com (HELO mail-wr0-f181.google.com) (209.85.128.181) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 13 Jul 2017 09:03:48 +0000 Received: by mail-wr0-f181.google.com with SMTP id k67so49543531wrc.2 for ; Thu, 13 Jul 2017 02:03:47 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:mail-followup-to:subject:references:date :in-reply-to:message-id:user-agent:mime-version; bh=tdObLj8jtPjDnq8n5LIhpphulAJxntn0B5hm3OXn6cI=; b=ih5JxEvW+FlJS0iqgZyiVAVQb3Z7/IwlQVd4sspu1aBohLbXdg2rRRDrFWYyQjaiQ+ sNNuTJrpDZwxA1Il8hl73RDsfaowABKYaqZ6yzpD422OBRHl4zijiL/b/AZ2t2sP5PNj QZlDlbbxHyapX6uMK/iQZfMplRX9ByD/5LfxsZs8WFyyv6VYpUCNRqSXHrXMXWfsPSUr 6ao7C3lkZ++0/JeBmwQWitQYAhVc/R6hV/R1AsUdLzSW4ZWrpKjqXwuvI5ItI8nxo+34 DAQXWEvyYkuscdXgrkBHXmDsm38zEH8yhwlqjnIgY5iU2/W8KdpB9x+7NaGulVohGI4S BTTg== X-Gm-Message-State: AIVw110XNqsIWVF2sL8qZwrwyJseOPbhr94ytFk2lPeWg8qhen5sGxv0 K0vG1EiZqXiW8IEgrBo7ZQ== X-Received: by 10.223.145.10 with SMTP id j10mr892574wrj.172.1499936625669; Thu, 13 Jul 2017 02:03:45 -0700 (PDT) Received: from localhost (92.40.249.184.threembb.co.uk. [92.40.249.184]) by smtp.gmail.com with ESMTPSA id r200sm4377042wmd.20.2017.07.13.02.03.44 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 13 Jul 2017 02:03:44 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@linaro.org Subject: [71/77] Use opt_scalar_mode for mode iterators References: <8760ewohsv.fsf@linaro.org> Date: Thu, 13 Jul 2017 10:03:43 +0100 In-Reply-To: <8760ewohsv.fsf@linaro.org> (Richard Sandiford's message of "Thu, 13 Jul 2017 09:35:44 +0100") Message-ID: <87mv88bte8.fsf@linaro.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.2 (gnu/linux) MIME-Version: 1.0 This patch uses opt_scalar_mode when iterating over scalar modes. 2017-07-13 Richard Sandiford Alan Hayward David Sherwood gcc/ * coretypes.h (opt_scalar_mode): New typedef. * gdbhooks.py (build_pretty_printers): Handle it. * machmode.h (mode_iterator::get_2xwider): Add overload for opt_mode. * emit-rtl.c (init_emit_once): Use opt_scalar_mode when iterating over scalar modes. * expr.c (convert_mode_scalar): Likewise. * omp-low.c (omp_clause_aligned_alignment): Likewise. * optabs.c (expand_float): Likewise. (expand_fix): Likewise. * tree-vect-stmts.c (vectorizable_conversion): Likewise. gcc/c-family/ * c-common.c (c_common_fixed_point_type_for_size): Use opt_scalar_mode for the mode iterator. Index: gcc/coretypes.h =================================================================== --- gcc/coretypes.h 2017-07-13 09:18:53.271650545 +0100 +++ gcc/coretypes.h 2017-07-13 09:18:56.810392248 +0100 @@ -59,6 +59,7 @@ typedef const struct rtx_def *const_rtx; class scalar_int_mode; class scalar_float_mode; template class opt_mode; +typedef opt_mode opt_scalar_mode; typedef opt_mode opt_scalar_int_mode; typedef opt_mode opt_scalar_float_mode; template class pod_mode; Index: gcc/gdbhooks.py =================================================================== --- gcc/gdbhooks.py 2017-07-13 09:18:53.273650396 +0100 +++ gcc/gdbhooks.py 2017-07-13 09:18:56.812392104 +0100 @@ -543,7 +543,8 @@ def build_pretty_printer(): pp.add_printer_for_regex(r'opt_mode<(\S+)>', 'opt_mode', OptMachineModePrinter) pp.add_printer_for_types(['opt_scalar_int_mode', - 'opt_scalar_float_mode'], + 'opt_scalar_float_mode', + 'opt_scalar_mode'], 'opt_mode', OptMachineModePrinter) pp.add_printer_for_regex(r'pod_mode<(\S+)>', 'pod_mode', MachineModePrinter) Index: gcc/machmode.h =================================================================== --- gcc/machmode.h 2017-07-13 09:18:53.274650323 +0100 +++ gcc/machmode.h 2017-07-13 09:18:56.812392104 +0100 @@ -836,6 +836,13 @@ is_float_mode (machine_mode mode, T *flo /* Set mode iterator *ITER to the mode that is two times wider than the current one, if such a mode exists. */ + template + inline void + get_2xwider (opt_mode *iter) + { + *iter = GET_MODE_2XWIDER_MODE (**iter); + } + inline void get_2xwider (machine_mode *iter) { Index: gcc/emit-rtl.c =================================================================== --- gcc/emit-rtl.c 2017-07-13 09:18:54.682546579 +0100 +++ gcc/emit-rtl.c 2017-07-13 09:18:56.811392176 +0100 @@ -5891,6 +5891,7 @@ init_emit_once (void) int i; machine_mode mode; scalar_float_mode double_mode; + opt_scalar_mode smode_iter; /* Initialize the CONST_INT, CONST_WIDE_INT, CONST_DOUBLE, CONST_FIXED, and memory attribute hash tables. */ @@ -6005,62 +6006,66 @@ init_emit_once (void) const_tiny_rtx[1][(int) mode] = gen_const_vector (mode, 1); } - FOR_EACH_MODE_IN_CLASS (mode, MODE_FRACT) + FOR_EACH_MODE_IN_CLASS (smode_iter, MODE_FRACT) { - FCONST0 (mode).data.high = 0; - FCONST0 (mode).data.low = 0; - FCONST0 (mode).mode = mode; - const_tiny_rtx[0][(int) mode] = CONST_FIXED_FROM_FIXED_VALUE ( - FCONST0 (mode), mode); - } - - FOR_EACH_MODE_IN_CLASS (mode, MODE_UFRACT) - { - FCONST0 (mode).data.high = 0; - FCONST0 (mode).data.low = 0; - FCONST0 (mode).mode = mode; - const_tiny_rtx[0][(int) mode] = CONST_FIXED_FROM_FIXED_VALUE ( - FCONST0 (mode), mode); - } - - FOR_EACH_MODE_IN_CLASS (mode, MODE_ACCUM) - { - FCONST0 (mode).data.high = 0; - FCONST0 (mode).data.low = 0; - FCONST0 (mode).mode = mode; - const_tiny_rtx[0][(int) mode] = CONST_FIXED_FROM_FIXED_VALUE ( - FCONST0 (mode), mode); + scalar_mode smode = *smode_iter; + FCONST0 (smode).data.high = 0; + FCONST0 (smode).data.low = 0; + FCONST0 (smode).mode = smode; + const_tiny_rtx[0][(int) smode] + = CONST_FIXED_FROM_FIXED_VALUE (FCONST0 (smode), smode); + } + + FOR_EACH_MODE_IN_CLASS (smode_iter, MODE_UFRACT) + { + scalar_mode smode = *smode_iter; + FCONST0 (smode).data.high = 0; + FCONST0 (smode).data.low = 0; + FCONST0 (smode).mode = smode; + const_tiny_rtx[0][(int) smode] + = CONST_FIXED_FROM_FIXED_VALUE (FCONST0 (smode), smode); + } + + FOR_EACH_MODE_IN_CLASS (smode_iter, MODE_ACCUM) + { + scalar_mode smode = *smode_iter; + FCONST0 (smode).data.high = 0; + FCONST0 (smode).data.low = 0; + FCONST0 (smode).mode = smode; + const_tiny_rtx[0][(int) smode] + = CONST_FIXED_FROM_FIXED_VALUE (FCONST0 (smode), smode); /* We store the value 1. */ - FCONST1 (mode).data.high = 0; - FCONST1 (mode).data.low = 0; - FCONST1 (mode).mode = mode; - FCONST1 (mode).data - = double_int_one.lshift (GET_MODE_FBIT (mode), + FCONST1 (smode).data.high = 0; + FCONST1 (smode).data.low = 0; + FCONST1 (smode).mode = smode; + FCONST1 (smode).data + = double_int_one.lshift (GET_MODE_FBIT (smode), HOST_BITS_PER_DOUBLE_INT, - SIGNED_FIXED_POINT_MODE_P (mode)); - const_tiny_rtx[1][(int) mode] = CONST_FIXED_FROM_FIXED_VALUE ( - FCONST1 (mode), mode); + SIGNED_FIXED_POINT_MODE_P (smode)); + const_tiny_rtx[1][(int) smode] + = CONST_FIXED_FROM_FIXED_VALUE (FCONST1 (smode), smode); } - FOR_EACH_MODE_IN_CLASS (mode, MODE_UACCUM) - { - FCONST0 (mode).data.high = 0; - FCONST0 (mode).data.low = 0; - FCONST0 (mode).mode = mode; - const_tiny_rtx[0][(int) mode] = CONST_FIXED_FROM_FIXED_VALUE ( - FCONST0 (mode), mode); + FOR_EACH_MODE_IN_CLASS (smode_iter, MODE_UACCUM) + { + scalar_mode smode = *smode_iter; + FCONST0 (smode).data.high = 0; + FCONST0 (smode).data.low = 0; + FCONST0 (smode).mode = smode; + const_tiny_rtx[0][(int) smode] + = CONST_FIXED_FROM_FIXED_VALUE (FCONST0 (smode), smode); /* We store the value 1. */ - FCONST1 (mode).data.high = 0; - FCONST1 (mode).data.low = 0; - FCONST1 (mode).mode = mode; - FCONST1 (mode).data - = double_int_one.lshift (GET_MODE_FBIT (mode), + FCONST1 (smode).data.high = 0; + FCONST1 (smode).data.low = 0; + FCONST1 (smode).mode = smode; + FCONST1 (smode).data + = double_int_one.lshift (GET_MODE_FBIT (smode), HOST_BITS_PER_DOUBLE_INT, - SIGNED_FIXED_POINT_MODE_P (mode)); - const_tiny_rtx[1][(int) mode] = CONST_FIXED_FROM_FIXED_VALUE ( - FCONST1 (mode), mode); + SIGNED_FIXED_POINT_MODE_P (smode)); + const_tiny_rtx[1][(int) smode] + = CONST_FIXED_FROM_FIXED_VALUE (FCONST1 (smode), smode); } FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_FRACT) @@ -6093,10 +6098,11 @@ init_emit_once (void) if (STORE_FLAG_VALUE == 1) const_tiny_rtx[1][(int) BImode] = const1_rtx; - FOR_EACH_MODE_IN_CLASS (mode, MODE_POINTER_BOUNDS) + FOR_EACH_MODE_IN_CLASS (smode_iter, MODE_POINTER_BOUNDS) { - wide_int wi_zero = wi::zero (GET_MODE_PRECISION (mode)); - const_tiny_rtx[0][mode] = immed_wide_int_const (wi_zero, mode); + scalar_mode smode = *smode_iter; + wide_int wi_zero = wi::zero (GET_MODE_PRECISION (smode)); + const_tiny_rtx[0][smode] = immed_wide_int_const (wi_zero, smode); } pc_rtx = gen_rtx_fmt_ (PC, VOIDmode); Index: gcc/expr.c =================================================================== --- gcc/expr.c 2017-07-13 09:18:56.007450082 +0100 +++ gcc/expr.c 2017-07-13 09:18:56.812392104 +0100 @@ -559,23 +559,28 @@ convert_mode_scalar (rtx to, rtx from, i } else { - machine_mode intermediate; + scalar_mode intermediate; rtx tmp; int shift_amount; /* Search for a mode to convert via. */ - FOR_EACH_MODE_FROM (intermediate, from_mode) - if (((can_extend_p (to_mode, intermediate, unsignedp) - != CODE_FOR_nothing) - || (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (intermediate) - && TRULY_NOOP_TRUNCATION_MODES_P (to_mode, intermediate))) - && (can_extend_p (intermediate, from_mode, unsignedp) - != CODE_FOR_nothing)) - { - convert_move (to, convert_to_mode (intermediate, from, - unsignedp), unsignedp); - return; - } + opt_scalar_mode intermediate_iter; + FOR_EACH_MODE_FROM (intermediate_iter, from_mode) + { + scalar_mode intermediate = *intermediate_iter; + if (((can_extend_p (to_mode, intermediate, unsignedp) + != CODE_FOR_nothing) + || (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (intermediate) + && TRULY_NOOP_TRUNCATION_MODES_P (to_mode, + intermediate))) + && (can_extend_p (intermediate, from_mode, unsignedp) + != CODE_FOR_nothing)) + { + convert_move (to, convert_to_mode (intermediate, from, + unsignedp), unsignedp); + return; + } + } /* No suitable intermediate mode. Generate what we need with shifts. */ Index: gcc/omp-low.c =================================================================== --- gcc/omp-low.c 2017-07-13 09:18:22.933278054 +0100 +++ gcc/omp-low.c 2017-07-13 09:18:56.813392032 +0100 @@ -3438,16 +3438,18 @@ omp_clause_aligned_alignment (tree claus /* Otherwise return implementation defined alignment. */ unsigned int al = 1; - machine_mode mode, vmode; + opt_scalar_mode mode_iter; int vs = targetm.vectorize.autovectorize_vector_sizes (); if (vs) vs = 1 << floor_log2 (vs); static enum mode_class classes[] = { MODE_INT, MODE_VECTOR_INT, MODE_FLOAT, MODE_VECTOR_FLOAT }; for (int i = 0; i < 4; i += 2) - FOR_EACH_MODE_IN_CLASS (mode, classes[i]) + /* The for loop above dictates that we only walk through scalar classes. */ + FOR_EACH_MODE_IN_CLASS (mode_iter, classes[i]) { - vmode = targetm.vectorize.preferred_simd_mode (mode); + scalar_mode mode = *mode_iter; + machine_mode vmode = targetm.vectorize.preferred_simd_mode (mode); if (GET_MODE_CLASS (vmode) != classes[i + 1]) continue; while (vs Index: gcc/optabs.c =================================================================== --- gcc/optabs.c 2017-07-13 09:18:56.346425666 +0100 +++ gcc/optabs.c 2017-07-13 09:18:56.813392032 +0100 @@ -4690,6 +4690,7 @@ expand_float (rtx to, rtx from, int unsi && is_a (GET_MODE (to), &to_mode) && is_a (GET_MODE (from), &from_mode)) { + opt_scalar_mode fmode_iter; rtx_code_label *label = gen_label_rtx (); rtx temp; REAL_VALUE_TYPE offset; @@ -4698,12 +4699,14 @@ expand_float (rtx to, rtx from, int unsi least as wide as the target. Using FMODE will avoid rounding woes with unsigned values greater than the signed maximum value. */ - FOR_EACH_MODE_FROM (fmode, to_mode) - if (GET_MODE_PRECISION (from_mode) < GET_MODE_BITSIZE (fmode) - && can_float_p (fmode, from_mode, 0) != CODE_FOR_nothing) + FOR_EACH_MODE_FROM (fmode_iter, to_mode) + if (GET_MODE_PRECISION (from_mode) < GET_MODE_BITSIZE (*fmode_iter) + && can_float_p (*fmode_iter, from_mode, 0) != CODE_FOR_nothing) break; - if (fmode == VOIDmode) + if (fmode_iter.exists ()) + fmode = *fmode_iter; + else { /* There is no such mode. Pretend the target is wide enough. */ fmode = to_mode; @@ -4838,6 +4841,7 @@ expand_fix (rtx to, rtx from, int unsign enum insn_code icode; rtx target = to; machine_mode fmode, imode; + opt_scalar_mode fmode_iter; bool must_trunc = false; /* We first try to find a pair of modes, one real and one integer, at @@ -4909,66 +4913,70 @@ expand_fix (rtx to, rtx from, int unsign if (unsignedp && is_a (GET_MODE (to), &to_mode) && HWI_COMPUTABLE_MODE_P (to_mode)) - FOR_EACH_MODE_FROM (fmode, GET_MODE (from)) - if (CODE_FOR_nothing != can_fix_p (to_mode, fmode, 0, &must_trunc) - && (!DECIMAL_FLOAT_MODE_P (fmode) - || GET_MODE_BITSIZE (fmode) > GET_MODE_PRECISION (to_mode))) - { - int bitsize; - REAL_VALUE_TYPE offset; - rtx limit; - rtx_code_label *lab1, *lab2; - rtx_insn *insn; - - bitsize = GET_MODE_PRECISION (to_mode); - real_2expN (&offset, bitsize - 1, fmode); - limit = const_double_from_real_value (offset, fmode); - lab1 = gen_label_rtx (); - lab2 = gen_label_rtx (); - - if (fmode != GET_MODE (from)) - from = convert_to_mode (fmode, from, 0); - - /* See if we need to do the subtraction. */ - do_pending_stack_adjust (); - emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from), - 0, lab1); - - /* If not, do the signed "fix" and branch around fixup code. */ - expand_fix (to, from, 0); - emit_jump_insn (targetm.gen_jump (lab2)); - emit_barrier (); - - /* Otherwise, subtract 2**(N-1), convert to signed number, - then add 2**(N-1). Do the addition using XOR since this - will often generate better code. */ - emit_label (lab1); - target = expand_binop (GET_MODE (from), sub_optab, from, limit, - NULL_RTX, 0, OPTAB_LIB_WIDEN); - expand_fix (to, target, 0); - target = expand_binop (to_mode, xor_optab, to, - gen_int_mode - (HOST_WIDE_INT_1 << (bitsize - 1), - to_mode), - to, 1, OPTAB_LIB_WIDEN); + FOR_EACH_MODE_FROM (fmode_iter, as_a (GET_MODE (from))) + { + scalar_mode fmode = *fmode_iter; + if (CODE_FOR_nothing != can_fix_p (to_mode, fmode, + 0, &must_trunc) + && (!DECIMAL_FLOAT_MODE_P (fmode) + || (GET_MODE_BITSIZE (fmode) > GET_MODE_PRECISION (to_mode)))) + { + int bitsize; + REAL_VALUE_TYPE offset; + rtx limit; + rtx_code_label *lab1, *lab2; + rtx_insn *insn; + + bitsize = GET_MODE_PRECISION (to_mode); + real_2expN (&offset, bitsize - 1, fmode); + limit = const_double_from_real_value (offset, fmode); + lab1 = gen_label_rtx (); + lab2 = gen_label_rtx (); - if (target != to) - emit_move_insn (to, target); + if (fmode != GET_MODE (from)) + from = convert_to_mode (fmode, from, 0); - emit_label (lab2); + /* See if we need to do the subtraction. */ + do_pending_stack_adjust (); + emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, + GET_MODE (from), 0, lab1); + + /* If not, do the signed "fix" and branch around fixup code. */ + expand_fix (to, from, 0); + emit_jump_insn (targetm.gen_jump (lab2)); + emit_barrier (); + + /* Otherwise, subtract 2**(N-1), convert to signed number, + then add 2**(N-1). Do the addition using XOR since this + will often generate better code. */ + emit_label (lab1); + target = expand_binop (GET_MODE (from), sub_optab, from, limit, + NULL_RTX, 0, OPTAB_LIB_WIDEN); + expand_fix (to, target, 0); + target = expand_binop (to_mode, xor_optab, to, + gen_int_mode + (HOST_WIDE_INT_1 << (bitsize - 1), + to_mode), + to, 1, OPTAB_LIB_WIDEN); - if (optab_handler (mov_optab, to_mode) != CODE_FOR_nothing) - { - /* Make a place for a REG_NOTE and add it. */ - insn = emit_move_insn (to, to); - set_dst_reg_note (insn, REG_EQUAL, - gen_rtx_fmt_e (UNSIGNED_FIX, to_mode, - copy_rtx (from)), - to); - } + if (target != to) + emit_move_insn (to, target); - return; - } + emit_label (lab2); + + if (optab_handler (mov_optab, to_mode) != CODE_FOR_nothing) + { + /* Make a place for a REG_NOTE and add it. */ + insn = emit_move_insn (to, to); + set_dst_reg_note (insn, REG_EQUAL, + gen_rtx_fmt_e (UNSIGNED_FIX, to_mode, + copy_rtx (from)), + to); + } + + return; + } + } /* We can't do it with an insn, so use a library call. But first ensure that the mode of TO is at least as wide as SImode, since those are the Index: gcc/tree-vect-stmts.c =================================================================== --- gcc/tree-vect-stmts.c 2017-07-13 09:18:55.599479728 +0100 +++ gcc/tree-vect-stmts.c 2017-07-13 09:18:56.814391960 +0100 @@ -4195,8 +4195,10 @@ vectorizable_conversion (gimple *stmt, g needs to be generated. */ gcc_assert (ncopies >= 1); - machine_mode lhs_mode = SCALAR_TYPE_MODE (lhs_type); - machine_mode rhs_mode = SCALAR_TYPE_MODE (rhs_type); + bool found_mode = false; + scalar_mode lhs_mode = SCALAR_TYPE_MODE (lhs_type); + scalar_mode rhs_mode = SCALAR_TYPE_MODE (rhs_type); + opt_scalar_mode rhs_mode_iter; /* Supportable by target? */ switch (modifier) @@ -4230,8 +4232,9 @@ vectorizable_conversion (gimple *stmt, g goto unsupported; fltsz = GET_MODE_SIZE (lhs_mode); - FOR_EACH_2XWIDER_MODE (rhs_mode, rhs_mode) + FOR_EACH_2XWIDER_MODE (rhs_mode_iter, rhs_mode) { + rhs_mode = *rhs_mode_iter; if (GET_MODE_SIZE (rhs_mode) > fltsz) break; @@ -4258,10 +4261,13 @@ vectorizable_conversion (gimple *stmt, g if (supportable_widening_operation (NOP_EXPR, stmt, cvt_type, vectype_in, &code1, &code2, &multi_step_cvt, &interm_types)) - break; + { + found_mode = true; + break; + } } - if (rhs_mode == VOIDmode || GET_MODE_SIZE (rhs_mode) > fltsz) + if (!found_mode) goto unsupported; if (GET_MODE_SIZE (rhs_mode) == fltsz) Index: gcc/c-family/c-common.c =================================================================== --- gcc/c-family/c-common.c 2017-07-13 09:18:53.993597112 +0100 +++ gcc/c-family/c-common.c 2017-07-13 09:18:56.810392248 +0100 @@ -2155,12 +2155,12 @@ c_common_fixed_point_type_for_size (unsi else mclass = unsignedp ? MODE_UACCUM : MODE_ACCUM; - machine_mode mode; + opt_scalar_mode mode; FOR_EACH_MODE_IN_CLASS (mode, mclass) - if (GET_MODE_IBIT (mode) >= ibit && GET_MODE_FBIT (mode) >= fbit) + if (GET_MODE_IBIT (*mode) >= ibit && GET_MODE_FBIT (*mode) >= fbit) break; - if (mode == VOIDmode || !targetm.scalar_mode_supported_p (mode)) + if (!mode.exists () || !targetm.scalar_mode_supported_p (*mode)) { sorry ("GCC cannot support operators with integer types and " "fixed-point types that have too many integral and " @@ -2168,7 +2168,7 @@ c_common_fixed_point_type_for_size (unsi return NULL_TREE; } - return c_common_type_for_mode (mode, satp); + return c_common_type_for_mode (*mode, satp); } /* Used for communication between c_common_type_for_mode and