diff options
author | Christophe Lyon <christophe.lyon@linaro.org> | 2016-04-08 17:16:38 +0200 |
---|---|---|
committer | Linaro Code Review <review@review.linaro.org> | 2016-04-11 09:06:09 +0000 |
commit | 4b539e776d896fa44203bc6430e82361bc97d2ae (patch) | |
tree | 2494f84bc457e087648538fa0a1e2bb10c6426f7 | |
parent | 046bf329082ef9a1fef6652aceb2401addb086e8 (diff) |
gcc/
Backport from trunk r234162.
2016-03-12 Vladimir Makarov <vmakarov@redhat.com>
PR target/69614
* lra-constraints.c (delete_move_and_clobber): New.
(remove_inheritance_pseudos): Use it.
gcc/testsuite/
Backport from trunk r234162.
2016-03-12 Vladimir Makarov <vmakarov@redhat.com>
PR target/69614
* gcc.target/arm/pr69614.c: New.
Change-Id: I45cb0897e5c0bcc69b1f02aaac8aaff8e7995fd6
-rw-r--r-- | gcc/lra-constraints.c | 22 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/pr69614.c | 39 |
2 files changed, 59 insertions, 2 deletions
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index a10bc772420..b996d67cbd7 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -5835,6 +5835,24 @@ get_regno (rtx reg) 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 return true if we did any change. The undo transformations for inheritance looks like @@ -5907,7 +5925,7 @@ remove_inheritance_pseudos (bitmap remove_pseudos) ? "split" : "inheritance"); dump_insn_slim (lra_dump_file, curr_insn); } - lra_set_insn_deleted (curr_insn); + delete_move_and_clobber (curr_insn, dregno); done_p = true; } else if (bitmap_bit_p (remove_pseudos, sregno) @@ -6107,7 +6125,7 @@ undo_optional_reloads (void) INSN_UID (insn)); dump_insn_slim (lra_dump_file, insn); } - lra_set_insn_deleted (insn); + delete_move_and_clobber (insn, REGNO (dest)); continue; } /* We should not worry about generation memory-memory diff --git a/gcc/testsuite/gcc.target/arm/pr69614.c b/gcc/testsuite/gcc.target/arm/pr69614.c new file mode 100644 index 00000000000..dadcb5cff9e --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr69614.c @@ -0,0 +1,39 @@ +/* { 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; +} |