Commit c049b107 by Jakub Jelinek Committed by Jakub Jelinek

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
parent 1137001c
2016-02-25 Jakub Jelinek <jakub@redhat.com>
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 <jakub@redhat.com> 2016-02-24 Jakub Jelinek <jakub@redhat.com>
PR debug/69705 PR debug/69705
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "addresses.h" #include "addresses.h"
#include "tree-pass.h" #include "tree-pass.h"
#include "rtl-iter.h" #include "rtl-iter.h"
#include "cfgrtl.h"
/* The following code does forward propagation of hard register copies. /* The following code does forward propagation of hard register copies.
The object is to eliminate as many dependencies as possible, so that The object is to eliminate as many dependencies as possible, so that
...@@ -739,9 +740,9 @@ static bool ...@@ -739,9 +740,9 @@ static bool
copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd) copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
{ {
bool anything_changed = false; 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; int n_ops, i, predicated;
bool is_asm, any_replacements; bool is_asm, any_replacements;
...@@ -751,6 +752,7 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd) ...@@ -751,6 +752,7 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
bool changed = false; bool changed = false;
struct kill_set_value_data ksvd; struct kill_set_value_data ksvd;
next = NEXT_INSN (insn);
if (!NONDEBUG_INSN_P (insn)) if (!NONDEBUG_INSN_P (insn))
{ {
if (DEBUG_INSN_P (insn)) if (DEBUG_INSN_P (insn))
...@@ -1042,6 +1044,23 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd) ...@@ -1042,6 +1044,23 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
bool noop_p = (copy_p bool noop_p = (copy_p
&& rtx_equal_p (SET_DEST (set), SET_SRC (set))); && 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) if (!noop_p)
{ {
/* Notice stores. */ /* Notice stores. */
......
2016-02-25 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/69896
* gcc.dg/pr69896.c: New test.
2016-02-25 Patrick Palka <ppalka@gcc.gnu.org> 2016-02-25 Patrick Palka <ppalka@gcc.gnu.org>
PR c++/69736 PR c++/69736
......
/* 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment