From patchwork Tue Jul 30 10:04:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 1138880 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-505817-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="M4UgUqfq"; dkim-atps=neutral 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 45yXGp36PGz9sBF for ; Tue, 30 Jul 2019 20:04:49 +1000 (AEST) 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:date:message-id:mime-version:content-type; q=dns; s= default; b=rbpLo5z/9nWTz1zZC0RfSA6tXE11wXJIxC1YzOsQfAcWf4l6PgFdM 9IYFiQwMRQSpLbATKpgthohZqd97rw735e34BrrBgzVPxXqB5BeAf4LdmRYFkHJP Xpp7Hs88mBuF6vLpYI71oGfFdOiujg6huZ/pxKGpyDzXdwIhuX5sTI= 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:date:message-id:mime-version:content-type; s= default; bh=D7mCmZSs+YGiEZPyqoRlB8RKR2w=; b=M4UgUqfqotW9B6lA1HX3 BXxCPj2IxUAC9iMnCZ7WpHuvbEvVzQqN98mGdLP2/unx8Eo7AGXkqebU3seicsen J5fJkHcfNN1i5Yg7UWHmdex8N5q1Hxu+RMTXtZHAyF3b9KdmyaWT2k60WvCbxG9M fl6Dh87uNfvgoO6/nwDxk4E= Received: (qmail 96944 invoked by alias); 30 Jul 2019 10:04:41 -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 96936 invoked by uid 89); 30 Jul 2019 10:04:41 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-8.1 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, SPF_PASS autolearn=ham version=3.3.1 spammy= X-HELO: foss.arm.com Received: from foss.arm.com (HELO foss.arm.com) (217.140.110.172) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 30 Jul 2019 10:04:40 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id A57F3344 for ; Tue, 30 Jul 2019 03:04:38 -0700 (PDT) Received: from localhost (unknown [10.32.99.62]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 4CC513F575 for ; Tue, 30 Jul 2019 03:04:38 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: Don't use integer "FMA" for shifts Date: Tue, 30 Jul 2019 11:04:37 +0100 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux) MIME-Version: 1.0 X-IsSubscribed: yes tree-ssa-math-opts supports FMA optabs for integers as well as floating-point types, even though there's no distinction between fused and unfused there. It turns out to be pretty handy for the IFN_COND_* handling though, so I don't want to remove it, however weird it might seem. Instead this patch makes sure that we don't apply it to integer multiplications that are actually shifts (but that are represented in gimple as multiplications because that's the canonical form). This is a preemptive strike. The test doesn't fail for SVE as-is, but would after a later patch. Tested on aarch64-linux-gnu, aarch64_be-elf and x86_64-linux-gnu. OK to install? Richard 2019-07-30 Richard Sandiford gcc/ * tree-ssa-math-opts.c (convert_mult_to_fma): Reject integer multiplications by a power of 2 or a negative power of 2. gcc/testsuite/ * gcc.dg/vect/vect-cond-arith-8.c: New test. Index: gcc/tree-ssa-math-opts.c =================================================================== --- gcc/tree-ssa-math-opts.c 2019-07-30 10:51:51.827405171 +0100 +++ gcc/tree-ssa-math-opts.c 2019-07-30 10:52:27.327139149 +0100 @@ -3074,10 +3074,20 @@ convert_mult_to_fma (gimple *mul_stmt, t && flag_fp_contract_mode == FP_CONTRACT_OFF) return false; - /* We don't want to do bitfield reduction ops. */ - if (INTEGRAL_TYPE_P (type) - && (!type_has_mode_precision_p (type) || TYPE_OVERFLOW_TRAPS (type))) - return false; + if (ANY_INTEGRAL_TYPE_P (type)) + { + /* We don't want to do bitfield reduction ops. */ + tree itype = INTEGRAL_TYPE_P (type) ? type : TREE_TYPE (type); + if (!type_has_mode_precision_p (itype) || TYPE_OVERFLOW_TRAPS (itype)) + return false; + + /* Don't use FMA for multiplications that are actually shifts. */ + tree val = VECTOR_TYPE_P (type) ? uniform_vector_p (op2) : op2; + if (val + && TREE_CODE (val) == INTEGER_CST + && wi::popcount (wi::abs (wi::to_wide (val))) == 1) + return false; + } /* If the target doesn't support it, don't generate it. We assume that if fma isn't available then fms, fnma or fnms are not either. */ Index: gcc/testsuite/gcc.dg/vect/vect-cond-arith-8.c =================================================================== --- /dev/null 2019-07-30 08:53:31.317691683 +0100 +++ gcc/testsuite/gcc.dg/vect/vect-cond-arith-8.c 2019-07-30 10:52:27.327139149 +0100 @@ -0,0 +1,57 @@ +/* { dg-require-effective-target scalar_all_fma } */ +/* { dg-additional-options "-fdump-tree-optimized -ffp-contract=fast" } */ + +#include "tree-vect.h" + +#define N (VECTOR_BITS * 11 / 64 + 3) + +#define DEF(INV) \ + void __attribute__ ((noipa)) \ + f_##INV (int *restrict a, int *restrict b, \ + int *restrict c) \ + { \ + for (int i = 0; i < N; ++i) \ + { \ + int mb = (INV & 1 ? -b[i] : b[i]); \ + int mc = (INV & 2 ? -c[i] : c[i]); \ + a[i] = b[i] < 10 ? mb * 8 + mc : 10; \ + } \ + } + +#define TEST(INV) \ + { \ + f_##INV (a, b, c); \ + for (int i = 0; i < N; ++i) \ + { \ + int mb = (INV & 1 ? -b[i] : b[i]); \ + int mc = (INV & 2 ? -c[i] : c[i]); \ + int truev = mb * 8 + mc; \ + if (a[i] != (i % 17 < 10 ? truev : 10)) \ + __builtin_abort (); \ + asm volatile ("" ::: "memory"); \ + } \ + } + +#define FOR_EACH_INV(T) \ + T (0) T (1) T (2) T (3) + +FOR_EACH_INV (DEF) + +int +main (void) +{ + int a[N], b[N], c[N]; + for (int i = 0; i < N; ++i) + { + b[i] = i % 17; + c[i] = i % 13 + 14; + asm volatile ("" ::: "memory"); + } + FOR_EACH_INV (TEST) + return 0; +} + +/* { dg-final { scan-tree-dump-not { = \.COND_FMA } "optimized" } } */ +/* { dg-final { scan-tree-dump-not { = \.COND_FMS } "optimized" } } */ +/* { dg-final { scan-tree-dump-not { = \.COND_FNMA } "optimized" } } */ +/* { dg-final { scan-tree-dump-not { = \.COND_FNMS } "optimized" } } */