Patchwork [AVR] Fix PR49881

login
register
mail settings
Submitter Richard Henderson
Date Aug. 1, 2011, 6:59 p.m.
Message ID <4E36F79A.2060108@redhat.com>
Download mbox | patch
Permalink /patch/107791/
State New
Headers show

Comments

Richard Henderson - Aug. 1, 2011, 6:59 p.m.
Dang, forgot to add gcc-patches...

-------- Original Message --------
Subject: [AVR] Fix PR49881
Date: Mon, 01 Aug 2011 11:58:32 -0700
From: Richard Henderson <rth@redhat.com>
To: Denis Chertykov <chertykov@gmail.com>, eric.weddington@atmel.com
CC: avr@gjlay.de

The following iteration fixes the two regressions reported
in comment 7 of the PR.

These were ICEs due to emit_push_insn_single being "helpful"
with pushing complex numbers.  Instead of recursing for the
components of a complex number, it simply generated raw
pre_dec patterns.  This is arguably a middle-end bug, but 
it's easier to fix in the backend by listing complex modes
in the macro for the push expander.

Ok?


r~
* config/avr/avr.h (PUSH_ROUNDING): New.
	* config/avr/avr.md (pushqi1): Rename from *pushqi.
	(*pushhi, *pushsi, *pushsf): Remove.
	(MPUSH): New mode iterator.
	(push<MPUSH>1): New expander.
Georg-Johann Lay - Aug. 2, 2011, 7:52 a.m.
Richard Henderson wrote:
> Dang, forgot to add gcc-patches...
> 
> -------- Original Message --------
> Subject: [AVR] Fix PR49881
> 
> The following iteration fixes the two regressions reported
> in comment 7 of the PR.
> 
> These were ICEs due to emit_push_insn_single being "helpful"
> with pushing complex numbers.  Instead of recursing for the
> components of a complex number, it simply generated raw
> pre_dec patterns.  This is arguably a middle-end bug, but 
> it's easier to fix in the backend by listing complex modes
> in the macro for the push expander.
> 
> Ok?
> 
> 
> r~

After updating to r177084 (your patch is r177071) I still get *many*
test fails or untested (programs hangs?) fails.

Just few examples:

PASS: gcc.c-torture/execute/920726-1.c compilation,  -O1
FAIL: gcc.c-torture/execute/920726-1.c execution,  -O1

PASS: gcc.c-torture/execute/930513-1.c compilation,  -Os
UNTESTED: gcc.c-torture/execute/930513-1.c execution,  -Os

FAIL: gcc.c-torture/execute/920726-1.c execution,  -O0
FAIL: gcc.c-torture/execute/920726-1.c execution,  -O1
FAIL: gcc.c-torture/execute/920726-1.c execution,  -O2
FAIL: gcc.c-torture/execute/920726-1.c execution,  -O3 -fomit-frame-pointer
FAIL: gcc.c-torture/execute/920726-1.c execution,  -O3 -fomit-frame-pointer -funroll-loops
FAIL: gcc.c-torture/execute/920726-1.c execution,  -O3 -fomit-frame-pointer -funroll-all-loops
-finline-functions
FAIL: gcc.c-torture/execute/920726-1.c execution,  -O3 -g

There are still unrecognizables:

gcc.c-torture/execute/complex-7.c:56:1: error: unrecognizable insn:
(insn 17 14 18 3 (set (mem:SF (post_dec:HI (reg/f:HI 32 __SP_L__)) [0 S4 A8])
        (reg:SF 43 [ f5.0+4 ]))
/mnt/nfs/home/georg/gnu/gcc.gnu.org/trunk/gcc/testsuite/gcc.c-torture/execute/complex-7.c:52 -1
     (nil))

FAIL: gcc.c-torture/execute/complex-7.c compilation,  -O0

Is it possible that you run avr regressions?

Johann

Patch

diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h
index ddd30d6..6a80693 100644
--- a/gcc/config/avr/avr.h
+++ b/gcc/config/avr/avr.h
@@ -665,3 +665,7 @@  struct GTY(()) machine_function
   /* 'true' if a callee might be tail called */
   int sibcall_fails;
 };
+
+/* AVR does not round pushes, but the existance of this macro is
+   required in order for pushes to be generated.  */
+#define PUSH_ROUNDING(X)	(X)
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index 55a883e..f60f9f0 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -202,8 +202,7 @@ 
   DONE;
 })
 
-
-(define_insn "*pushqi"
+(define_insn "pushqi1"
   [(set (mem:QI (post_dec:HI (reg:HI REG_SP)))
         (match_operand:QI 0 "reg_or_0_operand" "r,L"))]
   ""
@@ -212,33 +211,29 @@ 
 	push __zero_reg__"
   [(set_attr "length" "1,1")])
 
-(define_insn "*pushhi"
-  [(set (mem:HI (post_dec:HI (reg:HI REG_SP)))
-        (match_operand:HI 0 "reg_or_0_operand" "r,L"))]
-  ""
-  "@
-	push %B0\;push %A0
-	push __zero_reg__\;push __zero_reg__"
-  [(set_attr "length" "2,2")])
+;; All modes for a multi-byte push.  We must include complex modes here too,
+;; lest emit_single_push_insn "helpfully " create the auto-inc itself.
+(define_mode_iterator MPUSH
+  [(CQI "")
+   (HI "") (CHI "")
+   (SI "") (CSI "")
+   (DI "") (CDI "")
+   (SF "") (SC "")])
 
-(define_insn "*pushsi"
-  [(set (mem:SI (post_dec:HI (reg:HI REG_SP)))
-        (match_operand:SI 0 "reg_or_0_operand" "r,L"))]
+(define_expand "push<mode>1"
+  [(match_operand:MPUSH 0 "general_operand" "")]
   ""
-  "@
-	push %D0\;push %C0\;push %B0\;push %A0
-	push __zero_reg__\;push __zero_reg__\;push __zero_reg__\;push __zero_reg__"
-  [(set_attr "length" "4,4")])
-
-(define_insn "*pushsf"
-  [(set (mem:SF (post_dec:HI (reg:HI REG_SP)))
-        (match_operand:SF 0 "register_operand" "r"))]
-  ""
-  "push %D0
-	push %C0
-	push %B0
-	push %A0"
-  [(set_attr "length" "4")])
+{
+  int i;
+  for (i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
+    {
+      rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
+      if (part != const0_rtx)
+	part = force_reg (QImode, part);
+      emit_insn (gen_pushqi1 (part));
+    }
+  DONE;
+})
 
 ;;========================================================================
 ;; move byte