From c049b107223eb8f97c1049ab29b7bb2e293bbe9e Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 25 Feb 2016 09:09:02 +0100 Subject: [PATCH] re PR rtl-optimization/69896 (wrong code with -frename-registers @ x64_64) PR rtl-optimization/69896 * regcprop.c: Include cfgrtl.h. (copyprop_hardreg_forward_1): If noop_p insn uses narrower than remembered mode, either delete it (if noop_move_p), or treat like copy_p but not noop_p instruction. * gcc.dg/pr69896.c: New test. From-SVN: r233692 --- gcc/ChangeLog | 8 ++++++++ gcc/regcprop.c | 23 +++++++++++++++++++++-- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/pr69896.c | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr69896.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3cae3cbb8f37..4e360d57f468 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2016-02-25 Jakub Jelinek + + PR rtl-optimization/69896 + * regcprop.c: Include cfgrtl.h. + (copyprop_hardreg_forward_1): If noop_p insn uses narrower + than remembered mode, either delete it (if noop_move_p), or + treat like copy_p but not noop_p instruction. + 2016-02-24 Jakub Jelinek PR debug/69705 diff --git a/gcc/regcprop.c b/gcc/regcprop.c index 445b15962837..933cc8a8e07a 100644 --- a/gcc/regcprop.c +++ b/gcc/regcprop.c @@ -32,6 +32,7 @@ #include "addresses.h" #include "tree-pass.h" #include "rtl-iter.h" +#include "cfgrtl.h" /* The following code does forward propagation of hard register copies. The object is to eliminate as many dependencies as possible, so that @@ -739,9 +740,9 @@ static bool copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd) { bool anything_changed = false; - rtx_insn *insn; + rtx_insn *insn, *next; - for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn)) + for (insn = BB_HEAD (bb); ; insn = next) { int n_ops, i, predicated; bool is_asm, any_replacements; @@ -751,6 +752,7 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd) bool changed = false; struct kill_set_value_data ksvd; + next = NEXT_INSN (insn); if (!NONDEBUG_INSN_P (insn)) { if (DEBUG_INSN_P (insn)) @@ -1042,6 +1044,23 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd) bool noop_p = (copy_p && rtx_equal_p (SET_DEST (set), SET_SRC (set))); + /* If a noop move is using narrower mode than we have recorded, + we need to either remove the noop move, or kill_set_value. */ + if (noop_p + && (GET_MODE_BITSIZE (GET_MODE (SET_DEST (set))) + < GET_MODE_BITSIZE (vd->e[REGNO (SET_DEST (set))].mode))) + { + if (noop_move_p (insn)) + { + bool last = insn == BB_END (bb); + delete_insn (insn); + if (last) + break; + } + else + noop_p = false; + } + if (!noop_p) { /* Notice stores. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 55838071564f..7ce00d3b3135 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-02-25 Jakub Jelinek + + PR rtl-optimization/69896 + * gcc.dg/pr69896.c: New test. + 2016-02-25 Patrick Palka PR c++/69736 diff --git a/gcc/testsuite/gcc.dg/pr69896.c b/gcc/testsuite/gcc.dg/pr69896.c new file mode 100644 index 000000000000..af141adbf5e7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr69896.c @@ -0,0 +1,33 @@ +/* PR rtl-optimization/69896 */ +/* { dg-do run { target int128 } } */ +/* { dg-options "-w -O -fcaller-saves -fno-dse -frename-registers -fno-tree-ter" } */ +/* { dg-additional-options "-mno-sse" { target x86_64-*-* i?86-*-* } } */ + +typedef unsigned short A; +typedef unsigned short B __attribute__ ((vector_size (32))); +typedef unsigned int C; +typedef unsigned int D __attribute__ ((vector_size (32))); +typedef unsigned long long E; +typedef unsigned long long F __attribute__ ((vector_size (32))); +typedef unsigned __int128 G; +typedef unsigned __int128 H __attribute__ ((vector_size (32))); + +G __attribute__ ((noinline, noclone)) +foo (A a, C b, E c, G d, A e, C f, E g, G h, B i, D j, F k, H l, B m, D n, F o, H p) +{ + j /= (D) { -c, -c, ~h, 1, ~l[0], -m[0], p[0], 1} | 1; + l %= (H) o | 1; + l[1] = (l[1] << (e & 127)) | (l[1] >> (e & 127)); + return j[6] + l[0] + l[1] + n[7] + o[0] + o[2] + o[3] + p[0] + p[1]; +} + +int +main () +{ + if (__CHAR_BIT__ != 8 || sizeof (A) != 2 || sizeof (C) != 4 || sizeof (E) != 8 || sizeof (G) != 16) + return 0; + G x = foo (0, 1, 2, 3, 4, 5, 6, 7, (B) {}, (D) {}, (F) {}, (H) {}, (B) {}, (D) {}, (F) {}, (H) { 0xffffffffffffffffULL, 0x74a3e4aULL }); + if ((E) x != 0x00000000074a3e49ULL || (E) (x >> 64) != 1) + __builtin_abort (); + return 0; +}