From ff2ca1bca53a12df4877a93f441e4d032306ef20 Mon Sep 17 00:00:00 2001 From: Hans-Peter Nilsson Date: Sun, 29 Apr 2012 06:59:09 +0000 Subject: re PR target/53156 (gcc.target/cris/peep2-andu2.c) PR target/53156 * config/cris/cris.md (andqu): New peephole2. (andu): Tweak head comment. From-SVN: r186940 --- gcc/ChangeLog | 6 ++++++ gcc/config/cris/cris.md | 48 +++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 45 insertions(+), 9 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 713c23f..5c0e973 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-04-29 Hans-Peter Nilsson + + PR target/53156 + * config/cris/cris.md (andqu): New peephole2. + (andu): Tweak head comment. + 2012-04-28 Joern Rennecke Steven Bosscher Maxim Kuvyrkov diff --git a/gcc/config/cris/cris.md b/gcc/config/cris/cris.md index febe6f5..92657d1 100644 --- a/gcc/config/cris/cris.md +++ b/gcc/config/cris/cris.md @@ -4936,17 +4936,17 @@ "operands[7] = rtx_equal_p (operands[3], operands[0]) ? operands[4] : operands[3];") -;; I cannot tell GCC (2.1, 2.7.2) how to correctly reload an instruction -;; that looks like -;; and.b some_byte,const,reg_32 -;; where reg_32 is the destination of the "three-address" code optimally. +;; There seems to be no other way to make GCC (including 4.8/trunk at +;; r186932) optimally reload an instruction that looks like +;; and.d reg_or_mem,const_32__65535,other_reg +;; where other_reg is the destination. ;; It should be: -;; movu.b some_byte,reg_32 -;; and.b const,reg_32 +;; movu.[bw] reg_or_mem,reg_32 +;; and.[bw] trunc_int_for_mode([bw], const_32__65535),reg_32 ;; or andq ;; but it turns into: -;; move.b some_byte,reg_32 -;; and.d const,reg_32 -;; Fix it here. +;; move.d reg_or_mem,reg_32 +;; and.d const_32__65535,reg_32 +;; Fix it with these two peephole2's. ;; Testcases: gcc.dg/cris-peep2-andu1.c gcc.dg/cris-peep2-andu2.c (define_peephole2 ; andu (casesi+45) @@ -4984,6 +4984,36 @@ ? QImode : amode))); }) +;; Since r186861, gcc.dg/cris-peep2-andu2.c trigs this pattern, with which +;; we fix up e.g.: +;; movu.b 254,$r9. +;; and.d $r10,$r9 +;; into: +;; movu.b $r10,$r9 +;; andq -2,$r9. +;; Only do this for values fitting the quick immediate operand. +(define_peephole2 ; andqu (casesi+46) + [(set (match_operand:SI 0 "register_operand") + (match_operand:SI 1 "const_int_operand")) + (set (match_dup 0) + (and:SI (match_dup 0) (match_operand:SI 2 "nonimmediate_operand")))] + ;; Since the size of the memory access will be made different here, + ;; don't do this for a volatile access or a post-incremented address. + "satisfies_constraint_O (operands[1]) + && !side_effects_p (operands[2]) + && !reg_overlap_mentioned_p (operands[0], operands[2])" + [(set (match_dup 0) (match_dup 3)) + (set (match_dup 0) (and:SI (match_dup 0) (match_dup 4)))] +{ + enum machine_mode zmode = INTVAL (operands[2]) <= 255 ? QImode : HImode; + rtx op1 + = (REG_S_P (operands[2]) + ? gen_rtx_REG (zmode, REGNO (operands[2])) + : adjust_address (operands[2], zmode, 0)); + operands[3] = gen_rtx_ZERO_EXTEND (SImode, op1); + operands[4] = GEN_INT (trunc_int_for_mode (INTVAL (operands[1]), QImode)); +}) + ;; Try and avoid GOTPLT reads escaping a call: transform them into ;; PLT. Curiously (but thankfully), peepholes for instructions ;; *without side-effects* that just feed a call (or call_value) are -- cgit v1.1