Hi DJ,

  It turns out that the optimization in rl78_force_nonfar_3 to allow
  some special cases to be kept in far pointers does not always work.
  The test case included with this patch will trigger ICEs if the
  optimization is allowed to persist.

  So, may I check this patch in please ?

Cheers
  Nick

gcc/ChangeLog
2015-08-04  Nick Clifton  <ni...@redhat.com>

        * config/rl78/rl78.c (rl78_force_nonfar_3): Remove optimization
        to allow identical far pointers to remain.


gcc/testsuite/ChangeLog
2015-08-04  Nick Clifton  <ni...@redhat.com>

        * gcc.target/rl78: New directory.
        * gcc.target/rl78/rl78.exp: New file: Test driver.
        * gcc.target/rl78/test_addm3.c: New file: Test adds.

Index: gcc/config/rl78/rl78.c
===================================================================
--- gcc/config/rl78/rl78.c	(revision 226548)
+++ gcc/config/rl78/rl78.c	(working copy)
@@ -608,13 +608,6 @@
   int did = 0;
   rtx temp_reg = NULL;
 
-  /* As an exception, we allow two far operands if they're identical
-     and the third operand is not a MEM.  This allows global variables
-     to be incremented, for example.  */
-  if (rtx_equal_p (operands[0], operands[1])
-      && ! MEM_P (operands[2]))
-    return 0;
-
   /* FIXME: Likewise.  */
   if (rl78_far_p (operands[1]))
     {
--- /dev/null	2015-08-04 08:05:06.160754276 +0100
+++ gcc/testsuite/gcc.target/rl78/rl78.exp	2015-08-04 14:03:20.759389085 +0100
@@ -0,0 +1,43 @@
+# Copyright (C) 2015 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Exit immediately if this isn't the right target.
+if { ![istarget rl78-*-*] } then {
+  return
+}
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+    set DEFAULT_CFLAGS ""
+}
+
+# Initialize `dg'.
+dg-init
+
+# Find all tests
+set tests [lsort [find $srcdir/$subdir *.\[cS\]]]
+
+# Main loop.
+gcc-dg-runtest $tests "" $DEFAULT_CFLAGS
+
+# All done.
+dg-finish
--- /dev/null	2015-08-04 08:05:06.160754276 +0100
+++ gcc/testsuite/gcc.target/rl78/test_addm3.c	2015-08-04 15:12:53.509456677 +0100
@@ -0,0 +1,100 @@
+/* Remove `-ansi' from options to enable the use of __far and long long.  */
+/* { dg-options "" } */
+
+#define ADD(TYPE, name)			\
+  TYPE						\
+  add##name(TYPE a, TYPE b)			\
+  {						\
+    return a + b;				\
+  }						\
+  
+#define ADDIMM(TYPE, name)			\
+  TYPE						\
+  addimm##name(TYPE a)				\
+  {						\
+    return a + 50;				\
+  }						\
+
+#define ADDFAR(TYPE, name)			\
+  TYPE __far gf##name;				\
+  void						\
+  addfar##name(TYPE __far *pa, TYPE b)		\
+  {						\
+    gf##name += b;				\
+    *pa += 50;					\
+  }						\
+  
+
+ADD (char, qi3)
+ADD (int, hi3)
+ADD (long, si3)
+ADD (long long, di3)
+ADD (float, sf3)
+ADD (double, df3)
+
+ADDIMM (char, qi3)
+ADDIMM (int, hi3)
+ADDIMM (long, si3)
+ADDIMM (long long, di3)
+ADDIMM (float, sf3)
+ADDIMM (double, df3)
+
+ADDFAR (char, qi3)
+ADDFAR (int, hi3)
+ADDFAR (long, si3)
+ADDFAR (long long, di3)
+ADDFAR (float, sf3)
+ADDFAR (double, df3)
+
+char aqi1, aqi2;
+int ahi1, ahi2;
+long asi1, asi2;
+long long adi1, adi2;
+float af1, af2;
+double ad1, ad2;
+
+void
+testglobal (void)
+{
+  aqi1 += aqi2;
+  ahi1 += ahi2;
+  asi1 += asi2;
+  adi1 += adi2;
+  af1 += af2;
+  ad1 += ad2;
+}
+
+void
+testglobal2 (void)
+{
+  aqi1 += 10;
+  ahi1 += 11;
+  asi1 += 12;
+  adi1 += 13;
+  af1 += 2.0;
+  ad1 += 4.0;
+}
+
+void
+testptr (char *aqi1, int *ahi1, long *asi1, long long *adi1, float *af1, double *ad1, 
+	 char *aqi2, int *ahi2, long *asi2, long long *adi2, float *af2, double *ad2)
+{
+  *aqi1 += *aqi2;
+  *ahi1 += *ahi2;
+  *asi1 += *asi2;
+  *adi1 += *adi2;
+  *af1 += *af2;
+  *ad1 += *ad2;
+}
+
+void
+testptr2 (char *aqi1, int *ahi1, long *asi1, long long *adi1, float *af1, double *ad1)
+{
+  *aqi1 += 5;
+  *ahi1 += 10;
+  *asi1 += 11;
+  *adi1 += 12;
+  *af1 += 4.5;
+  *ad1 += 5.5;
+}
+

Reply via email to