public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] PR opt/7291: bzero problems on x86_64
@ 2002-07-23 19:32 Roger Sayle
  2002-07-23 22:33 ` Mark Mitchell
  2002-07-23 22:58 ` Andreas Jaeger
  0 siblings, 2 replies; 4+ messages in thread
From: Roger Sayle @ 2002-07-23 19:32 UTC (permalink / raw)
  To: gcc-patches; +Cc: fvdl


This patch is essentially Frank van der Linden's fix as proposed
in the GNATS bug report for PR optimization/7291.  This slips
through the correctness checks in the testsuite:  memset-1.c tests
variable alignment and variable length and memset-2.c tests
variable alignment and constant length.  The new test case below
adds memset-3.c which tests constant alignment and variable length.

Frank has confirmed that the new testcase currently fails on x86_64
but passses with the patch below applied.


Ok for mainline?


2002-07-23  Frank van der Linden  <fvdl@wasabisystems.com>

	PR optimization/7291
	* config/i386/i386.c (ix86_expand_clrstr): Fix bzero alignment
	problem on x86_64.

2002-07-23  Roger Sayle  <roger@eyesopen.com>

	* gcc.c-torture/execute/memset-3.c: New testcase.


Index: config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.438
diff -c -3 -p -r1.438 i386.c
*** config/i386/i386.c	23 Jul 2002 06:26:28 -0000	1.438
--- config/i386/i386.c	24 Jul 2002 01:51:47 -0000
*************** ix86_expand_clrstr (src, count_exp, alig
*** 10193,10199 ****
  				 gen_rtx_SUBREG (SImode, zeroreg, 0)));
        if (TARGET_64BIT && (align <= 4 || count == 0))
  	{
! 	  rtx label = ix86_expand_aligntest (countreg, 2);
  	  emit_insn (gen_strsetsi (destreg,
  				   gen_rtx_SUBREG (SImode, zeroreg, 0)));
  	  emit_label (label);
--- 10193,10199 ----
  				 gen_rtx_SUBREG (SImode, zeroreg, 0)));
        if (TARGET_64BIT && (align <= 4 || count == 0))
  	{
! 	  rtx label = ix86_expand_aligntest (countreg, 4);
  	  emit_insn (gen_strsetsi (destreg,
  				   gen_rtx_SUBREG (SImode, zeroreg, 0)));
  	  emit_label (label);
*** /dev/null	Thu Aug 30 14:30:55 2001
--- gcc.c-torture/execute/memset-3.c	Tue Jul 23 19:40:21 2002
***************
*** 0 ****
--- 1,208 ----
+ /* Copyright (C) 2002  Free Software Foundation.
+
+    Test memset with various combinations of constant pointer alignments and
+    lengths to make sure any optimizations in the compiler are correct.
+
+    Written by Roger Sayle, July 22, 2002.  */
+
+ #ifndef MAX_OFFSET
+ #define MAX_OFFSET (sizeof (long long))
+ #endif
+
+ #ifndef MAX_COPY
+ #define MAX_COPY 15
+ #endif
+
+ #ifndef MAX_EXTRA
+ #define MAX_EXTRA (sizeof (long long))
+ #endif
+
+ #define MAX_LENGTH (MAX_OFFSET + MAX_COPY + MAX_EXTRA)
+
+ static union {
+   char buf[MAX_LENGTH];
+   long long align_int;
+   long double align_fp;
+ } u;
+
+ char A = 'A';
+
+ void reset ()
+ {
+   int i;
+
+   for (i = 0; i < MAX_LENGTH; i++)
+     u.buf[i] = 'a';
+ }
+
+ void check (int off, int len, int ch)
+ {
+   char *q;
+   int i;
+
+   q = u.buf;
+   for (i = 0; i < off; i++, q++)
+     if (*q != 'a')
+       abort ();
+
+   for (i = 0; i < len; i++, q++)
+     if (*q != ch)
+       abort ();
+
+   for (i = 0; i < MAX_EXTRA; i++, q++)
+     if (*q != 'a')
+       abort ();
+ }
+
+ int main ()
+ {
+   int len;
+   char *p;
+
+   /* off == 0 */
+   for (len = 0; len < MAX_COPY; len++)
+     {
+       reset ();
+
+       p = memset (u.buf, '\0', len);
+       if (p != u.buf) abort ();
+       check (0, len, '\0');
+
+       p = memset (u.buf, A, len);
+       if (p != u.buf) abort ();
+       check (0, len, 'A');
+
+       p = memset (u.buf, 'B', len);
+       if (p != u.buf) abort ();
+       check (0, len, 'B');
+     }
+
+   /* off == 1 */
+   for (len = 0; len < MAX_COPY; len++)
+     {
+       reset ();
+
+       p = memset (u.buf+1, '\0', len);
+       if (p != u.buf+1) abort ();
+       check (1, len, '\0');
+
+       p = memset (u.buf+1, A, len);
+       if (p != u.buf+1) abort ();
+       check (1, len, 'A');
+
+       p = memset (u.buf+1, 'B', len);
+       if (p != u.buf+1) abort ();
+       check (1, len, 'B');
+     }
+
+   /* off == 2 */
+   for (len = 0; len < MAX_COPY; len++)
+     {
+       reset ();
+
+       p = memset (u.buf+2, '\0', len);
+       if (p != u.buf+2) abort ();
+       check (2, len, '\0');
+
+       p = memset (u.buf+2, A, len);
+       if (p != u.buf+2) abort ();
+       check (2, len, 'A');
+
+       p = memset (u.buf+2, 'B', len);
+       if (p != u.buf+2) abort ();
+       check (2, len, 'B');
+     }
+
+   /* off == 3 */
+   for (len = 0; len < MAX_COPY; len++)
+     {
+       reset ();
+
+       p = memset (u.buf+3, '\0', len);
+       if (p != u.buf+3) abort ();
+       check (3, len, '\0');
+
+       p = memset (u.buf+3, A, len);
+       if (p != u.buf+3) abort ();
+       check (3, len, 'A');
+
+       p = memset (u.buf+3, 'B', len);
+       if (p != u.buf+3) abort ();
+       check (3, len, 'B');
+     }
+
+   /* off == 4 */
+   for (len = 0; len < MAX_COPY; len++)
+     {
+       reset ();
+
+       p = memset (u.buf+4, '\0', len);
+       if (p != u.buf+4) abort ();
+       check (4, len, '\0');
+
+       p = memset (u.buf+4, A, len);
+       if (p != u.buf+4) abort ();
+       check (4, len, 'A');
+
+       p = memset (u.buf+4, 'B', len);
+       if (p != u.buf+4) abort ();
+       check (4, len, 'B');
+     }
+
+   /* off == 5 */
+   for (len = 0; len < MAX_COPY; len++)
+     {
+       reset ();
+
+       p = memset (u.buf+5, '\0', len);
+       if (p != u.buf+5) abort ();
+       check (5, len, '\0');
+
+       p = memset (u.buf+5, A, len);
+       if (p != u.buf+5) abort ();
+       check (5, len, 'A');
+
+       p = memset (u.buf+5, 'B', len);
+       if (p != u.buf+5) abort ();
+       check (5, len, 'B');
+     }
+
+   /* off == 6 */
+   for (len = 0; len < MAX_COPY; len++)
+     {
+       reset ();
+
+       p = memset (u.buf+6, '\0', len);
+       if (p != u.buf+6) abort ();
+       check (6, len, '\0');
+
+       p = memset (u.buf+6, A, len);
+       if (p != u.buf+6) abort ();
+       check (6, len, 'A');
+
+       p = memset (u.buf+6, 'B', len);
+       if (p != u.buf+6) abort ();
+       check (6, len, 'B');
+     }
+
+   /* off == 7 */
+   for (len = 0; len < MAX_COPY; len++)
+     {
+       reset ();
+
+       p = memset (u.buf+7, '\0', len);
+       if (p != u.buf+7) abort ();
+       check (7, len, '\0');
+
+       p = memset (u.buf+7, A, len);
+       if (p != u.buf+7) abort ();
+       check (7, len, 'A');
+
+       p = memset (u.buf+7, 'B', len);
+       if (p != u.buf+7) abort ();
+       check (7, len, 'B');
+     }
+
+   exit (0);
+ }
+

Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] PR opt/7291: bzero problems on x86_64
  2002-07-23 19:32 [PATCH] PR opt/7291: bzero problems on x86_64 Roger Sayle
@ 2002-07-23 22:33 ` Mark Mitchell
  2002-07-23 22:58 ` Andreas Jaeger
  1 sibling, 0 replies; 4+ messages in thread
From: Mark Mitchell @ 2002-07-23 22:33 UTC (permalink / raw)
  To: Roger Sayle, gcc-patches; +Cc: fvdl

> Ok for mainline?

Yes, thanks.

-- 
Mark Mitchell                mark@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] PR opt/7291: bzero problems on x86_64
  2002-07-23 19:32 [PATCH] PR opt/7291: bzero problems on x86_64 Roger Sayle
  2002-07-23 22:33 ` Mark Mitchell
@ 2002-07-23 22:58 ` Andreas Jaeger
  2002-07-25 10:11   ` Mark Mitchell
  1 sibling, 1 reply; 4+ messages in thread
From: Andreas Jaeger @ 2002-07-23 22:58 UTC (permalink / raw)
  To: Roger Sayle; +Cc: gcc-patches, fvdl

Roger Sayle <roger@eyesopen.com> writes:

> This patch is essentially Frank van der Linden's fix as proposed
> in the GNATS bug report for PR optimization/7291.  This slips
> through the correctness checks in the testsuite:  memset-1.c tests
> variable alignment and variable length and memset-2.c tests
> variable alignment and constant length.  The new test case below
> adds memset-3.c which tests constant alignment and variable length.
>
> Frank has confirmed that the new testcase currently fails on x86_64
> but passses with the patch below applied.
>
>
> Ok for mainline?

Exactly the same patch is needed for the 3.1 branch.  Ok to add for 3.2
after it has been branched?

Thanks Roger and Frank!

Andreas

>
>
> 2002-07-23  Frank van der Linden  <fvdl@wasabisystems.com>
>
> 	PR optimization/7291
> 	* config/i386/i386.c (ix86_expand_clrstr): Fix bzero alignment
> 	problem on x86_64.
>
> 2002-07-23  Roger Sayle  <roger@eyesopen.com>
>
> 	* gcc.c-torture/execute/memset-3.c: New testcase.
>
>
> Index: config/i386/i386.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
> retrieving revision 1.438
> diff -c -3 -p -r1.438 i386.c
> *** config/i386/i386.c	23 Jul 2002 06:26:28 -0000	1.438
> --- config/i386/i386.c	24 Jul 2002 01:51:47 -0000
> *************** ix86_expand_clrstr (src, count_exp, alig
> *** 10193,10199 ****
>   				 gen_rtx_SUBREG (SImode, zeroreg, 0)));
>         if (TARGET_64BIT && (align <= 4 || count == 0))
>   	{
> ! 	  rtx label = ix86_expand_aligntest (countreg, 2);
>   	  emit_insn (gen_strsetsi (destreg,
>   				   gen_rtx_SUBREG (SImode, zeroreg, 0)));
>   	  emit_label (label);
> --- 10193,10199 ----
>   				 gen_rtx_SUBREG (SImode, zeroreg, 0)));
>         if (TARGET_64BIT && (align <= 4 || count == 0))
>   	{
> ! 	  rtx label = ix86_expand_aligntest (countreg, 4);
>   	  emit_insn (gen_strsetsi (destreg,
>   				   gen_rtx_SUBREG (SImode, zeroreg, 0)));
>   	  emit_label (label);
> *** /dev/null	Thu Aug 30 14:30:55 2001
> --- gcc.c-torture/execute/memset-3.c	Tue Jul 23 19:40:21 2002
> ***************
> *** 0 ****
> --- 1,208 ----
> + /* Copyright (C) 2002  Free Software Foundation.
> +
> +    Test memset with various combinations of constant pointer alignments and
> +    lengths to make sure any optimizations in the compiler are correct.
> +
> +    Written by Roger Sayle, July 22, 2002.  */
> +
> + #ifndef MAX_OFFSET
> + #define MAX_OFFSET (sizeof (long long))
> + #endif
> +
> + #ifndef MAX_COPY
> + #define MAX_COPY 15
> + #endif
> +
> + #ifndef MAX_EXTRA
> + #define MAX_EXTRA (sizeof (long long))
> + #endif
> +
> + #define MAX_LENGTH (MAX_OFFSET + MAX_COPY + MAX_EXTRA)
> +
> + static union {
> +   char buf[MAX_LENGTH];
> +   long long align_int;
> +   long double align_fp;
> + } u;
> +
> + char A = 'A';
> +
> + void reset ()
> + {
> +   int i;
> +
> +   for (i = 0; i < MAX_LENGTH; i++)
> +     u.buf[i] = 'a';
> + }
> +
> + void check (int off, int len, int ch)
> + {
> +   char *q;
> +   int i;
> +
> +   q = u.buf;
> +   for (i = 0; i < off; i++, q++)
> +     if (*q != 'a')
> +       abort ();
> +
> +   for (i = 0; i < len; i++, q++)
> +     if (*q != ch)
> +       abort ();
> +
> +   for (i = 0; i < MAX_EXTRA; i++, q++)
> +     if (*q != 'a')
> +       abort ();
> + }
> +
> + int main ()
> + {
> +   int len;
> +   char *p;
> +
> +   /* off == 0 */
> +   for (len = 0; len < MAX_COPY; len++)
> +     {
> +       reset ();
> +
> +       p = memset (u.buf, '\0', len);
> +       if (p != u.buf) abort ();
> +       check (0, len, '\0');
> +
> +       p = memset (u.buf, A, len);
> +       if (p != u.buf) abort ();
> +       check (0, len, 'A');
> +
> +       p = memset (u.buf, 'B', len);
> +       if (p != u.buf) abort ();
> +       check (0, len, 'B');
> +     }
> +
> +   /* off == 1 */
> +   for (len = 0; len < MAX_COPY; len++)
> +     {
> +       reset ();
> +
> +       p = memset (u.buf+1, '\0', len);
> +       if (p != u.buf+1) abort ();
> +       check (1, len, '\0');
> +
> +       p = memset (u.buf+1, A, len);
> +       if (p != u.buf+1) abort ();
> +       check (1, len, 'A');
> +
> +       p = memset (u.buf+1, 'B', len);
> +       if (p != u.buf+1) abort ();
> +       check (1, len, 'B');
> +     }
> +
> +   /* off == 2 */
> +   for (len = 0; len < MAX_COPY; len++)
> +     {
> +       reset ();
> +
> +       p = memset (u.buf+2, '\0', len);
> +       if (p != u.buf+2) abort ();
> +       check (2, len, '\0');
> +
> +       p = memset (u.buf+2, A, len);
> +       if (p != u.buf+2) abort ();
> +       check (2, len, 'A');
> +
> +       p = memset (u.buf+2, 'B', len);
> +       if (p != u.buf+2) abort ();
> +       check (2, len, 'B');
> +     }
> +
> +   /* off == 3 */
> +   for (len = 0; len < MAX_COPY; len++)
> +     {
> +       reset ();
> +
> +       p = memset (u.buf+3, '\0', len);
> +       if (p != u.buf+3) abort ();
> +       check (3, len, '\0');
> +
> +       p = memset (u.buf+3, A, len);
> +       if (p != u.buf+3) abort ();
> +       check (3, len, 'A');
> +
> +       p = memset (u.buf+3, 'B', len);
> +       if (p != u.buf+3) abort ();
> +       check (3, len, 'B');
> +     }
> +
> +   /* off == 4 */
> +   for (len = 0; len < MAX_COPY; len++)
> +     {
> +       reset ();
> +
> +       p = memset (u.buf+4, '\0', len);
> +       if (p != u.buf+4) abort ();
> +       check (4, len, '\0');
> +
> +       p = memset (u.buf+4, A, len);
> +       if (p != u.buf+4) abort ();
> +       check (4, len, 'A');
> +
> +       p = memset (u.buf+4, 'B', len);
> +       if (p != u.buf+4) abort ();
> +       check (4, len, 'B');
> +     }
> +
> +   /* off == 5 */
> +   for (len = 0; len < MAX_COPY; len++)
> +     {
> +       reset ();
> +
> +       p = memset (u.buf+5, '\0', len);
> +       if (p != u.buf+5) abort ();
> +       check (5, len, '\0');
> +
> +       p = memset (u.buf+5, A, len);
> +       if (p != u.buf+5) abort ();
> +       check (5, len, 'A');
> +
> +       p = memset (u.buf+5, 'B', len);
> +       if (p != u.buf+5) abort ();
> +       check (5, len, 'B');
> +     }
> +
> +   /* off == 6 */
> +   for (len = 0; len < MAX_COPY; len++)
> +     {
> +       reset ();
> +
> +       p = memset (u.buf+6, '\0', len);
> +       if (p != u.buf+6) abort ();
> +       check (6, len, '\0');
> +
> +       p = memset (u.buf+6, A, len);
> +       if (p != u.buf+6) abort ();
> +       check (6, len, 'A');
> +
> +       p = memset (u.buf+6, 'B', len);
> +       if (p != u.buf+6) abort ();
> +       check (6, len, 'B');
> +     }
> +
> +   /* off == 7 */
> +   for (len = 0; len < MAX_COPY; len++)
> +     {
> +       reset ();
> +
> +       p = memset (u.buf+7, '\0', len);
> +       if (p != u.buf+7) abort ();
> +       check (7, len, '\0');
> +
> +       p = memset (u.buf+7, A, len);
> +       if (p != u.buf+7) abort ();
> +       check (7, len, 'A');
> +
> +       p = memset (u.buf+7, 'B', len);
> +       if (p != u.buf+7) abort ();
> +       check (7, len, 'B');
> +     }
> +
> +   exit (0);
> + }
> +
>
> Roger

Andreas
-- 
 Andreas Jaeger
  SuSE Labs aj@suse.de
   private aj@arthur.inka.de
    http://www.suse.de/~aj

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] PR opt/7291: bzero problems on x86_64
  2002-07-23 22:58 ` Andreas Jaeger
@ 2002-07-25 10:11   ` Mark Mitchell
  0 siblings, 0 replies; 4+ messages in thread
From: Mark Mitchell @ 2002-07-25 10:11 UTC (permalink / raw)
  To: Andreas Jaeger, Roger Sayle; +Cc: gcc-patches, fvdl

> Exactly the same patch is needed for the 3.1 branch.  Ok to add for 3.2
> after it has been branched?

Yes.

-- 
Mark Mitchell                mark@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2002-07-25 16:28 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-07-23 19:32 [PATCH] PR opt/7291: bzero problems on x86_64 Roger Sayle
2002-07-23 22:33 ` Mark Mitchell
2002-07-23 22:58 ` Andreas Jaeger
2002-07-25 10:11   ` Mark Mitchell

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).