This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR optimization/4994


Hi!

The following testcase ICEs because reload is very unhappy it cannot move
a SImode value from one MMX reg to another one.
I don't see why it shouldn't be supported though.
Bootstrapped on i386-redhat-linux, no regressions.
Ok to commit?

2002-02-21  Jakub Jelinek  <jakub@redhat.com>

	PR optimization/4994
	* config/i386/i386.md (movsi_1, movsf_1): Support MMX -> MMX
	register moves.

	* g++.dg/opt/mmx1.C: New test.

--- gcc/config/i386/i386.md.jj	Tue Feb 19 11:13:34 2002
+++ gcc/config/i386/i386.md	Thu Feb 21 18:47:54 2002
@@ -1734,8 +1734,8 @@
    (set_attr "length_immediate" "1")])
 
 (define_insn "*movsi_1"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=*a,r,*a,m,!*y,!rm,!*Y,!rm,!*Y")
-	(match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,rm,*y,rm,*Y,*Y"))]
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=*a,r,*a,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
+	(match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,rm,*y,*y,rm,*Y,*Y"))]
   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
 {
   switch (get_attr_type (insn))
@@ -1746,6 +1746,8 @@
       return "movd\t{%1, %0|%0, %1}";
 
     case TYPE_MMX:
+      if (get_attr_mode (insn) == DImode)
+	return "movq\t{%1, %0|%0, %1}";
       return "movd\t{%1, %0|%0, %1}";
 
     case TYPE_LEA:
@@ -1758,17 +1760,17 @@
     }
 }
   [(set (attr "type")
-     (cond [(eq_attr "alternative" "4,5")
+     (cond [(eq_attr "alternative" "4,5,6")
 	      (const_string "mmx")
-	    (eq_attr "alternative" "6,7,8")
+	    (eq_attr "alternative" "7,8,9")
 	      (const_string "sse")
 	    (and (ne (symbol_ref "flag_pic") (const_int 0))
 		 (match_operand:SI 1 "symbolic_operand" ""))
 	      (const_string "lea")
 	   ]
 	   (const_string "imov")))
-   (set_attr "modrm" "0,*,0,*,*,*,*,*,*")
-   (set_attr "mode" "SI,SI,SI,SI,SI,SI,TI,SI,SI")])
+   (set_attr "modrm" "0,*,0,*,*,*,*,*,*,*")
+   (set_attr "mode" "SI,SI,SI,SI,SI,SI,DI,TI,SI,SI")])
 
 ;; Stores and loads of ax to arbitary constant address.
 ;; We fake an second form of instruction to force reload to load address
@@ -2713,8 +2715,8 @@
    (set (mem:SF (reg:DI 7)) (match_dup 1))])
 
 (define_insn "*movsf_1"
-  [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!rm")
-	(match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,H,x,xm#rf,x#rf,rm,*y"))]
+  [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!rm,!*y")
+	(match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,H,x,xm#rf,x#rf,rm,*y,*y"))]
   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
    && (reload_in_progress || reload_completed
        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
@@ -2766,12 +2768,15 @@
     case 10:
       return "movd\t{%1, %0|%0, %1}";
 
+    case 11:
+      return "movq\t{%1, %0|%0, %1}";
+
     default:
       abort();
     }
 }
-  [(set_attr "type" "fmov,fmov,fmov,imov,imov,sse,sse,sse,sse,mmx,mmx")
-   (set_attr "mode" "SF,SF,SF,SI,SI,TI,SF,SF,SF,SI,SI")])
+  [(set_attr "type" "fmov,fmov,fmov,imov,imov,sse,sse,sse,sse,mmx,mmx,mmx")
+   (set_attr "mode" "SF,SF,SF,SI,SI,TI,SF,SF,SF,SI,SI,DI")])
 
 (define_insn "*swapsf"
   [(set (match_operand:SF 0 "register_operand" "+f")
--- gcc/testsuite/g++.dg/opt/mmx1.C.jj	Thu Feb 21 18:59:26 2002
+++ gcc/testsuite/g++.dg/opt/mmx1.C	Thu Feb 21 18:59:08 2002
@@ -0,0 +1,65 @@
+// PR optimization/4994
+// This testcase ICEd because there movsi was not supporting direct
+// mmx -> mmx register moves.
+// { dg-do compile }
+// { dg-options "-O2" }
+// { dg-options "-fno-exceptions -O2 -mmmx -fPIC" { target i?86-*-*  } }
+
+struct A {
+  unsigned a0;
+  bool a1 () { return !--a0; }
+  void a2 ();
+};
+
+struct B
+{
+  B ();
+  B (const B &);
+  ~B();
+  B &operator= (const B &);
+  B b0 (unsigned long x, int y = 0, int z = 10) const;
+
+private:
+  A *b1;
+  static A *b2;
+};
+
+inline B::~B()
+{
+  if (b1->a1 () && b1 == b2)
+    b1->a2();
+}
+
+struct C
+{
+  C *c0;
+};
+
+struct D
+{
+  C *d0;
+  D ();
+  D (const D &c0) {}
+  D &operator++ () {
+    C *x = d0; C *y = x->c0;
+    while (x == y->c0)
+      x = y;
+    d0 = x;
+    return *this;
+  }
+};
+
+B foo (const char *x, const B &y);
+
+void bar (void)
+{
+  B *y = 0;
+  B z;
+  for (unsigned long l = 0; l < 2147483647L * 2UL + 1; l++)
+    {
+      z = y->b0 (l);
+      *y = foo ("data", z);
+    }
+  D d;
+  ++d;
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]