re PR middle-end/27663 (missed-optimization transforming a byte array to unsigned...
authorGeorg-Johann Lay <avr@gjlay.de>
Mon, 16 May 2011 14:20:19 +0000 (14:20 +0000)
committerGeorg-Johann Lay <gjl@gcc.gnu.org>
Mon, 16 May 2011 14:20:19 +0000 (14:20 +0000)
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

gcc/ChangeLog
gcc/config/avr/avr.md
gcc/config/avr/predicates.md

index b8af4fb3edecdaa325d663b976fc23c3029d61fb..8ba223fe60fcc708266dcef72b532a11cd89fecc 100644 (file)
@@ -1,3 +1,11 @@
+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
index 1ab30332bdb98ae18f29e7d461f2720f0ebfb2f4..efe6bb6914f647e5ed7ec5f2829d5485c938a53b 100644 (file)
        clr __zero_reg__"
   [(set_attr "length" "3")
    (set_attr "cc" "clobber")])
+
+\f
+;; 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);
+  })
index 9a3473bf88f549114ca8269bb551872e02eaee33..a7cc2ba052fa5e4a7113924bb1e38bd93160a10c 100755 (executable)
 (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)")))
+