Register conflicts between output memory address and output register

2018-04-17 Thread Matthew Fortune
Hi,

I've been investigating some quirks of register allocation when handling
some inline asm. The behaviour is non-intuitive but I am not sure if it
is a bug or not. This is back on GCC 6 so I'm still reviewing to see if
anything changed in this area since then.

The inline asm in question is:

int bar;
int my_mem;

void foo()
{
  asm volatile ("%0, %1, %2" : "=m"(my_mem), "=r"(bar)
 : "m"(my_mem)
 : "memory");
}

What I see is that if the address of my_mem is lowered prior to IRA then
there is a pseudo register for the output memory address (and perhaps an
offset) and a pseudo register for the output register. These two registers
are seen as a conflict in IRA so get different registers allocated. This is
good.

If however the address of my_mem is lowered after IRA i.e. when validating
constraints in LRA then IRA has nothing to do as the address is just a
symbol_ref. When LRA resolves the constraint for the address it introduces
a register for the output memory address but does not seem to acknowledge
any conflict with the output register (bar) it can therefore end up
using the same register for the output memory address as the output register.
This leads to the obvious problem if the ASM updates %1 before %0 as it will
corrupt the address.

This can of course be worked around by making (bar) an early clobber or an
in/out but this does seem unnecessary.

The question is... Should LRA recognise a conflict between the registers
involved in the address portion of an output memory operand and any output
register operands or is this a case where you strictly have to use early
clobber.

Any advice welcome!

Thanks,
Matthew


Re: libmvec in gcc to have vector math in fortran

2018-04-17 Thread Szabolcs Nagy

On 10/04/18 14:27, Richard Biener wrote:

On April 10, 2018 3:06:55 PM GMT+02:00, Jakub Jelinek  wrote:

On Tue, Apr 10, 2018 at 02:55:43PM +0200, Richard Biener wrote:

I wonder if it is possible for glibc to ship a "module" for fortran

instead

containing the appropriate declarations and gfortran auto-include

that

(if present).


Then we'd run into module binary format changing every release, so hard
for
glibc to ship that.

Another thing is how would we express it in the module,
we could just use OpenMP syntax,
  interface
function sin(x) bind(C,name="__builtin_sin") result(res)
  import
  !$omp declare simd notinbranch
  real(c_double) :: res
  real(c_double),value :: x
end function
  end interface
but we'd need to temporarily enable OpenMP while parsing that module.
I see Fortran now supports already
!GCC$ attributes stdcall, fastcall::test
Could we support
!GCC$ attributes simd
and
!GCC$ attributes simd('notinbranch')
too?


Maybe we can also generate this module in a fixinlclude way?



ideally everything should work magically but i think
it's good to have a big hammer solution that's easy
to reason about.

the gcc vectorizer should be testable independently
of glibc, and users should be able to specify what
can be vectorized.

if this is via a per-frontend declaration syntax,
then i see implementation and usability issues, while
those are sorted out a single flag that requests every
function known to gcc to be vectorized sounds to me a
viable big hammer solution: easy to implement and
enables users to start experimenting with simd math.

(the implementation may use a preincluded fortran
module internally, but i think it makes sense to
have a single flag ui too)