public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jim Wilson <jim.wilson@linaro.org>
To: "gcc-patches@gcc.gnu.org" <gcc-patches@gcc.gnu.org>
Subject: [PATCH, ARM] stop changing signedness in PROMOTE_MODE
Date: Tue, 30 Jun 2015 01:56:00 -0000	[thread overview]
Message-ID: <CABXYE2VXjy7=5Y=c1TCxLE8KuwLtwBYBhTB24xrWDvWAeiBwbQ@mail.gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 3594 bytes --]

This is my suggested fix for PR 65932, which is a linux kernel
miscompile with gcc-5.1.

The problem here is caused by a chain of events.  The first is that
the relatively new eipa_sra pass creates fake parameters that behave
slightly differently than normal parameters.  The second is that the
optimizer creates phi nodes that copy local variables to fake
parameters and/or vice versa.  The third is that the ouf-of-ssa pass
assumes that it can emit simple move instructions for these phi nodes.
And the fourth is that the ARM port has a PROMOTE_MODE macro that
forces QImode and HImode to unsigned, but a
TARGET_PROMOTE_FUNCTION_MODE hook that does not.  So signed char and
short parameters have different in register representations than local
variables, and require a conversion when copying between them, a
conversion that the out-of-ssa pass can't easily emit.

Ultimately, I think this is a problem in the arm backend.  It should
not have a PROMOTE_MODE macro that is changing the sign of char and
short local variables.  I also think that we should merge the
PROMOTE_MODE macro with the TARGET_PROMOTE_FUNCTION_MODE hook to
prevent this from happening again.

I see four general problems with the current ARM PROMOTE_MODE definition.
1) Unsigned char is only faster for armv5 and earlier, before the sxtb
instruction was added.  It is a lose for armv6 and later.
2) Unsigned short was only faster for targets that don't support
unaligned accesses.  Support for these targets was removed a while
ago, and this PROMODE_MODE hunk should have been removed at the same
time.  It was accidentally left behind.
3) TARGET_PROMOTE_FUNCTION_MODE used to be a boolean hook, when it was
converted to a function, the PROMOTE_MODE code was copied without the
UNSIGNEDP changes.  Thus it is only an accident that
TARGET_PROMOTE_FUNCTION_MODE and PROMOTE_MODE disagree.  Changing
TARGET_PROMOTE_FUNCTION_MODE is an ABI change, so only PROMOTE_MODE
changes to resolve the difference are safe.
4) There is a general principle that you should only change signedness
in PROMOTE_MODE if the hardware forces it, as otherwise this results
in extra conversion instructions that make code slower.  The mips64
hardware for instance requires that 32-bit values be sign-extended
regardless of type, and instructions may trap if this is not true.
However, it has a set of 32-bit instructions that operate on these
values, and hence no conversions are required.  There is no similar
case on ARM. Thus the conversions are unnecessary and unwise.  This
can be seen in the testcases where gcc emits both a zero-extend and a
sign-extend inside a loop, as the sign-extend is required for a
compare, and the zero-extend is required by PROMOTE_MODE.

My change was tested with an arm bootstrap, make check, and SPEC
CPU2000 run.  The original poster verified that this gives a linux
kernel that boots correctly.

The PRMOTE_MODE change causes 3 testsuite testcases to fail.  These
are tests to verify that smulbb and/or smlabb are generated.
Eliminating the unnecessary sign conversions causes us to get better
code that doesn't include the smulbb and smlabb instructions.  I had
to modify the testcases to get them to emit the desired instructions.
With the testcase changes there are no additional testsuite failures,
though I'm concerned that these testcases with the changes may be
fragile, and future changes may break them again.

If there are ARM parts where smulbb/smlabb are faster than mul/mla,
then maybe we should try to add new patterns to get the instructions
emitted again for the unmodified testcases.

Jim

[-- Attachment #2: pr65932-3.patch --]
[-- Type: text/x-patch, Size: 2775 bytes --]

gcc/
2015-06-29  Jim Wilson  <jim.wilson@linaro.org>

	PR target/65932
	* config/arm/arm.h (PROMOTE_MODE): Don't set UNSIGNEDP for QImode and
	HImode.

gcc/testsuite/
2015-06-29  Jim Wilson  <jim.wilson@linaro.org>

	PR target/65932
	* gcc.target/arm/wmul-1.c (mac): Change a and b to int pointers.  Cast
	multiply operands to short.
	* gcc.target/arm/wmul-2.c (vec_mpy): Cast multiply result to short.
	* gcc.target/arm/wmul-3.c (mac): Cast multiply results to short.

Index: config/arm/arm.h
===================================================================
--- config/arm/arm.h	(revision 224672)
+++ config/arm/arm.h	(working copy)
@@ -523,16 +523,10 @@ extern int arm_arch_crc;
    type, but kept valid in the wider mode.  The signedness of the
    extension may differ from that of the type.  */
 
-/* It is far faster to zero extend chars than to sign extend them */
-
 #define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE)	\
   if (GET_MODE_CLASS (MODE) == MODE_INT		\
       && GET_MODE_SIZE (MODE) < 4)      	\
     {						\
-      if (MODE == QImode)			\
-	UNSIGNEDP = 1;				\
-      else if (MODE == HImode)			\
-	UNSIGNEDP = 1;				\
       (MODE) = SImode;				\
     }
 
Index: testsuite/gcc.target/arm/wmul-1.c
===================================================================
--- testsuite/gcc.target/arm/wmul-1.c	(revision 224672)
+++ testsuite/gcc.target/arm/wmul-1.c	(working copy)
@@ -2,14 +2,14 @@
 /* { dg-require-effective-target arm_dsp } */
 /* { dg-options "-O1 -fexpensive-optimizations" } */
 
-int mac(const short *a, const short *b, int sqr, int *sum)
+int mac(const int *a, const int *b, int sqr, int *sum)
 {
   int i;
   int dotp = *sum;
 
   for (i = 0; i < 150; i++) {
-    dotp += b[i] * a[i];
-    sqr += b[i] * b[i];
+    dotp += (short)b[i] * (short)a[i];
+    sqr += (short)b[i] * (short)b[i];
   }
 
   *sum = dotp;
Index: testsuite/gcc.target/arm/wmul-2.c
===================================================================
--- testsuite/gcc.target/arm/wmul-2.c	(revision 224672)
+++ testsuite/gcc.target/arm/wmul-2.c	(working copy)
@@ -7,7 +7,7 @@ void vec_mpy(int y[], const short x[], s
  int i;
 
  for (i = 0; i < 150; i++)
-   y[i] += ((scaler * x[i]) >> 31);
+   y[i] += ((short)(scaler * x[i]) >> 31);
 }
 
 /* { dg-final { scan-assembler-times "smulbb" 1 } } */
Index: testsuite/gcc.target/arm/wmul-3.c
===================================================================
--- testsuite/gcc.target/arm/wmul-3.c	(revision 224672)
+++ testsuite/gcc.target/arm/wmul-3.c	(working copy)
@@ -8,8 +8,8 @@ int mac(const short *a, const short *b,
   int dotp = *sum;
 
   for (i = 0; i < 150; i++) {
-    dotp -= b[i] * a[i];
-    sqr -= b[i] * b[i];
+    dotp -= (short)(b[i] * a[i]);
+    sqr -= (short)(b[i] * b[i]);
   }
 
   *sum = dotp;

             reply	other threads:[~2015-06-30  1:15 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-30  1:56 Jim Wilson [this message]
2015-07-02  9:07 ` Richard Earnshaw
2015-07-07 18:25   ` Jim Wilson
2015-07-07 15:07 ` Jeff Law
2015-07-07 16:29   ` Jim Wilson
2015-07-07 21:35     ` Richard Biener
2015-07-10 15:46       ` Jim Wilson
2015-07-13  8:19         ` Richard Biener
2015-07-13 15:29           ` Michael Matz
2015-07-13 15:35             ` H.J. Lu
2015-07-14 16:38             ` Richard Earnshaw
2015-07-14 16:49               ` Richard Biener
2015-07-14 17:07               ` Jim Wilson
2015-07-14 17:23                 ` Richard Biener
2015-07-15 13:25                 ` Michael Matz
2015-07-15 16:01                   ` Jim Wilson
2015-07-16  9:40                     ` Richard Earnshaw
2015-07-16 15:02                       ` Michael Matz
2015-07-16 15:20                         ` Richard Earnshaw
2015-07-15 13:04               ` Michael Matz
2015-07-08 22:54     ` Jeff Law
2015-07-10 15:35       ` Jim Wilson
2016-02-04  8:58 ` Ramana Radhakrishnan
2016-02-15 11:32   ` Kyrill Tkachov
2016-02-16 10:44     ` Ramana Radhakrishnan
2016-02-17 10:03     ` Christophe Lyon
2016-02-17 10:05       ` Kyrill Tkachov
2016-02-17 10:20         ` Christophe Lyon
2016-02-17 10:22           ` Kyrill Tkachov
2016-02-18 10:16             ` Christophe Lyon
2016-03-07  4:43           ` Ramana Radhakrishnan
2016-03-07 12:55             ` Christophe Lyon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CABXYE2VXjy7=5Y=c1TCxLE8KuwLtwBYBhTB24xrWDvWAeiBwbQ@mail.gmail.com' \
    --to=jim.wilson@linaro.org \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).