On 26/04/17 13:39, Wilco Dijkstra wrote: > Float to int moves currently generate inefficient code due to > hacks used in the movsi and movdi patterns. The 'r = w' variant > uses '*' which explicitly tells the register allocator to ignore it. > As a result float to int moves typically spill to the stack, which is > extremely inefficient. For example: > > static inline unsigned asuint (float f) > { > union { float f; unsigned i; } u = {f}; > return u.i; > } > > float foo (float x) > { > unsigned i = asuint (x); > if (__builtin_expect (i > 42, 0)) > return x*x; > return i; > } > > generates: > > sub sp, sp, #16 > str s0, [sp, 12] > ldr w0, [sp, 12] > cmp w0, 42 > bhi .L7 > scvtf s0, w0 > add sp, sp, 16 > ret > .L7: > fmul s0, s0, s0 > add sp, sp, 16 > ret > > Removing '*' from the variant generates: > > fmov w0, s0 > cmp w0, 42 > bhi .L6 > scvtf s0, w0 > ret > .L6: > fmul s0, s0, s0 > ret > > Passes regress & bootstrap, OK for commit? > > ChangeLog: > 2017-04-26 Wilco Dijkstra <wdijk...@arm.com> > > * config/aarch64/aarch64.md (movsi_aarch64): Remove '*' from r=w. > (movdi_aarch64): Likewise. >
OK. While on the subject, why is the w->w operation also hidden? R. > -- > diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md > index > 51368e29f2d1fd12f48a972bd81a08589a720e07..d656e92e1ff02bdc90c824227ec3b2e1ccfe665a > 100644 > --- a/gcc/config/aarch64/aarch64.md > +++ b/gcc/config/aarch64/aarch64.md > @@ -1026,8 +1026,8 @@ (define_expand "mov<mode>" > ) > > (define_insn_and_split "*movsi_aarch64" > - [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,r,*w,m, > m,r,r ,*w, r,*w") > - (match_operand:SI 1 "aarch64_mov_operand" " r,r,k,M,n,m, > m,rZ,*w,S,Ush,rZ,*w,*w"))] > + [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,r,*w,m, > m,r,r ,*w,r,*w") > + (match_operand:SI 1 "aarch64_mov_operand" " r,r,k,M,n,m, > m,rZ,*w,S,Ush,rZ,w,*w"))] > "(register_operand (operands[0], SImode) > || aarch64_reg_or_zero (operands[1], SImode))" > "@ > @@ -1058,8 +1058,8 @@ (define_insn_and_split "*movsi_aarch64" > ) > > (define_insn_and_split "*movdi_aarch64" > - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,r,*w,m, > m,r,r, *w, r,*w,w") > - (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,n,m, > m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))] > + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,r,*w,m, > m,r,r, *w,r,*w,w") > + (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,n,m, > m,rZ,*w,S,Ush,rZ,w,*w,Dd"))] > "(register_operand (operands[0], DImode) > || aarch64_reg_or_zero (operands[1], DImode))" > "@ >