summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>2014-01-10 22:13:18 +0000
committerH.J. Lu <hjl.tools@gmail.com>2015-02-15 09:08:28 -0800
commit9420e5808e69b4ad6a30a0be0b278a2272935456 (patch)
tree5707d50cc010c2b763ec0baf7e7180cd797be413
parentf293e1d57fca34ad9896842b15f6f5ba5de180dd (diff)
downloadgcc-9420e5808e69b4ad6a30a0be0b278a2272935456.tar.gz
PR middle-end/59743
* ree.c (combine_reaching_defs): Ensure the defining statement occurs before the extension when optimizing extensions with different source and destination hard registers. PR middle-end/59743 * gcc.c-torture/compile/pr59743.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@206545 138bc75d-0d04-0410-961f-82ee72b054a4 Conflicts: gcc/ChangeLog gcc/testsuite/ChangeLog
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/ree.c6
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr59743.c23
4 files changed, 40 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 180e8cd1f7e..d74ba14466d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,6 +1,13 @@
2015-02-15 H.J. Lu <hongjiu.lu@intel.com>
Backport from mainline:
+ 2014-01-10 Jeff Law <law@redhat.com>
+
+ PR middle-end/59743
+ * ree.c (combine_reaching_defs): Ensure the defining statement
+ occurs before the extension when optimizing extensions with
+ different source and destination hard registers.
+
2014-01-08 Jeff Law <law@redhat.com>
* ree.c (get_sub_rtx): New function, extracted from...
diff --git a/gcc/ree.c b/gcc/ree.c
index d5bad37ff85..856d142aa15 100644
--- a/gcc/ree.c
+++ b/gcc/ree.c
@@ -758,8 +758,10 @@ combine_reaching_defs (ext_cand *cand, const_rtx set_pat, ext_state *state)
/* The defining statement and candidate insn must be in the same block.
This is merely to keep the test for safety and updating the insn
- stream simple. */
- if (BLOCK_FOR_INSN (cand->insn) != BLOCK_FOR_INSN (def_insn))
+ stream simple. Also ensure that within the block the candidate
+ follows the defining insn. */
+ if (BLOCK_FOR_INSN (cand->insn) != BLOCK_FOR_INSN (def_insn)
+ || DF_INSN_LUID (def_insn) > DF_INSN_LUID (cand->insn))
return false;
/* If there is an overlap between the destination of DEF_INSN and
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index eb7c5c9d3a1..5f83373f6e2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,6 +1,12 @@
2015-02-15 H.J. Lu <hongjiu.lu@intel.com>
Backport from mainline:
+ 2014-01-10 Jeff Law <law@redhat.com>
+
+ PR middle-end/59743
+ * gcc.c-torture/compile/pr59743.c: New test.
+
+ Backport from mainline:
2014-01-07 Jeff Law <law@redhat.com>
PR middle-end/53623
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr59743.c b/gcc/testsuite/gcc.c-torture/compile/pr59743.c
new file mode 100644
index 00000000000..8dadba594e5
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr59743.c
@@ -0,0 +1,23 @@
+/* PR middle-end/59743 */
+
+typedef union {
+ long all;
+ struct {
+ int low;
+ int high;
+ } s;
+} udwords;
+int a, b, c, d;
+void __udivmoddi4() {
+ udwords r;
+ d = __builtin_clz(0);
+ r.s.low = 0;
+ for (; d; --d) {
+ r.s.high = r.s.high << 1 | r.s.low >> a;
+ r.s.low = r.s.low << b >> 1;
+ int s = -r.all;
+ c = s;
+ r.all--;
+ }
+}
+