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