From: Georg-Johann Lay Date: Thu, 11 Aug 2011 07:50:37 +0000 (+0000) Subject: re PR target/49687 ([avr] Missed optimization for widening MUL) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7ece388150bbbfb0c946b28efa43ad1eeb2f0bf8;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f85d349b8e1..0220752fed5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2011-08-11 Georg-Johann Lay + + 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 PR tree-optimization/50039 diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index d9ed2248947..76542a87dc0 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -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; } diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index 8293ba7558e..356b5095438 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -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 "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 - "*mulsi3" + "*mulsi3" [(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 "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 "*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 __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 "*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 __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" - [(set (reg:SI 22) - (mult:SI (zero_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" +(define_insn "*mulhisi3_call" [(set (reg:SI 22) - (mult:SI (sign_extend:SI (reg:HI 26)) + (mult:SI (any_extend:SI (reg:HI 26)) (reg:SI 18)))] "AVR_HAVE_MUL" - "%~call __mulshisi3" + "%~call __mulhisi3" [(set_attr "type" "xcall") (set_attr "cc" "clobber")]) @@ -2269,7 +2316,7 @@ ;; "*ashluqihiqi3" ;; "*ashlsqihiqi3" -(define_insn_and_split "*ashlqihiqi3" +(define_insn_and_split "*ashlqihiqi3" [(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 "*ashlqihiqi3.mem" +(define_insn_and_split "*ashlqihiqi3.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: