On Fri, 21 Oct 2016 08:30:06 PDT (-0700),
sor...@gmail.com wrote:
> On Fri, Oct 21, 2016 at 5:31 AM, Richard W.M. Jones <
rjo...@redhat.com> wrote:
>>
>> I have a few related questions about alignment on RV64G, and the
>> GCC -Wcast-align warning. I am using:
>>
>> gcc (GCC) 6.1.0 20160427 (Red Hat 6.1.0-1)
>>
>> with the riscv-gcc patch.
>>
>> (1) Is it correct that RV64G allows reads and writes of any size at
>> any byte alignment?
>
> Yes. (
https://content.riscv.org/wp-content/uploads/2016/06/riscv-spec-v2.1.pdf#page=28
> )
>
>> (2) The program align.c below provokes a -Wcast-align warning.
>> (Obviously the code is terrible and not even valid C99, it's just
>> designed to demonstrate the warning).
>>
>> align.c:8:12: warning: cast increases required alignment of target type [-Wcast-align]
>> int *i = (int *) d;
>> ^
>>
>> Why does it print this warning if any alignment is permitted?
>
> Probably a gcc bug since it doesn't print the warning on x86, which
> has the same rules.
I'm hesitant to call this a bug: even though RISC-V allows unaligned memory
operations, on all the implementations I know about it's a bad idea from a
performance perspective and since this is just a warning I think it's sane.
Since this doesn't trigger on x86 I'd be OK changing the behavior, but I'd want
to make sure it doesn't have any ramifications first (and I'm pretty sure it
will). Looking at the GCC sources, it should be an easy fix: I believe
STRICT_ALIGNMENT is the port-specific flag that controls these kind of
warnings. We have
/* All accesses must be aligned. */
#define STRICT_ALIGNMENT 1
which is false according the spec, but I think a reasonable assumption given
the implementations that exist. x86 has
/* x86 doesn't require strict alignment for the basic types. */
#define STRICT_ALIGNMENT 0
so based on that x86 comment I think we would be safe removing the alignment
constraint, but I'd be super worried about the codegen going terrible if we
flipped that bit. The x86 port is complicated and I'm not sure what the
alignment restrictions on high-performance x86 code are, so I didn't look
further into it.
Note that TileGx, which had exactly the same alignment requirements RISC-V does
(Linux fixed unaligned accesses from userspace) just sets
#define STRICT_ALIGNMENT 1
without any comments, so I'm assuming this would result in bad code gen (the
alignment traps are really slow, so it doesn't take many unaligned accesses to
make this approach bad).
The 68k GCC port looks like it has support for changing the alignment as a GCC
option:
$ git grep STRICT_ALIGNMENT | grep m68k
gcc/ChangeLog-1999: * config/m68k/m68k.h (MASK_NO_STRICT_ALIGNMENT): New macro.
gcc/ChangeLog-2007: * config/m68k/m68k.h (M68K_HONOR_TARGET_STRICT_ALIGNMENT):
gcc/FSFChangeLog.10: * m68k/linux.h (STRICT_ALIGNMENT): Define to zero.
gcc/config/m68k/linux.h:#undef STRICT_ALIGNMENT
gcc/config/m68k/linux.h:#define STRICT_ALIGNMENT 0
gcc/config/m68k/linux.h:#undef M68K_HONOR_TARGET_STRICT_ALIGNMENT
gcc/config/m68k/linux.h:#define M68K_HONOR_TARGET_STRICT_ALIGNMENT 0
gcc/config/m68k/m68k.c:#if M68K_HONOR_TARGET_STRICT_ALIGNMENT
gcc/config/m68k/m68k.c:#if M68K_HONOR_TARGET_STRICT_ALIGNMENT
gcc/config/m68k/m68k.c: target_mask |= MASK_STRICT_ALIGNMENT;
gcc/config/m68k/m68k.c:#if M68K_HONOR_TARGET_STRICT_ALIGNMENT
gcc/config/m68k/m68k.h:#define STRICT_ALIGNMENT (TARGET_STRICT_ALIGNMENT)
gcc/config/m68k/m68k.h:#define M68K_HONOR_TARGET_STRICT_ALIGNMENT 1
gcc/config/m68k/m68k.opt:Target Report Mask(STRICT_ALIGNMENT)
I'd be OK taking a patch that implements this on RISC-V, but I'm not going to
write one until there's hardware that supports unaligned operations. This flag
will probably break the ABI, so it's probably not going to be well supported.
I'd tell you to open a github issue for further comments, but it looks like the
internet has completely melted down here :).