This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Bad MEM_SIZE for cmpmem causes wrong scheduling


Hello,

I'm seeing testsuite failures in gcc.c-torture/execute/builtins/strpcpy.c
which are caused by the scheduler missing a dependency.  The code in
question does something equivalent to

  unsigned char a[16] = "";

  memcpy (a + 2, "ab", 3);
  if (memcmp (a + 1, "\0" "ab" "\0", 4))
    abort ();

which gets expanded into a movmem insn followed by a cmpmem insn.
However, the scheduler reverses the order of the two insns.

This is caused by the MEM_SIZE attribute of the first argument of
the cmpmem insn being 1, which causes the scheduler to think there
is no dependency (because a+1/len1 doesn't overlap a+2/len3).

The following patch fixes the problem by simply setting MEM_SIZE
to the actual comparison length if that is known at compile-time.
This is analogous to what's being done for movmem in expr.c
(emit_block_move).

While this does fix the strpcpy.c test case, I'm not quite sure
this is the proper solution; shouldn't get_memory_rtx have 
recognized that the whole array 'a' could potentially be the
target of the memcmp?

Bootstrapped/regtested on s390-ibm-linux and s390x-ibm-linux.
OK for mainline?

Bye,
Ulrich


ChangeLog:

	* builtins.c (expand_builtin_memcmp): Adjust MEM_SIZE to
	reflect size of memory regions being compared.

Index: gcc/builtins.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/builtins.c,v
retrieving revision 1.386
diff -c -p -r1.386 builtins.c
*** gcc/builtins.c	20 Sep 2004 14:47:17 -0000	1.386
--- gcc/builtins.c	22 Sep 2004 23:37:43 -0000
*************** expand_builtin_memcmp (tree exp ATTRIBUT
*** 3537,3542 ****
--- 3537,3550 ----
      arg1_rtx = get_memory_rtx (arg1);
      arg2_rtx = get_memory_rtx (arg2);
      arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
+ 
+     /* Set MEM_SIZE as appropriate.  */
+     if (GET_CODE (arg3_rtx) == CONST_INT)
+       {
+ 	set_mem_size (arg1_rtx, arg3_rtx);
+ 	set_mem_size (arg2_rtx, arg3_rtx);
+       }
+ 
  #ifdef HAVE_cmpmemsi
      if (HAVE_cmpmemsi)
        insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
-- 
  Dr. Ulrich Weigand
  weigand@informatik.uni-erlangen.de


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]