summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2004-03-04 09:01:03 +0000
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2004-03-04 09:01:03 +0000
commitd6af6bc2277b4be75e143a806add564c2b116b84 (patch)
tree70ca7951bbb8dd5d3322110e353693674bfc1df8 /gcc
parent93d302144297d18f61298c3e92ab72436fc82322 (diff)
downloadgcc-d6af6bc2277b4be75e143a806add564c2b116b84.tar.gz
PR optimization/14235
* expr.c (convert_move): Copy the source to a new pseudo when converting from a sub-word source to a larger-than-word register which conflicts with the source. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@78893 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/expr.c6
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20040304-1.c45
4 files changed, 61 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f1dd35f5dc7..3c6aae3558b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2004-03-04 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/14235
+ * expr.c (convert_move): Copy the source to a new pseudo
+ when converting from a sub-word source to a larger-than-word
+ register which conflicts with the source.
+
2004-03-03 Zack Weinberg <zack@codesourcery.com>
PR 13728
diff --git a/gcc/expr.c b/gcc/expr.c
index e2063c1950f..14809498a93 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -682,7 +682,11 @@ convert_move (rtx to, rtx from, int unsignedp)
!= CODE_FOR_nothing))
{
if (GET_CODE (to) == REG)
- emit_insn (gen_rtx_CLOBBER (VOIDmode, to));
+ {
+ if (reg_overlap_mentioned_p (to, from))
+ from = force_reg (from_mode, from);
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, to));
+ }
convert_move (gen_lowpart (word_mode, to), from, unsignedp);
emit_unop_insn (code, to,
gen_lowpart (word_mode, to), equiv_code);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b0edee4d54a..931439d24b5 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2004-03-04 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * gcc.c-torture/compile/20040304-1.c: New test.
+
2004-03-03 Zack Weinberg <zack@codesourcery.com>
PR 13728
diff --git a/gcc/testsuite/gcc.c-torture/compile/20040304-1.c b/gcc/testsuite/gcc.c-torture/compile/20040304-1.c
new file mode 100644
index 00000000000..146d42f23d6
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20040304-1.c
@@ -0,0 +1,45 @@
+/* PR optimization/14235 */
+/* Origin: <senor_fjord@yahoo.com> */
+
+typedef signed char int8_t;
+typedef short int16_t;
+typedef int int32_t;
+typedef unsigned long long uint64_t;
+
+static const uint64_t LOW_BYTE_MASK = 0x00000000000000ffULL;
+static const uint64_t HIGH_BYTE_MASK = 0x000000000000ff00ULL;
+static const uint64_t WORD_MASK = 0x000000000000ffffULL;
+static const uint64_t DWORD_MASK = 0x00000000ffffffffULL;
+
+extern uint64_t *srca_mask;
+extern int *assert_thrown;
+
+void foo()
+{
+ uint64_t tempA = 0; /* actually a bunch of code to set A */
+ uint64_t tempB = 0; /* actually a bunch of code to set B */
+
+ /* cast A to right size */
+ tempA = (((*srca_mask == LOW_BYTE_MASK) ||
+ (*srca_mask == HIGH_BYTE_MASK)) ?
+ ((int8_t)tempA) :
+ ((*srca_mask == WORD_MASK) ?
+ ((int16_t)tempA) :
+ ((*srca_mask == DWORD_MASK) ?
+ ((int32_t)tempA) :
+ tempA)));
+
+ /* cast B to right size */
+ tempB = (((*srca_mask == LOW_BYTE_MASK) ||
+ (*srca_mask == HIGH_BYTE_MASK)) ?
+ ((int8_t)tempB) :
+ ((*srca_mask == WORD_MASK) ?
+ ((int16_t)tempB) :
+ ((*srca_mask == DWORD_MASK) ?
+ ((int32_t)tempB) :
+ tempB)));
+
+ if ((int) tempA > (int) tempB) {
+ *assert_thrown = 1;
+ }
+}