Julian Brown julian@codesourcery.com writes:
- Builtins (__builtin_neon_*) which previously used "big" integer
modes to pass/return values, are initialised such that they directly pass/return the struct types above instead. The intrinsic wrappers in arm_neon.h no longer need to use unions to pun the types of arguments & return values.
Yeah, I'd wondered about that too. However, these days, I think we ought to be able to generate good code for this type of union, and we seem to for the cases I've tried. In the end I thought it was better to keep the underlying built-in function close to the rtl pattern. E.g. the fact that the name of the field is "val" seems more like an arm_neon.h detail than something that should be hard-coded into GCC.
I still think it's a good idea to get rid of the unions in this case, or at least, replace the wide-integer modes in the unions with wide vectors. But I'm happy with whatever works :-).
Yeah, I was wondering about changing the mode to a vector mode (which is what the rtl pattern will use), but keeping the union.
I think we should keep the integer modes too, though, just like we allow DImode for double registers. (I'm surprised to see we don't allow TImode for quad registers TBH -- might look into that.) Given that there are no architectual restrictions on mode punning, these integer modes are useful neutral ground.
I'm not convinced by that. Consider that:
There are no useful operations on the wide-integer types.
There is no way of representing constants in RTL for the
wide-integer types (we have an internal bug where a constant-zero OImode value is synthesized when using NEON intrinsics, and it leads to an ICE: see emit-rtl.c:immed_double_const -- OImode, etc. are wider than 2 * HOST_BITS_PER_WIDE_INT, so fail the second assertion).
Unless we can show that the wide-integer modes are really needed, and patch things up so (2) no longer holds, I'd strongly prefer to see them disappear. (As a side note, we obviously want to avoid wide-integer or wide-vector modes *ever* being reloaded via core registers, since there simply aren't enough of them for that to be possible. I think that may be one of the reasons that integer-equivalent modes for each size have traditionally been used by the compiler?).
I think the main reason is that integer modes simply represent a string of bits, without any particular interpretation (not even signed vs. unsigned). So the restrictions on subregs are much more lax than they are for more specialised modes like floating-point and vector modes.
We can stop large modes from being stored in integer registers regardless of whether the mode is an integer or a vector (and we already do this). There's certainly the potential to mess things up by defining the secondary reload hooks in the wrong way -- see for instance
http://gcc.gnu.org/ml/gcc-patches/2011-01/msg02266.html
-- but the restriction is already there in principle.
I take your point about (2) not being possible at the moment, but that's a flaw that's worth fixing in its own right.
Richard