Richard Guenther <richard.guent...@gmail.com> writes:
>>> For your case in question the vectorizer would create local vars with
>>> that mode, knowing it is supported, so I don't see big problems for
>>> that particular case.
>>
>> The problem is that I'd like to use this for intrinsics as well as for
>> automatic vectorisation.  E.g. I'd like:
>>
>> typedef struct int8x16x4_t
>> {
>>  int8x16_t val[4];
>> } int8x16x4_t;
>>
>> to have non-BLKmode as well.  arm_neon.h uses this type of structure
>> to represent compounds vectors.  But once the type is defined (with Neon
>> support enabled), there's nothing to stop someone using the type
>> (not the intrinsics) in a function that has Neon disabled.  We mustn't
>> use the special mode in such cases, because there aren't enough GPRs to
>> store it.  It should be treated as BLKmode instead.  Which I suppose
>> is the same situation as...
>
> I'd use non-BLKmode for the above unconditionally.

But without Neon, there aren't enough registers to store the structure.
Any use of the Neon mode would just lead to a reload failure.  Even if
we think it's not sensible to use the type without Neon, we need a better
diagnostic than that.

So I think this mode has to be conditional in exactly the way that
vector modes are, or be subject to the same diagnostics that you
were suggesting for 128-bit types.

I was actually thinking along the lines of having a target hook such as:

   array_mode_supported_p (tree elemtype, unsigned HOST_WIDE_INT size)

which would return true if ELEMTYPE[SIZE] should use non-BLKmode where
possible.  When it returns true, we'd pass 0 rather than 1 to this
mode_for_size_tree call (from the ARRAY_TYPE case in layout_type):

            /* One-element arrays get the component type's mode.  */
            if (simple_cst_equal (TYPE_SIZE (type),
                                  TYPE_SIZE (TREE_TYPE (type))))
              SET_TYPE_MODE (type, TYPE_MODE (TREE_TYPE (type)));
            else
              SET_TYPE_MODE (type, mode_for_size_tree (TYPE_SIZE (type),
                                                       MODE_INT, 1));

This would have the "advantage" (as I see it) of working with the
generic vector extensions too.  E.g. if a user defines their own
3-element-array-of-vector type, they would benefit from the same
handling as the Neon-specific intrinsics and the vectoriser-generated
arrays.

We still make generic vectors available when there's no underlying
hardware support, so I'd have expected these 3-element-array-of-vector
types to be available too.  That's why I prefer the idea of making the
mode conditional, as for vector types, rather than rejecting uses of
the type outright.

But from this:

> I'd say if somebody writes
>
> v4sf float_vec;
>
> void __attribute__((target("no-sse")))
> foo (void)
> {
>   float_vec += float_vec;
> }
>
> he deserves to get a diagnostic.  Thus, even for global decls I think we
> can reject such uses.  Complication arises whenever we do not see
> a decl, like for
>
> void foo(v4sf *x)
> {
> }
>
> which we could of course reject (at function definition time) if an
> unsupported type is used in this way.  But the function might
> not even dereference that pointer ...

it sounds like you think there's no point supporting generic vectors
when no underlying hardware support is available.

> And I still think that only changing DECL_MODEs based on
> target attributes and not TYPE_MODEs is appealing ;)

Understood.  I just think that, if we do that, we really should
get rid of TYPE_MODE (as a global property) as well, otherwise there'd
be even more chaos than there is now.  And that sounds like it could
be several months' work in itself.

Richard

Reply via email to