Gentle PING.
On Wed, Oct 7, 2020 at 12:39 PM Claudiu Zissulescu <claz...@gmail.com> wrote: > > From: Claudiu Zissulescu <claz...@gmail.com> > > The compiler can match mpyd.eq r0,r1,r0 as a predicated instruction, > which is incorrect. The mpyd(u) instruction takes as input two 32-bit > registers, returning into a double 64-bit even-odd register pair. For > the predicated case, the ARC instruction decoder expects the > destination register to be the same as the first input register. In > the big-endian case the result is swaped in the destination register > pair, however, the instruction encoding remains the same. Refurbish > the mpyd(u) patterns to take into account the above observation. > > Permission to apply this patch to master, gcc10 and gcc9 branches. > > Cheers, > Claudiu > > xxxx-xx-xx Claudiu Zissulescu <claz...@synopsys.com> > > * testsuite/gcc.target/arc/pmpyd.c: New test. > * testsuite/gcc.target/arc/tmac-1.c: Update. > * config/arc/arc.md (mpyd<su_optab>_arcv2hs): New template > pattern. > (*pmpyd<su_optab>_arcv2hs): Likewise. > (*pmpyd<su_optab>_imm_arcv2hs): Likewise. > (mpyd_arcv2hs): Moved into above template. > (mpyd_imm_arcv2hs): Moved into above template. > (mpydu_arcv2hs): Likewise. > (mpydu_imm_arcv2hs): Likewise. > (su_optab): New optab prefix for sign/zero-extending operations. > > Signed-off-by: Claudiu Zissulescu <claz...@gmail.com> > --- > gcc/config/arc/arc.md | 101 +++++++++++++------------- > gcc/testsuite/gcc.target/arc/pmpyd.c | 15 ++++ > gcc/testsuite/gcc.target/arc/tmac-1.c | 2 +- > 3 files changed, 67 insertions(+), 51 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/arc/pmpyd.c > > diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md > index 1720e8cd2f6f..d4d9f59a3eac 100644 > --- a/gcc/config/arc/arc.md > +++ b/gcc/config/arc/arc.md > @@ -894,6 +894,8 @@ archs4x, archs4xd" > > (define_code_iterator SEZ [sign_extend zero_extend]) > (define_code_attr SEZ_prefix [(sign_extend "sex") (zero_extend "ext")]) > +; Optab prefix for sign/zero-extending operations > +(define_code_attr su_optab [(sign_extend "") (zero_extend "u")]) > > (define_insn "*<SEZ_prefix>xt<SQH_postfix>_cmp0_noout" > [(set (match_operand 0 "cc_set_register" "") > @@ -6436,66 +6438,65 @@ archs4x, archs4xd" > (set_attr "predicable" "no") > (set_attr "cond" "nocond")]) > > -(define_insn "mpyd_arcv2hs" > - [(set (match_operand:DI 0 "even_register_operand" > "=Rcr, r") > - (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " > 0, c")) > - (sign_extend:DI (match_operand:SI 2 "register_operand" " > c, c")))) > +(define_insn "mpyd<su_optab>_arcv2hs" > + [(set (match_operand:DI 0 "even_register_operand" "=r") > + (mult:DI (SEZ:DI (match_operand:SI 1 "register_operand" "r")) > + (SEZ:DI (match_operand:SI 2 "register_operand" "r")))) > (set (reg:DI ARCV2_ACC) > (mult:DI > - (sign_extend:DI (match_dup 1)) > - (sign_extend:DI (match_dup 2))))] > + (SEZ:DI (match_dup 1)) > + (SEZ:DI (match_dup 2))))] > "TARGET_PLUS_MACD" > - "mpyd%? %0,%1,%2" > - [(set_attr "length" "4,4") > - (set_attr "iscompact" "false") > - (set_attr "type" "multi") > - (set_attr "predicable" "yes,no") > - (set_attr "cond" "canuse,nocond")]) > - > -(define_insn "mpyd_imm_arcv2hs" > - [(set (match_operand:DI 0 "even_register_operand" > "=Rcr, r,r,Rcr, r") > - (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " > 0, c,0, 0, c")) > - (match_operand 2 "immediate_operand" " > L, L,I,Cal,Cal"))) > + "mpyd<su_optab>%?\\t%0,%1,%2" > + [(set_attr "length" "4") > + (set_attr "iscompact" "false") > + (set_attr "type" "multi") > + (set_attr "predicable" "no")]) > + > +(define_insn "*pmpyd<su_optab>_arcv2hs" > + [(set (match_operand:DI 0 "even_register_operand" "=r") > + (mult:DI > + (SEZ:DI (match_operand:SI 1 "even_register_operand" "%0")) > + (SEZ:DI (match_operand:SI 2 "register_operand" "r")))) > (set (reg:DI ARCV2_ACC) > - (mult:DI (sign_extend:DI (match_dup 1)) > - (match_dup 2)))] > + (mult:DI > + (SEZ:DI (match_dup 1)) > + (SEZ:DI (match_dup 2))))] > "TARGET_PLUS_MACD" > - "mpyd%? %0,%1,%2" > - [(set_attr "length" "4,4,4,8,8") > - (set_attr "iscompact" "false") > - (set_attr "type" "multi") > - (set_attr "predicable" "yes,no,no,yes,no") > - (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")]) > - > -(define_insn "mpydu_arcv2hs" > - [(set (match_operand:DI 0 "even_register_operand" > "=Rcr, r") > - (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " > 0, c")) > - (zero_extend:DI (match_operand:SI 2 "register_operand" " > c, c")))) > + "mpyd<su_optab>%?\\t%0,%1,%2" > + [(set_attr "length" "4") > + (set_attr "iscompact" "false") > + (set_attr "type" "multi") > + (set_attr "predicable" "yes")]) > + > +(define_insn "mpyd<su_optab>_imm_arcv2hs" > + [(set (match_operand:DI 0 "even_register_operand" "=r,r, r") > + (mult:DI (SEZ:DI (match_operand:SI 1 "register_operand" "r,0, r")) > + (match_operand 2 "immediate_operand" "L,I,Cal"))) > (set (reg:DI ARCV2_ACC) > - (mult:DI (zero_extend:DI (match_dup 1)) > - (zero_extend:DI (match_dup 2))))] > + (mult:DI (SEZ:DI (match_dup 1)) > + (match_dup 2)))] > "TARGET_PLUS_MACD" > - "mpydu%? %0,%1,%2" > - [(set_attr "length" "4,4") > - (set_attr "iscompact" "false") > - (set_attr "type" "multi") > - (set_attr "predicable" "yes,no") > - (set_attr "cond" "canuse,nocond")]) > - > -(define_insn "mpydu_imm_arcv2hs" > - [(set (match_operand:DI 0 "even_register_operand" > "=Rcr, r,r,Rcr, r") > - (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " > 0, c,0, 0, c")) > - (match_operand 2 "immediate_operand" " > L, L,I,Cal,Cal"))) > + "mpyd<su_optab>%?\\t%0,%1,%2" > + [(set_attr "length" "4,4,8") > + (set_attr "iscompact" "false") > + (set_attr "type" "multi") > + (set_attr "predicable" "no")]) > + > +(define_insn "*pmpyd<su_optab>_imm_arcv2hs" > + [(set (match_operand:DI 0 "even_register_operand" "=r,r") > + (mult:DI > + (SEZ:DI (match_operand:SI 1 "even_register_operand" "0,0")) > + (match_operand 2 "immediate_operand" "L,Cal"))) > (set (reg:DI ARCV2_ACC) > - (mult:DI (zero_extend:DI (match_dup 1)) > + (mult:DI (SEZ:DI (match_dup 1)) > (match_dup 2)))] > "TARGET_PLUS_MACD" > - "mpydu%? %0,%1,%2" > - [(set_attr "length" "4,4,4,8,8") > - (set_attr "iscompact" "false") > - (set_attr "type" "multi") > - (set_attr "predicable" "yes,no,no,yes,no") > - (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")]) > + "mpyd<su_optab>%?\\t%0,%1,%2" > + [(set_attr "length" "4,8") > + (set_attr "iscompact" "false") > + (set_attr "type" "multi") > + (set_attr "predicable" "yes")]) > > (define_insn "*add_shift" > [(set (match_operand:SI 0 "register_operand" "=q,r,r") > diff --git a/gcc/testsuite/gcc.target/arc/pmpyd.c > b/gcc/testsuite/gcc.target/arc/pmpyd.c > new file mode 100644 > index 000000000000..0eb0ff7f11b6 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/arc/pmpyd.c > @@ -0,0 +1,15 @@ > +/* { dg-do assemble } */ > +/* { dg-skip-if "" { ! { clmcpu } } } */ > +/* { dg-options "-mcpu=hs38 -Os -EB" } */ > + > +/* This example is found during big-endian build. The compiler is > + matching mpydu.hi r12,r13,r3 as a predicated instruction, which is > + incorrect. The error is due to different predicates between the > + output operand and the first operand of the instruction. */ > +unsigned int test(unsigned int x, unsigned long long y) > +{ > + y /= 0x20000000; > + if (x > 1) > + y *= x; > + return y; > +} > diff --git a/gcc/testsuite/gcc.target/arc/tmac-1.c > b/gcc/testsuite/gcc.target/arc/tmac-1.c > index 3fcabf5fff2d..5b302cad4a4a 100644 > --- a/gcc/testsuite/gcc.target/arc/tmac-1.c > +++ b/gcc/testsuite/gcc.target/arc/tmac-1.c > @@ -7,5 +7,5 @@ > > /* { dg-final { scan-assembler "macd " } } */ > /* { dg-final { scan-assembler "macdu" } } */ > -/* { dg-final { scan-assembler "mpyd " } } */ > +/* { dg-final { scan-assembler "mpyd\\t" } } */ > /* { dg-final { scan-assembler "mpydu" } } */ > -- > 2.26.2 >