Commit cefe08a4 by Vladimir Makarov Committed by Vladimir Makarov

re PR target/69614 (wrong code with -Os -fno-expensive-optimizations…

re PR target/69614 (wrong code with -Os -fno-expensive-optimizations -fschedule-insns -mtpcs-leaf-frame -fira-algorithm=priority @ armv7a)

2016-03-12  Vladimir Makarov  <vmakarov@redhat.com>

	PR target/69614
	* lra-constraints.c (delete_move_and_clobber): New.
	(remove_inheritance_pseudos): Use it.

2016-03-12  Vladimir Makarov  <vmakarov@redhat.com>

	PR target/69614
	* gcc.target/arm/pr69614.c: New.

From-SVN: r234162
parent 70112e2a
2016-03-12 Vladimir Makarov <vmakarov@redhat.com>
PR target/69614
* lra-constraints.c (delete_move_and_clobber): New.
(remove_inheritance_pseudos): Use it.
2016-03-12 Eric Botcazou <ebotcazou@adacore.com> 2016-03-12 Eric Botcazou <ebotcazou@adacore.com>
PR ada/70017 PR ada/70017
......
...@@ -5850,6 +5850,24 @@ get_regno (rtx reg) ...@@ -5850,6 +5850,24 @@ get_regno (rtx reg)
return -1; return -1;
} }
/* Delete a move INSN with destination reg DREGNO and a previous
clobber insn with the same regno. The inheritance/split code can
generate moves with preceding clobber and when we delete such moves
we should delete the clobber insn too to keep the correct life
info. */
static void
delete_move_and_clobber (rtx_insn *insn, int dregno)
{
rtx_insn *prev_insn = PREV_INSN (insn);
lra_set_insn_deleted (insn);
lra_assert (dregno > 0);
if (prev_insn != NULL && NONDEBUG_INSN_P (prev_insn)
&& GET_CODE (PATTERN (prev_insn)) == CLOBBER
&& dregno == get_regno (XEXP (PATTERN (prev_insn), 0)))
lra_set_insn_deleted (prev_insn);
}
/* Remove inheritance/split pseudos which are in REMOVE_PSEUDOS and /* Remove inheritance/split pseudos which are in REMOVE_PSEUDOS and
return true if we did any change. The undo transformations for return true if we did any change. The undo transformations for
inheritance looks like inheritance looks like
...@@ -5922,7 +5940,7 @@ remove_inheritance_pseudos (bitmap remove_pseudos) ...@@ -5922,7 +5940,7 @@ remove_inheritance_pseudos (bitmap remove_pseudos)
? "split" : "inheritance"); ? "split" : "inheritance");
dump_insn_slim (lra_dump_file, curr_insn); dump_insn_slim (lra_dump_file, curr_insn);
} }
lra_set_insn_deleted (curr_insn); delete_move_and_clobber (curr_insn, dregno);
done_p = true; done_p = true;
} }
else if (bitmap_bit_p (remove_pseudos, sregno) else if (bitmap_bit_p (remove_pseudos, sregno)
...@@ -6122,7 +6140,7 @@ undo_optional_reloads (void) ...@@ -6122,7 +6140,7 @@ undo_optional_reloads (void)
INSN_UID (insn)); INSN_UID (insn));
dump_insn_slim (lra_dump_file, insn); dump_insn_slim (lra_dump_file, insn);
} }
lra_set_insn_deleted (insn); delete_move_and_clobber (insn, REGNO (dest));
continue; continue;
} }
/* We should not worry about generation memory-memory /* We should not worry about generation memory-memory
......
2016-03-12 Vladimir Makarov <vmakarov@redhat.com>
PR target/69614
* gcc.target/arm/pr69614.c: New.
2016-03-12 Paul Thomas <pault@gcc.gnu.org> 2016-03-12 Paul Thomas <pault@gcc.gnu.org>
PR fortran/70031 PR fortran/70031
......
/* { dg-do run } */
/* { dg-require-effective-target arm_arch_v7a_ok } */
/* { dg-options "-Os -w -fno-expensive-optimizations -fschedule-insns -mtpcs-leaf-frame -fira-algorithm=priority" } */
typedef unsigned short u16;
typedef unsigned short v16u16 __attribute__ ((vector_size (16)));
typedef unsigned int u32;
typedef unsigned int v16u32 __attribute__ ((vector_size (16)));
typedef unsigned long long u64;
typedef unsigned long long v16u64 __attribute__ ((vector_size (16)));
u64 __attribute__ ((noinline, noclone))
foo(u16 u16_0, u32 u32_0, u64 u64_0, u16 u16_1, u32 u32_1, u64 u64_1,
v16u16 v16u16_0, v16u32 v16u32_0, v16u64 v16u64_0, v16u16 v16u16_1, v16u32 v16u32_1, v16u64 v16u64_1)
{
v16u64_0 %= (v16u64){(u16) v16u16_0[5], ~v16u64_1[1]};
v16u64_0[1] = 1;
v16u32_1[3] >>= 31;
v16u64_1 ^= (v16u64){v16u16_1[4], u64_1};
v16u64_1[0] = (v16u64_1[0] >> 63) | (v16u64_1[0] << 1);
u16_0 -= 1;
v16u32_1 %= (v16u32)-v16u64_0 | 1;
v16u16_0 /= (v16u16){-u64_1} | 1;
v16u32_0[2] |= (u16)~u16_1;
return u16_0 + u64_0 + u32_1 + u64_1 +
v16u16_0[0] + v16u16_0[1] + v16u16_0[2] + v16u16_0[3] + v16u16_0[4] + v16u16_0[5] + v16u16_0[6] + v16u32_0[2] + v16u32_0[3] + v16u64_0[0] +
v16u16_1[2] + v16u16_1[4] + v16u32_1[0] + v16u32_1[1] + v16u32_1[2] + v16u32_1[3] + v16u64_1[0] + v16u64_1[1];
}
int
main ()
{
u64 x = foo(0, 0, 1, 0, 0, 1, (v16u16){-1, 0, 0, 0, 0, 1}, (v16u32){0}, (v16u64){0}, (v16u16){0}, (v16u32){0}, (v16u64){0x67784fdb22, 1});
__builtin_printf ("%016llx\n", (unsigned long long) (x >> 0));
if (x != 0x000000cef0a1b646)
__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