Add another testcase for PR middle-end/55116
authorhjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 30 Oct 2012 21:35:35 +0000 (21:35 +0000)
committerhjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 30 Oct 2012 21:35:35 +0000 (21:35 +0000)
* gcc.target/i386/pr55116-2.c: New file.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@192996 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr55116-2.c [new file with mode: 0644]

index 6573b8d..06f95f5 100644 (file)
@@ -1,3 +1,7 @@
+2012-10-30  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * gcc.target/i386/pr55116-2.c: New file.
+
 2012-10-30  Richard Biener  <rguenther@suse.de>
 
        * gcc.dg/vect/slp-perm-2.c: Adjust.
diff --git a/gcc/testsuite/gcc.target/i386/pr55116-2.c b/gcc/testsuite/gcc.target/i386/pr55116-2.c
new file mode 100644 (file)
index 0000000..7ef8ead
--- /dev/null
@@ -0,0 +1,86 @@
+/* { dg-do compile { target { ! { ia32 } } } } */
+/* { dg-options "-O2 -mx32 -maddress-mode=long" } */
+
+typedef struct rtx_def *rtx;
+enum rtx_code { MINUS };
+union rtunion_def {
+  rtx rt_rtx;
+};
+typedef union rtunion_def rtunion;
+struct rtx_def {
+  enum rtx_code code: 16;
+  union u {
+    rtunion fld[1];
+  }
+  u;
+};
+rtx simplify_binary_operation (enum rtx_code code, int mode,
+                              rtx op0, rtx op1);
+struct simplify_plus_minus_op_data {
+  rtx op;
+  short neg;
+};
+void simplify_plus_minus (enum rtx_code code, int mode, rtx op0, rtx op1)
+{
+  struct simplify_plus_minus_op_data ops[8];
+  rtx tem = (rtx) 0;
+  int n_ops = 2, input_ops = 2;
+  int changed, canonicalized = 0;
+  int i, j;
+  __builtin_memset (ops, 0, sizeof (ops));
+  do
+    {
+      changed = 0;
+      for (i = 0; i < n_ops; i++)
+       {
+         rtx this_op = ops[i].op;
+         int this_neg = ops[i].neg;
+         enum rtx_code this_code = ((enum rtx_code) (this_op)->code);
+         switch (this_code)
+           {
+           case MINUS:
+             if (n_ops == 7)
+               return;
+             n_ops++;
+             input_ops++;
+             changed = 1;
+             canonicalized |= this_neg; 
+             break;
+           }
+       }
+    }
+  while (changed);
+  do 
+    {
+      j =  n_ops - 1;
+      for (i = n_ops - 1; j >= 0; j--)
+       {
+         rtx lhs = ops[j].op, rhs = ops[i].op;
+         int lneg = ops[j].neg, rneg = ops[i].neg;
+         if (lhs != 0 && rhs != 0)
+           {
+             enum rtx_code ncode = MINUS;
+             if (((enum rtx_code) (lhs)->code) == MINUS)
+               tem = simplify_binary_operation (ncode, mode, lhs, rhs);
+             if (tem && ! (((enum rtx_code) (tem)->code) == MINUS 
+                           && ((((((tem)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx) == lhs
+                           && ((((((tem)->u.fld[0]).rt_rtx))->u.fld[1]).rt_rtx) == rhs))
+               {
+                 lneg &= rneg;
+                 ops[i].op = tem;
+                 ops[i].neg = lneg;
+                 ops[j].op = (rtx) 0;
+                 changed = 1;
+                 canonicalized = 1;
+               }
+           }
+       }
+      for (i = 0, j = 0; j < n_ops; j++)
+       if (ops[j].op)
+         {
+           ops[i] = ops[j];
+           i++;
+         }
+    }
+  while (changed);
+}