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]

PATCH: to fix gcc.c-torture/execute/20010124-1.c failure


This is a fix for the regression from 2.95.2 as found by
gcc.c-torture/execute/20010124-1.c .  Here is a line of argument on
why this is a correct fix: Under some calling conventions, 3.0 is
smarter than 2.95 when calling a function that returns a structure.
It may now pass the address of any immediate resting place of the
return value instead of the address of a staging buffer (which had
been allocated on the stack).  Of course, this improvement means that
source and target memory now has the possibility to overlap.

Independent of all this recent history, and at some point before
recorded history available in the current CVS archive,
expand_assignment() was originally written and/or modified to allow it
to use either bcopy or memcpy to perform the assignment at runtime.
Given that expand_assignment() is not documented to only handle
non-overlapping cases, it may never have been right on some platforms.
memmove, not memcpy, is the ISO equivalent to bcopy when overlap of
source and target memory is a possibility.

Bootstrapped and tested on the 3.0 branch on i386-unknown-freebsd4.2.
The only changes were the expected disappearance of these failures:

FAIL: gcc.c-torture/execute/20010124-1.c execution,  -O0 
FAIL: gcc.c-torture/execute/20010124-1.c execution,  -O1 
FAIL: gcc.c-torture/execute/20010124-1.c execution,  -O2 
FAIL: gcc.c-torture/execute/20010124-1.c execution,  -O3 -fomit-frame-pointer 
FAIL: gcc.c-torture/execute/20010124-1.c execution,  -O3 -g 
FAIL: gcc.c-torture/execute/20010124-1.c execution,  -Os 

People that know more about this area of the compiler might want to
consider these points:

- memcpy_libfunc could still be used instead of memmove_libfunc
  whenever we can detect at compile-time that overlap is impossible.

- Some other places exist where emit_library_call(memcpy_libfunc, [...])
  may be used in place of emit_library_call(bcopy_libfunc, [...]).
  However, it is unclear to me that they have to deal with overlapping
  memory issues.

- Once we use emit_library_call() here, it seems that any related
  builtin function provided within gcc will not be considered, no
  matter what optimization level.

- Finally, note that there is currently no builtin for memmove so the
  last point is now moot.

Here is the argument against this patch or any similar patch and for
declaring the regression bogus: it was a quirk of implementation that
allowed this test to pass under 2.95.2.  A related testcase that uses
this main() has a "failure" on my platform with 2.95.2 (except this
case does use the builtin memcpy thus RTH's technique for finding the
failure has to be rewritten to look for trashed memory inside u
instead of invalid calls to memcpy):

int main()
{
  union U u = {0, {0, 1, 2, 3, 4}};
  u.b.s = u.a.s;
  u.a.s = u.b.s;
  g(&u);
  return 0;
}

(All other declarations are as in gcc.c-torture/execute/20010124-1.c.)

Note: my patch doesn't "fix" this "failure".  It is unclear that an
implementation has to allow either set of code.

Regards,
Loren

2001-03-06  Loren J. Rittle  <ljrittle@acm.org>

	* expr.h (enum libfunc_index): Add LTI_memmove.
	(memmove_libfunc): Define macro.
	* optabs.c (init_optabs): Initialize memmove_libfunc.
	* expr.c (expand_assignment): Use memmove_libfunc instead of
	memcpy_libfunc.

Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.295.2.1
diff -c -r1.295.2.1 expr.c
*** expr.c	2001/03/02 19:51:56	1.295.2.1
--- expr.c	2001/03/06 05:08:09
***************
*** 3843,3849 ****
  			   TYPE_MODE (sizetype));
  
  #ifdef TARGET_MEM_FUNCTIONS
!       emit_library_call (memcpy_libfunc, LCT_NORMAL,
  			 VOIDmode, 3, XEXP (to_rtx, 0), Pmode,
  			 XEXP (from_rtx, 0), Pmode,
  			 convert_to_mode (TYPE_MODE (sizetype),
--- 3843,3849 ----
  			   TYPE_MODE (sizetype));
  
  #ifdef TARGET_MEM_FUNCTIONS
!       emit_library_call (memmove_libfunc, LCT_NORMAL,
  			 VOIDmode, 3, XEXP (to_rtx, 0), Pmode,
  			 XEXP (from_rtx, 0), Pmode,
  			 convert_to_mode (TYPE_MODE (sizetype),
Index: expr.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.h,v
retrieving revision 1.73
diff -c -r1.73 expr.h
*** expr.h	2000/12/03 23:58:44	1.73
--- expr.h	2001/03/06 05:08:09
***************
*** 493,498 ****
--- 493,499 ----
    LTI_trunctfdf2,
  
    LTI_memcpy,
+   LTI_memmove,
    LTI_bcopy,
    LTI_memcmp,
    LTI_bcmp,
***************
*** 626,631 ****
--- 627,633 ----
  #define trunctfdf2_libfunc	(libfunc_table[LTI_trunctfdf2])
  
  #define memcpy_libfunc	(libfunc_table[LTI_memcpy])
+ #define memmove_libfunc	(libfunc_table[LTI_memmove])
  #define bcopy_libfunc	(libfunc_table[LTI_bcopy])
  #define memcmp_libfunc	(libfunc_table[LTI_memcmp])
  #define bcmp_libfunc	(libfunc_table[LTI_bcmp])
Index: optabs.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/optabs.c,v
retrieving revision 1.87
diff -c -r1.87 optabs.c
*** optabs.c	2001/01/28 01:50:06	1.87
--- optabs.c	2001/03/06 05:08:11
***************
*** 4757,4762 ****
--- 4757,4763 ----
    trunctfdf2_libfunc = init_one_libfunc ("__trunctfdf2");
  
    memcpy_libfunc = init_one_libfunc ("memcpy");
+   memmove_libfunc = init_one_libfunc ("memmove");
    bcopy_libfunc = init_one_libfunc ("bcopy");
    memcmp_libfunc = init_one_libfunc ("memcmp");
    bcmp_libfunc = init_one_libfunc ("__gcc_bcmp");


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