diff mbox

[AVR] : Fix PR29560 (map 16-bit shift to 8-bit)

Message ID 4E2DA83B.3090002@gjlay.de
State New
Headers show

Commit Message

Georg-Johann Lay July 25, 2011, 5:30 p.m. UTC
This is an optimization for 8-bit shifts if the high part is unused.

Variable shift offset shifts are tedious on AVR because these devices
can just shift by 1.

If the high part of a shift is unused, the high part need not to be
computed, i.e. the 16-bit shift can be mapped to a 8-bit shift.

Most of such shifts come from implicit 8->16 bit (word_mode) conversions
when dealing with 8-bit variables as in the example code:

unsigned char shift1 (unsigned char x, unsigned char s)
{
    return x << s;
}

unsigned char y;

void shift2 (unsigned char x, unsigned char s)
{
    y = x << s;
}

Note that the result will still be correct for shift offsets
8..15, i.e. the result will be 0.

Ok to commit?

Johann


	PR target/29560
	* config/avr/avr.md: Add peephole2 to map ashlhi3 to ashlqi3 if
	high part of shift target is unused.

Comments

Richard Henderson July 25, 2011, 5:47 p.m. UTC | #1
On 07/25/2011 10:30 AM, Georg-Johann Lay wrote:
> 	PR target/29560
> 	* config/avr/avr.md: Add peephole2 to map ashlhi3 to ashlqi3 if
> 	high part of shift target is unused.

Ok.


r~
diff mbox

Patch

Index: config/avr/avr.md
===================================================================
--- config/avr/avr.md	(revision 176624)
+++ config/avr/avr.md	(working copy)
@@ -1993,6 +1993,29 @@  (define_insn "ashlhi3"
   [(set_attr "length" "6,0,2,2,4,10,10")
    (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
 
+
+;; High part of 16-bit shift is unused after the instruction:
+;; No need to compute it, map to 8-bit shift.
+
+(define_peephole2
+  [(set (match_operand:HI 0 "register_operand" "")
+        (ashift:HI (match_dup 0)
+                   (match_operand:QI 1 "register_operand" "")))]
+  ""
+  [(set (match_dup 2)
+        (ashift:QI (match_dup 2)
+                   (match_dup 1)))
+   (clobber (match_dup 3))]
+  {
+    operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
+
+    if (!peep2_reg_dead_p (1, operands[3]))
+      FAIL;
+
+    operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
+  })
+
+
 (define_insn "ashlsi3"
   [(set (match_operand:SI 0 "register_operand"           "=r,r,r,r,r,r,r")
 	(ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")