This is the mail archive of the gcc@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]

aliasing problem with va_arg


This testcase gives incorrect code for a sparc-sun-solaris2 target when
compiled with -O2.

#include <stdarg.h>
extern double bar (double);
double foo (va_list ap) {
  double d = va_arg (ap, double);
  return bar (d);
}

The problem is that a SImode store created by the va_arg expansion is being
moved after the DFmode load of the result.  This movement comes from
DIFFERENT_ALIAS_SETS_P which sees that the two MEMs have different
MEM_ALIAS_SET values, and hence assumes that they can't overlap.  This macro
already knows that va_arg is unsafe, but it handles va_arg by checking to see
if this is a stdarg or varargs function.  That isn't sufficient, because we
can call va_arg from a function that takes a va_list parameter.  It is
also overkill since it means there is no aliasing within a stdarg/varargs
function, even though it is only MEMs from va_arg expansion that are unsafe.

Long term, I'd suggest changing how we implement va_arg.  Instead of a macro
that expands to complicated non-ISO C code, we should instead have a target
independent macro that expands to a call to a built-in function, e.g.
builtin_va_arg.  builtin_va_arg is then implemented by calling a target
dependent function that emits appropriate RTL.  When this code generates
RTL, it can set MEM_ALIAS_SET appropriately, which probably means setting it
to zero.  It would take a lot of work to convert all of the ports to a new
va_arg scheme though.  I did this once for irix6 as an experiment.  I can
send the patches if anyone is interested.  They would need a lot of work
before they could be checked in.

Short term, I am not sure what to do.  We can't easily search the parameter
list for va_list types, because that is a macro that could expand to any
type.  We could probably add some GNU C extension used to mark functions
that call va_arg, similar to the ... extension used for marking vararg
functions.  That seems like an ugly hack though.

Perhaps we can add code to dynamically enable/disable alias set computations.
E.g. add builtin functions __builtin_disable_aliasing, and
__builtin_enable_aliasing, modify va_arg to call them at the beginning and
end, and then modify get_alias_set to always return zero if
__builtin_disable_aliasing has been called.  We could then get rid of
the varargs/stdarg function checks in DIFFERENT_ALIAS_SETS_P, while
fixing va_list functions at the same time.

Jim


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