Wilco Dijkstra <wilco.dijks...@arm.com> writes:
> Richard Sandiford <richard.sandif...@linaro.org>
>> The "?" change seems to make intrinsic sense given the extra cost of the
>> GPR alternative.  But I think the real reason for this failure is that
>> we define no V1DF patterns, and target-independent code falls back to
>> using moves in the corresponding *integer* mode.  So for that function
>> we generate the rather ugly code:
>
> This:
>
> typedef struct { double x; } X;
> X f2(X *p)
> {
>   return *p;
> }
>
> emits at expand:
>
> (insn 6 3 7 2 (set (reg:DF 90 [ D.21009 ])
>         (mem:DF (reg/v/f:DI 92 [ p ]) [2 *p_2(D)+0 S8 A64])) 
> "vect_copy_lane_1.c":26 -1
>      (nil))
> (insn 7 6 8 2 (set (subreg:DF (reg:DI 94) 0)
>         (reg:DF 90 [ D.21009 ])) "vect_copy_lane_1.c":26 -1
>      (nil))
> (insn 8 7 9 2 (set (reg:DI 95)
>         (reg:DI 94)) "vect_copy_lane_1.c":26 -1
>      (nil))
> (insn 9 8 13 2 (set (reg:DF 91 [ <retval> ])
>         (subreg:DF (reg:DI 95) 0)) "vect_copy_lane_1.c":26 -1
>      (nil))
>
> So the underlying cause is the structure passing code. Things get
> worse when you return 2 doubles and it really becomes horrific at 3...

Yeah, the handling of structures can also be poor, but float64x1_t is a
vector type rather than a structure, so I don't think the above is the
problem in the specific case of test_copy_laneq_f64.

float64x1_t has the TYPE_MODE we want (V1DF).  But because we have
no V1DF move pattern, it ends up being moved as a DI instead.

Thanks,
Richard

Reply via email to