aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>2016-03-18 19:09:08 +0000
committerbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>2016-03-18 19:09:08 +0000
commite7142ce1fb81c48623bef1c30ef3fe222c89b25f (patch)
tree56844518935399d010918f8fc3def7ad42f8012f
parent5539bc70a31b6694a83c6b6a5dc528fae73378f9 (diff)
Fix PR70278, a problem with the previous split_reg change
PR rtl-optimization/70278 * lra-constraints.c (split_reg): Handle the case where biggest_mode is VOIDmode. testsuite/ * gcc.dg/torture/pr70278.c: New test. * gcc.target/arm/pr70278.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@234342 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/lra-constraints.c7
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr70278.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/pr70278.c41
5 files changed, 96 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d988be26d67..328fde839dd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2016-03-18 Bernd Schmidt <bschmidt@redhat.com>
+
+ PR rtl-optimization/70278
+ * lra-constraints.c (split_reg): Handle the case where biggest_mode is
+ VOIDmode.
+
2016-03-18 Jason Merrill <jason@redhat.com>
* calls.c (load_register_parameters): Fix zero size sibcall logic.
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index ced9e12b0f1..4883eefc532 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -4982,7 +4982,12 @@ split_reg (bool before_p, int original_regno, rtx_insn *insn,
nregs = 1;
mode = lra_reg_info[hard_regno].biggest_mode;
machine_mode reg_rtx_mode = GET_MODE (regno_reg_rtx[hard_regno]);
- if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (reg_rtx_mode))
+ /* A reg can have a biggest_mode of VOIDmode if it was only ever seen
+ as part of a multi-word register. In that case, or if the biggest
+ mode was larger than a register, just use the reg_rtx. Otherwise,
+ limit the size to that of the biggest access in the function. */
+ if (mode == VOIDmode
+ || GET_MODE_SIZE (mode) > GET_MODE_SIZE (reg_rtx_mode))
{
original_reg = regno_reg_rtx[hard_regno];
mode = reg_rtx_mode;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c3ceedbd88e..53994fe63ec 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2016-03-18 Bernd Schmidt <bschmidt@redhat.com>
+
+ PR rtl-optimization/70278
+ * gcc.dg/torture/pr70278.c: New test.
+ * gcc.target/arm/pr70278.c: New test.
+
2016-03-18 David Malcolm <dmalcolm@redhat.com>
PR c/70281
diff --git a/gcc/testsuite/gcc.dg/torture/pr70278.c b/gcc/testsuite/gcc.dg/torture/pr70278.c
new file mode 100644
index 00000000000..89bd2660c1f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr70278.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+typedef union
+{
+ double value;
+ struct
+ {
+ unsigned int msw;
+ } parts;
+} ieee_double_shape_type;
+double __ieee754_hypot(double x, double y)
+{
+ double a=x,b=y,t1,t2,y1,y2,w;
+ int j,k,ha,hb;
+ do { ieee_double_shape_type gh_u; gh_u.value = (x); (ha) = gh_u.parts.msw; } while (0);;
+ if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
+ if(ha > 0x5f300000) {
+ do { ieee_double_shape_type sh_u; sh_u.value = (a); sh_u.parts.msw = (ha); (a) = sh_u.value; } while (0);;
+ }
+ w = a-b;
+ if (w <= b)
+ {
+ t2 = a - t1;
+ w = t1*y1-(w*(-w)-(t1*y2+t2*b));
+ }
+ if(k!=0) {
+ } else return w;
+}
diff --git a/gcc/testsuite/gcc.target/arm/pr70278.c b/gcc/testsuite/gcc.target/arm/pr70278.c
new file mode 100644
index 00000000000..c44c07b7b59
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr70278.c
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-march=*" } { "-march=armv4t" } } */
+/* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-marm" } { "" } } */
+/* { dg-options "-mthumb" } */
+/* { dg-add-options arm_arch_v4t } */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+typedef union
+{
+ double value;
+ struct
+ {
+ unsigned int msw;
+ } parts;
+} ieee_double_shape_type;
+double __ieee754_hypot(double x, double y)
+{
+ double a=x,b=y,t1,t2,y1,y2,w;
+ int j,k,ha,hb;
+ do { ieee_double_shape_type gh_u; gh_u.value = (x); (ha) = gh_u.parts.msw; } while (0);;
+ if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
+ if(ha > 0x5f300000) {
+ do { ieee_double_shape_type sh_u; sh_u.value = (a); sh_u.parts.msw = (ha); (a) = sh_u.value; } while (0);;
+ }
+ w = a-b;
+ if (w <= b)
+ {
+ t2 = a - t1;
+ w = t1*y1-(w*(-w)-(t1*y2+t2*b));
+ }
+ if(k!=0) {
+ } else return w;
+}