re PR target/49687 ([avr] Missed optimization for widening MUL)

PR target/49687
	* config/avr/avr.md (smulqi3_highpart): New insn.
	(umulqi3_highpart): New insn.
	(*subqi3.ashiftrt7): New insn.
	(smulhi3_highpart): New expander.
	(umulhi3_highpart): Nex expander.
	(*smulhi3_highpart_call): New insn.
	(*umulhi3_highpart_call): New insn.
	(extend_u): New code attribute.
	(extend_prefix): Rename code attribute to extend_su.
	* config/avr/avr.c (avr_rtx_costs): Report costs of highpart of
	widening QI/HI multiply.

From-SVN: r177648
This commit is contained in:
Georg-Johann Lay 2011-08-11 07:50:37 +00:00 committed by Georg-Johann Lay
parent fb2c2b1672
commit 7ece388150
3 changed files with 118 additions and 42 deletions

View file

@ -1,3 +1,18 @@
2011-08-11 Georg-Johann Lay <avr@gjlay.de>
PR target/49687
* config/avr/avr.md (smulqi3_highpart): New insn.
(umulqi3_highpart): New insn.
(*subqi3.ashiftrt7): New insn.
(smulhi3_highpart): New expander.
(umulhi3_highpart): Nex expander.
(*smulhi3_highpart_call): New insn.
(*umulhi3_highpart_call): New insn.
(extend_u): New code attribute.
(extend_prefix): Rename code attribute to extend_su.
* config/avr/avr.c (avr_rtx_costs): Report costs of highpart of
widening QI/HI multiply.
2011-08-11 Ira Rosen <ira.rosen@linaro.org>
PR tree-optimization/50039

View file

@ -5954,6 +5954,20 @@ avr_rtx_costs (rtx x, int codearg, int outer_code ATTRIBUTE_UNUSED, int *total,
*total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
return true;
case TRUNCATE:
if (AVR_HAVE_MUL
&& LSHIFTRT == GET_CODE (XEXP (x, 0))
&& MULT == GET_CODE (XEXP (XEXP (x, 0), 0))
&& CONST_INT_P (XEXP (XEXP (x, 0), 1)))
{
if (QImode == mode || HImode == mode)
{
*total = COSTS_N_INSNS (2);
return true;
}
}
break;
default:
break;
}

View file

@ -141,10 +141,14 @@
(define_code_iterator any_extend2 [sign_extend zero_extend])
;; Define code attributes
(define_code_attr extend_prefix
(define_code_attr extend_su
[(sign_extend "s")
(zero_extend "u")])
(define_code_attr extend_u
[(sign_extend "")
(zero_extend "u")])
;;========================================================================
;; The following is used by nonlocal_goto and setjmp.
@ -1015,6 +1019,43 @@
[(set_attr "type" "xcall")
(set_attr "cc" "clobber")])
(define_insn "smulqi3_highpart"
[(set (match_operand:QI 0 "register_operand" "=r")
(truncate:QI
(lshiftrt:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
(sign_extend:HI (match_operand:QI 2 "register_operand" "d")))
(const_int 8))))]
"AVR_HAVE_MUL"
"muls %1,%2
mov %0,r1
clr __zero_reg__"
[(set_attr "length" "3")
(set_attr "cc" "clobber")])
(define_insn "umulqi3_highpart"
[(set (match_operand:QI 0 "register_operand" "=r")
(truncate:QI
(lshiftrt:HI (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
(zero_extend:HI (match_operand:QI 2 "register_operand" "r")))
(const_int 8))))]
"AVR_HAVE_MUL"
"mul %1,%2
mov %0,r1
clr __zero_reg__"
[(set_attr "length" "3")
(set_attr "cc" "clobber")])
;; Used when expanding div or mod inline for some special values
(define_insn "*subqi3.ashiftrt7"
[(set (match_operand:QI 0 "register_operand" "=r")
(minus:QI (match_operand:QI 1 "register_operand" "0")
(ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
(const_int 7))))]
""
"sbrc %2,7\;inc %0"
[(set_attr "length" "2")
(set_attr "cc" "clobber")])
(define_insn "mulqihi3"
[(set (match_operand:HI 0 "register_operand" "=r")
(mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
@ -1367,9 +1408,7 @@
[(set_attr "type" "xcall")
(set_attr "cc" "clobber")])
;; Operand 2 (reg:SI 18) not clobbered on the enhanced core.
;; All call-used registers clobbered otherwise - normal library call.
;; To support widening multiplicatioon with constant we postpone
;; To support widening multiplicatioon with constant we postpone
;; expanding to the implicit library call until post combine and
;; prior to register allocation. Clobber all hard registers that
;; might be used by the (widening) multiply until it is split and
@ -1535,19 +1574,12 @@
(reg:SI 22))]
"")
(define_expand "mulhisi3"
;; "mulhisi3"
;; "umulhisi3"
(define_expand "<extend_u>mulhisi3"
[(parallel [(set (match_operand:SI 0 "register_operand" "")
(mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
(sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
(clobber (reg:HI 26))
(clobber (reg:DI 18))])]
"AVR_HAVE_MUL"
"")
(define_expand "umulhisi3"
[(parallel [(set (match_operand:SI 0 "register_operand" "")
(mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
(zero_extend:SI (match_operand:HI 2 "register_operand" ""))))
(mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" ""))
(any_extend:SI (match_operand:HI 2 "register_operand" ""))))
(clobber (reg:HI 26))
(clobber (reg:DI 18))])]
"AVR_HAVE_MUL"
@ -1567,7 +1599,7 @@
;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
(define_insn_and_split
"*<any_extend:extend_prefix><any_extend2:extend_prefix>mul<QIHI:mode><QIHI2:mode>si3"
"*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3"
[(set (match_operand:SI 0 "pseudo_register_operand" "=r")
(mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
(any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
@ -1618,6 +1650,24 @@
}
})
;; "smulhi3_highpart"
;; "umulhi3_highpart"
(define_expand "<extend_su>mulhi3_highpart"
[(set (reg:HI 18)
(match_operand:HI 1 "nonmemory_operand" ""))
(set (reg:HI 26)
(match_operand:HI 2 "nonmemory_operand" ""))
(parallel [(set (reg:HI 24)
(truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
(any_extend:SI (reg:HI 26)))
(const_int 16))))
(clobber (reg:HI 22))])
(set (match_operand:HI 0 "register_operand" "")
(reg:HI 24))]
"AVR_HAVE_MUL"
"")
(define_insn "*mulsi3_call"
[(set (reg:SI 22)
(mult:SI (reg:SI 22)
@ -1628,21 +1678,27 @@
[(set_attr "type" "xcall")
(set_attr "cc" "clobber")])
(define_insn "*mulhisi3_call"
;; "*mulhisi3_call"
;; "*umulhisi3_call"
(define_insn "*<extend_u>mulhisi3_call"
[(set (reg:SI 22)
(mult:SI (sign_extend:SI (reg:HI 18))
(sign_extend:SI (reg:HI 26))))]
(mult:SI (any_extend:SI (reg:HI 18))
(any_extend:SI (reg:HI 26))))]
"AVR_HAVE_MUL"
"%~call __mulhisi3"
"%~call __<extend_u>mulhisi3"
[(set_attr "type" "xcall")
(set_attr "cc" "clobber")])
(define_insn "*umulhisi3_call"
[(set (reg:SI 22)
(mult:SI (zero_extend:SI (reg:HI 18))
(zero_extend:SI (reg:HI 26))))]
;; "*umulhi3_highpart_call"
;; "*smulhi3_highpart_call"
(define_insn "*<extend_su>mulhi3_highpart_call"
[(set (reg:HI 24)
(truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
(any_extend:SI (reg:HI 26)))
(const_int 16))))
(clobber (reg:HI 22))]
"AVR_HAVE_MUL"
"%~call __umulhisi3"
"%~call __<extend_u>mulhisi3"
[(set_attr "type" "xcall")
(set_attr "cc" "clobber")])
@ -1655,21 +1711,12 @@
[(set_attr "type" "xcall")
(set_attr "cc" "clobber")])
(define_insn "*muluhisi3_call"
(define_insn "*mul<extend_su>hisi3_call"
[(set (reg:SI 22)
(mult:SI (zero_extend:SI (reg:HI 26))
(mult:SI (any_extend:SI (reg:HI 26))
(reg:SI 18)))]
"AVR_HAVE_MUL"
"%~call __muluhisi3"
[(set_attr "type" "xcall")
(set_attr "cc" "clobber")])
(define_insn "*mulshisi3_call"
[(set (reg:SI 22)
(mult:SI (sign_extend:SI (reg:HI 26))
(reg:SI 18)))]
"AVR_HAVE_MUL"
"%~call __mulshisi3"
"%~call __mul<extend_su>hisi3"
[(set_attr "type" "xcall")
(set_attr "cc" "clobber")])
@ -2269,7 +2316,7 @@
;; "*ashluqihiqi3"
;; "*ashlsqihiqi3"
(define_insn_and_split "*ashl<extend_prefix>qihiqi3"
(define_insn_and_split "*ashl<extend_su>qihiqi3"
[(set (match_operand:QI 0 "register_operand" "=r")
(subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
(match_operand:QI 2 "register_operand" "r"))
@ -2287,7 +2334,7 @@
;; "*ashluqihiqi3.mem"
;; "*ashlsqihiqi3.mem"
(define_insn_and_split "*ashl<extend_prefix>qihiqi3.mem"
(define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
[(set (match_operand:QI 0 "memory_operand" "=m")
(subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
(match_operand:QI 2 "register_operand" "r"))
@ -2301,7 +2348,7 @@
(set (match_dup 0)
(match_dup 3))]
{
operands[3] = force_reg (QImode, operands[0]);
operands[3] = gen_reg_rtx (QImode);
})
;; Similar.
@ -2320,7 +2367,7 @@
(match_dup 4))]
{
operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
operands[4] = force_reg (QImode, operands[0]);
operands[4] = gen_reg_rtx (QImode);
})
;; High part of 16-bit shift is unused after the instruction: