diff options
author | Georg-Johann Lay <avr@gjlay.de> | 2011-05-16 14:20:19 +0000 |
---|---|---|
committer | Georg-Johann Lay <gjl@gcc.gnu.org> | 2011-05-16 14:20:19 +0000 |
commit | 687027a4d55c087c933ef94868ff5450311e98ca (patch) | |
tree | c33cf38081412e0395b8d552fc0d917f941aa4d1 /gcc | |
parent | f24a5190c25a90ec8734ce62b68c081681a314fe (diff) | |
download | gcc-687027a4d55c087c933ef94868ff5450311e98ca.zip gcc-687027a4d55c087c933ef94868ff5450311e98ca.tar.gz gcc-687027a4d55c087c933ef94868ff5450311e98ca.tar.bz2 |
re PR middle-end/27663 (missed-optimization transforming a byte array to unsigned long)
PR target/27663
PR target/41076
* config/avr/predicates.md (const_8_16_24_operand): New predicate.
* config/avr/avr.md ("*ior<mode>qi.byte0",
"*ior<mode>qi.byte1-3"): New define_insn_and_split patterns.
From-SVN: r173792
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/avr/avr.md | 39 | ||||
-rwxr-xr-x | gcc/config/avr/predicates.md | 7 |
3 files changed, 54 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b8af4fb..8ba223f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 2011-05-16 Georg-Johann Lay <avr@gjlay.de> + PR target/27663 + PR target/41076 + * config/avr/predicates.md (const_8_16_24_operand): New predicate. + * config/avr/avr.md ("*ior<mode>qi.byte0", + "*ior<mode>qi.byte1-3"): New define_insn_and_split patterns. + +2011-05-16 Georg-Johann Lay <avr@gjlay.de> + PR target/45099 * config/avr/avr.c (avr_function_arg_advance): Error if a fixed register is needed for a function argument. diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index 1ab3033..efe6bb6 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -3388,3 +3388,42 @@ clr __zero_reg__" [(set_attr "length" "3") (set_attr "cc" "clobber")]) + + +;; Some combine patterns that try to fix bad code when a value is composed +;; from byte parts like in PR27663. +;; The patterns give some release but the code still is not optimal, +;; in particular when subreg lowering (-fsplit-wide-types) is turned on. +;; That switch obfuscates things here and in many other places. + +(define_insn_and_split "*ior<mode>qi.byte0" + [(set (match_operand:HISI 0 "register_operand" "=r") + (ior:HISI + (zero_extend:HISI (match_operand:QI 1 "register_operand" "r")) + (match_operand:HISI 2 "register_operand" "0")))] + "" + "#" + "reload_completed" + [(set (match_dup 3) + (ior:QI (match_dup 3) + (match_dup 1)))] + { + operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0); + }) + +(define_insn_and_split "*ior<mode>qi.byte1-3" + [(set (match_operand:HISI 0 "register_operand" "=r") + (ior:HISI + (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r")) + (match_operand:QI 2 "const_8_16_24_operand" "n")) + (match_operand:HISI 3 "register_operand" "0")))] + "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)" + "#" + "&& reload_completed" + [(set (match_dup 4) + (ior:QI (match_dup 4) + (match_dup 1)))] + { + int byteno = INTVAL(operands[2]) / BITS_PER_UNIT; + operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno); + }) diff --git a/gcc/config/avr/predicates.md b/gcc/config/avr/predicates.md index 9a3473b..a7cc2ba 100755 --- a/gcc/config/avr/predicates.md +++ b/gcc/config/avr/predicates.md @@ -138,3 +138,10 @@ (define_predicate "pseudo_register_operand" (and (match_code "reg") (match_test "!HARD_REGISTER_P (op)"))) + +;; Return true if OP is a constant integer that is either +;; 8 or 16 or 24. +(define_predicate "const_8_16_24_operand" + (and (match_code "const_int") + (match_test "8 == INTVAL(op) || 16 == INTVAL(op) || 24 == INTVAL(op)"))) + |