aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2016-03-12 14:56:24 +0000
committerVladimir Makarov <vmakarov@gcc.gnu.org>2016-03-12 14:56:24 +0000
commitcefe08a4ec4ff2e8dadfc26f89e70be5a3f21a1f (patch)
tree89175bb87f020eb40814bf5bb4015c266618b554 /gcc
parent70112e2a64f7cbeddb9a1155e6cb65e188f6d7e3 (diff)
downloadgcc-cefe08a4ec4ff2e8dadfc26f89e70be5a3f21a1f.zip
gcc-cefe08a4ec4ff2e8dadfc26f89e70be5a3f21a1f.tar.gz
gcc-cefe08a4ec4ff2e8dadfc26f89e70be5a3f21a1f.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/lra-constraints.c22
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/arm/pr69614.c39
4 files changed, 70 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0ee79e0..7d73d32 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+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>
PR ada/70017
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index ef18100..b070218 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -5850,6 +5850,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
@@ -5922,7 +5940,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)
@@ -6122,7 +6140,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/ChangeLog b/gcc/testsuite/ChangeLog
index dd470c3..4ef53c4 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+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>
PR fortran/70031
diff --git a/gcc/testsuite/gcc.target/arm/pr69614.c b/gcc/testsuite/gcc.target/arm/pr69614.c
new file mode 100644
index 0000000..dadcb5c
--- /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;
+}