Message ID | VI1PR0801MB2127244849A5CAE15B11216683B90@VI1PR0801MB2127.eurprd08.prod.outlook.com |
---|---|
State | New |
Headers | show |
Series | [ARM] Cleanup multiply patterns | expand |
ping Cleanup the 32-bit multiply patterns. Merge the pre-Armv6 with the Armv6 patterns, remove useless alternatives and order the accumulator operands to prefer MLA Ra, Rb, Rc, Ra whenever feasible. Bootstrap OK on armhf, regress passes. ChangeLog: 2019-09-03 Wilco Dijkstra <wdijkstr@arm.com> * config/arm/arm.md (arm_mulsi3): Remove pattern. (arm_mulsi3_v6): Likewise. (mulsi3addsi_v6): Likewise. (mulsi3subsi): Likewise. (mul): Add new multiply pattern. (mla): Likewise. (mls): Likewise. -- diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 66dafdc47b7cfc37c131764e482d47bcaab90538..681358512e88f6823d1b6d59038f387daaec226e 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -1594,64 +1594,44 @@ (define_expand "mulsi3" "" ) -;; Use `&' and then `0' to prevent the operands 0 and 1 being the same -(define_insn "*arm_mulsi3" - [(set (match_operand:SI 0 "s_register_operand" "=&r,&r") - (mult:SI (match_operand:SI 2 "s_register_operand" "r,r") - (match_operand:SI 1 "s_register_operand" "%0,r")))] - "TARGET_32BIT && !arm_arch6" +;; Use `&' and then `0' to prevent operands 0 and 2 being the same +(define_insn "*mul" + [(set (match_operand:SI 0 "s_register_operand" "=l,r,&r,&r") + (mult:SI (match_operand:SI 2 "s_register_operand" "l,r,r,r") + (match_operand:SI 1 "s_register_operand" "%0,r,0,r")))] + "TARGET_32BIT" "mul%?\\t%0, %2, %1" [(set_attr "type" "mul") - (set_attr "predicable" "yes")] -) - -(define_insn "*arm_mulsi3_v6" - [(set (match_operand:SI 0 "s_register_operand" "=l,l,r") - (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r") - (match_operand:SI 2 "s_register_operand" "l,0,r")))] - "TARGET_32BIT && arm_arch6" - "mul%?\\t%0, %1, %2" - [(set_attr "type" "mul") (set_attr "predicable" "yes") - (set_attr "arch" "t2,t2,*") + (set_attr "arch" "t2,v6,nov6,nov6") (set_attr "length" "4") - (set_attr "predicable_short_it" "yes,yes,no")] + (set_attr "predicable_short_it" "yes,no,*,*")] ) -;; Unnamed templates to match MLA instruction. +;; MLA and MLS instruction. Use operand 1 for the accumulator to prefer +;; reusing the same register. -(define_insn "*mulsi3addsi" - [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r") +(define_insn "*mla" + [(set (match_operand:SI 0 "s_register_operand" "=r,&r,&r,&r") (plus:SI - (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r") - (match_operand:SI 1 "s_register_operand" "%0,r,0,r")) - (match_operand:SI 3 "s_register_operand" "r,r,0,0")))] - "TARGET_32BIT && !arm_arch6" - "mla%?\\t%0, %2, %1, %3" - [(set_attr "type" "mla") - (set_attr "predicable" "yes")] -) - -(define_insn "*mulsi3addsi_v6" - [(set (match_operand:SI 0 "s_register_operand" "=r") - (plus:SI - (mult:SI (match_operand:SI 2 "s_register_operand" "r") - (match_operand:SI 1 "s_register_operand" "r")) - (match_operand:SI 3 "s_register_operand" "r")))] - "TARGET_32BIT && arm_arch6" - "mla%?\\t%0, %2, %1, %3" + (mult:SI (match_operand:SI 3 "s_register_operand" "r,r,r,r") + (match_operand:SI 2 "s_register_operand" "%r,r,0,r")) + (match_operand:SI 1 "s_register_operand" "r,0,r,r")))] + "TARGET_32BIT" + "mla%?\\t%0, %3, %2, %1" [(set_attr "type" "mla") - (set_attr "predicable" "yes")] + (set_attr "predicable" "yes") + (set_attr "arch" "v6,nov6,nov6,nov6")] ) -(define_insn "*mulsi3subsi" +(define_insn "*mls" [(set (match_operand:SI 0 "s_register_operand" "=r") (minus:SI - (match_operand:SI 3 "s_register_operand" "r") - (mult:SI (match_operand:SI 2 "s_register_operand" "r") - (match_operand:SI 1 "s_register_operand" "r"))))] + (match_operand:SI 1 "s_register_operand" "r") + (mult:SI (match_operand:SI 3 "s_register_operand" "r") + (match_operand:SI 2 "s_register_operand" "r"))))] "TARGET_32BIT && arm_arch_thumb2" - "mls%?\\t%0, %2, %1, %3" + "mls%?\\t%0, %3, %2, %1" [(set_attr "type" "mla") (set_attr "predicable" "yes")] )
Hi Wilco, On 9/9/19 6:07 PM, Wilco Dijkstra wrote: > ping > > > Cleanup the 32-bit multiply patterns. Merge the pre-Armv6 with the Armv6 > patterns, remove useless alternatives and order the accumulator operands > to prefer MLA Ra, Rb, Rc, Ra whenever feasible. > > Bootstrap OK on armhf, regress passes. > > ChangeLog: > 2019-09-03 Wilco Dijkstra <wdijkstr@arm.com> > > * config/arm/arm.md (arm_mulsi3): Remove pattern. > (arm_mulsi3_v6): Likewise. > (mulsi3addsi_v6): Likewise. > (mulsi3subsi): Likewise. > (mul): Add new multiply pattern. > (mla): Likewise. > (mls): Likewise. > > -- > diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md > index > 66dafdc47b7cfc37c131764e482d47bcaab90538..681358512e88f6823d1b6d59038f387daaec226e > 100644 > --- a/gcc/config/arm/arm.md > +++ b/gcc/config/arm/arm.md > @@ -1594,64 +1594,44 @@ (define_expand "mulsi3" > "" > ) > > -;; Use `&' and then `0' to prevent the operands 0 and 1 being the same > -(define_insn "*arm_mulsi3" > - [(set (match_operand:SI 0 "s_register_operand" "=&r,&r") > - (mult:SI (match_operand:SI 2 "s_register_operand" "r,r") > - (match_operand:SI 1 "s_register_operand" "%0,r")))] > - "TARGET_32BIT && !arm_arch6" > +;; Use `&' and then `0' to prevent operands 0 and 2 being the same > +(define_insn "*mul" > + [(set (match_operand:SI 0 "s_register_operand" "=l,r,&r,&r") > + (mult:SI (match_operand:SI 2 "s_register_operand" "l,r,r,r") > + (match_operand:SI 1 "s_register_operand" "%0,r,0,r")))] > + "TARGET_32BIT" > "mul%?\\t%0, %2, %1" > [(set_attr "type" "mul") > - (set_attr "predicable" "yes")] > -) > - > -(define_insn "*arm_mulsi3_v6" > - [(set (match_operand:SI 0 "s_register_operand" "=l,l,r") > - (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r") > - (match_operand:SI 2 "s_register_operand" "l,0,r")))] > - "TARGET_32BIT && arm_arch6" > - "mul%?\\t%0, %1, %2" > - [(set_attr "type" "mul") > (set_attr "predicable" "yes") > - (set_attr "arch" "t2,t2,*") > + (set_attr "arch" "t2,v6,nov6,nov6") > (set_attr "length" "4") > - (set_attr "predicable_short_it" "yes,yes,no")] > + (set_attr "predicable_short_it" "yes,no,*,*")] > ) > > -;; Unnamed templates to match MLA instruction. > +;; MLA and MLS instruction. Use operand 1 for the accumulator to prefer > +;; reusing the same register. > > -(define_insn "*mulsi3addsi" > - [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r") > +(define_insn "*mla" > + [(set (match_operand:SI 0 "s_register_operand" "=r,&r,&r,&r") > (plus:SI > - (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r") > - (match_operand:SI 1 "s_register_operand" "%0,r,0,r")) > - (match_operand:SI 3 "s_register_operand" "r,r,0,0")))] > - "TARGET_32BIT && !arm_arch6" > - "mla%?\\t%0, %2, %1, %3" > - [(set_attr "type" "mla") > - (set_attr "predicable" "yes")] > -) > - > -(define_insn "*mulsi3addsi_v6" > - [(set (match_operand:SI 0 "s_register_operand" "=r") > - (plus:SI > - (mult:SI (match_operand:SI 2 "s_register_operand" "r") > - (match_operand:SI 1 "s_register_operand" "r")) > - (match_operand:SI 3 "s_register_operand" "r")))] > - "TARGET_32BIT && arm_arch6" > - "mla%?\\t%0, %2, %1, %3" > + (mult:SI (match_operand:SI 3 "s_register_operand" "r,r,r,r") > + (match_operand:SI 2 "s_register_operand" "%r,r,0,r")) > + (match_operand:SI 1 "s_register_operand" "r,0,r,r")))] > + "TARGET_32BIT" > + "mla%?\\t%0, %3, %2, %1" > [(set_attr "type" "mla") > - (set_attr "predicable" "yes")] > + (set_attr "predicable" "yes") > + (set_attr "arch" "v6,nov6,nov6,nov6")] > ) > > -(define_insn "*mulsi3subsi" > +(define_insn "*mls" > [(set (match_operand:SI 0 "s_register_operand" "=r") > (minus:SI > - (match_operand:SI 3 "s_register_operand" "r") > - (mult:SI (match_operand:SI 2 "s_register_operand" "r") > - (match_operand:SI 1 "s_register_operand" "r"))))] > + (match_operand:SI 1 "s_register_operand" "r") > + (mult:SI (match_operand:SI 3 "s_register_operand" "r") > + (match_operand:SI 2 "s_register_operand" "r"))))] Looks like we'll want to mark operand 2 here with '%' as well? Looks ok to me otherwise. Thanks, Kyrill > "TARGET_32BIT && arm_arch_thumb2" > - "mls%?\\t%0, %2, %1, %3" > + "mls%?\\t%0, %3, %2, %1" > [(set_attr "type" "mla") > (set_attr "predicable" "yes")] > ) >
Hi Kyrill, >> + (mult:SI (match_operand:SI 3 "s_register_operand" "r") >> + (match_operand:SI 2 "s_register_operand" "r"))))] > > Looks like we'll want to mark operand 2 here with '%' as well? That doesn't make any difference since both operands are identical. It only helps if the operands are not the same, eg. rather than "r,0" "0,r" you can write "%r" "0". Wilco
On 9/18/19 7:19 PM, Wilco Dijkstra wrote: > Hi Kyrill, > >>> + (mult:SI (match_operand:SI 3 "s_register_operand" "r") >>> + (match_operand:SI 2 "s_register_operand" "r"))))] >> Looks like we'll want to mark operand 2 here with '%' as well? > That doesn't make any difference since both operands are identical. > It only helps if the operands are not the same, eg. rather than > "r,0" "0,r" you can write "%r" "0". Right, I remember that now. The patch is ok then. Thanks, Kyrill > > Wilco > > >
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 66dafdc47b7cfc37c131764e482d47bcaab90538..681358512e88f6823d1b6d59038f387daaec226e 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -1594,64 +1594,44 @@ (define_expand "mulsi3" "" ) -;; Use `&' and then `0' to prevent the operands 0 and 1 being the same -(define_insn "*arm_mulsi3" - [(set (match_operand:SI 0 "s_register_operand" "=&r,&r") - (mult:SI (match_operand:SI 2 "s_register_operand" "r,r") - (match_operand:SI 1 "s_register_operand" "%0,r")))] - "TARGET_32BIT && !arm_arch6" +;; Use `&' and then `0' to prevent operands 0 and 2 being the same +(define_insn "*mul" + [(set (match_operand:SI 0 "s_register_operand" "=l,r,&r,&r") + (mult:SI (match_operand:SI 2 "s_register_operand" "l,r,r,r") + (match_operand:SI 1 "s_register_operand" "%0,r,0,r")))] + "TARGET_32BIT" "mul%?\\t%0, %2, %1" [(set_attr "type" "mul") - (set_attr "predicable" "yes")] -) - -(define_insn "*arm_mulsi3_v6" - [(set (match_operand:SI 0 "s_register_operand" "=l,l,r") - (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r") - (match_operand:SI 2 "s_register_operand" "l,0,r")))] - "TARGET_32BIT && arm_arch6" - "mul%?\\t%0, %1, %2" - [(set_attr "type" "mul") (set_attr "predicable" "yes") - (set_attr "arch" "t2,t2,*") + (set_attr "arch" "t2,v6,nov6,nov6") (set_attr "length" "4") - (set_attr "predicable_short_it" "yes,yes,no")] + (set_attr "predicable_short_it" "yes,no,*,*")] ) -;; Unnamed templates to match MLA instruction. +;; MLA and MLS instruction. Use operand 1 for the accumulator to prefer +;; reusing the same register. -(define_insn "*mulsi3addsi" - [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r") +(define_insn "*mla" + [(set (match_operand:SI 0 "s_register_operand" "=r,&r,&r,&r") (plus:SI - (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r") - (match_operand:SI 1 "s_register_operand" "%0,r,0,r")) - (match_operand:SI 3 "s_register_operand" "r,r,0,0")))] - "TARGET_32BIT && !arm_arch6" - "mla%?\\t%0, %2, %1, %3" - [(set_attr "type" "mla") - (set_attr "predicable" "yes")] -) - -(define_insn "*mulsi3addsi_v6" - [(set (match_operand:SI 0 "s_register_operand" "=r") - (plus:SI - (mult:SI (match_operand:SI 2 "s_register_operand" "r") - (match_operand:SI 1 "s_register_operand" "r")) - (match_operand:SI 3 "s_register_operand" "r")))] - "TARGET_32BIT && arm_arch6" - "mla%?\\t%0, %2, %1, %3" + (mult:SI (match_operand:SI 3 "s_register_operand" "r,r,r,r") + (match_operand:SI 2 "s_register_operand" "%r,r,0,r")) + (match_operand:SI 1 "s_register_operand" "r,0,r,r")))] + "TARGET_32BIT" + "mla%?\\t%0, %3, %2, %1" [(set_attr "type" "mla") - (set_attr "predicable" "yes")] + (set_attr "predicable" "yes") + (set_attr "arch" "v6,nov6,nov6,nov6")] ) -(define_insn "*mulsi3subsi" +(define_insn "*mls" [(set (match_operand:SI 0 "s_register_operand" "=r") (minus:SI - (match_operand:SI 3 "s_register_operand" "r") - (mult:SI (match_operand:SI 2 "s_register_operand" "r") - (match_operand:SI 1 "s_register_operand" "r"))))] + (match_operand:SI 1 "s_register_operand" "r") + (mult:SI (match_operand:SI 3 "s_register_operand" "r") + (match_operand:SI 2 "s_register_operand" "r"))))] "TARGET_32BIT && arm_arch_thumb2" - "mls%?\\t%0, %2, %1, %3" + "mls%?\\t%0, %3, %2, %1" [(set_attr "type" "mla") (set_attr "predicable" "yes")] )