aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/expr.c12
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr57134.c29
4 files changed, 46 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5096b2e..e7d352c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2013-06-14 Alan Modra <amodra@gmail.com>
+
+ PR middle-end/57134
+ PR middle-end/57586
+ * expr.c (expand_expr_real_1 <normal_inner_ref>): Pass
+ EXPAND_MEMORY and EXPAND_WRITE to recursive call. Don't use
+ bitfield expansion when EXPAND_MEMORY.
+ (expand_expr_real_1 <VIEW_CONVERT_EXPR>): Pass modifier likewise.
+
2013-06-13 Michael Meissner <meissner@linux.vnet.ibm.com>
* config/rs6000/rs6000.c (rs6000_option_override_internal): Move
diff --git a/gcc/expr.c b/gcc/expr.c
index 2cdb87c..c68f489 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -9909,11 +9909,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
&& modifier != EXPAND_STACK_PARM
? target : NULL_RTX),
VOIDmode,
- (modifier == EXPAND_INITIALIZER
- || modifier == EXPAND_CONST_ADDRESS
- || modifier == EXPAND_STACK_PARM)
- ? modifier : EXPAND_NORMAL);
-
+ modifier == EXPAND_SUM ? EXPAND_NORMAL : modifier);
/* If the bitfield is volatile, we want to access it in the
field's mode, not the computed mode.
@@ -10072,6 +10068,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
|| (MEM_P (op0)
&& (MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode1)
|| (bitpos % GET_MODE_ALIGNMENT (mode1) != 0))))
+ && modifier != EXPAND_MEMORY
&& ((modifier == EXPAND_CONST_ADDRESS
|| modifier == EXPAND_INITIALIZER)
? STRICT_ALIGNMENT
@@ -10271,10 +10268,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
&& modifier != EXPAND_STACK_PARM
? target : NULL_RTX),
VOIDmode,
- (modifier == EXPAND_INITIALIZER
- || modifier == EXPAND_CONST_ADDRESS
- || modifier == EXPAND_STACK_PARM)
- ? modifier : EXPAND_NORMAL);
+ modifier == EXPAND_SUM ? EXPAND_NORMAL : modifier);
if (MEM_P (orig_op0))
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0d4c54e..a209086 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2013-06-14 Alan Modra <amodra@gmail.com>
+
+ PR middle-end/57134
+ * gcc.dg/pr57134.c: New.
+
2013-06-14 Tobias Burnus <burnus@net-b.de>
PR fortran/57596
diff --git a/gcc/testsuite/gcc.dg/pr57134.c b/gcc/testsuite/gcc.dg/pr57134.c
new file mode 100644
index 0000000..94ff092
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr57134.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target stdint_types } */
+/* { dg-options "-O2" } */
+/* { dg-options "-O2 -mstrict-align" { target { powerpc*-*-linux* powerpc*-*-elf* } } } */
+
+#include <stdint.h>
+
+typedef struct {
+ int64_t counter;
+} atomic64_t;
+
+struct buffer_page {
+ void *a, *b;
+ atomic64_t entries;
+};
+
+static __inline__ __attribute__((always_inline)) int64_t
+atomic64_read(const atomic64_t *v)
+{
+ int64_t t;
+ __asm__ __volatile__("# %0, %1" : "=r"(t) : "m"(v->counter));
+ return t;
+}
+
+int rb_remove_pages(void *p)
+{
+ struct buffer_page *blah = (void *)((intptr_t) p & -4);
+ return atomic64_read(&blah->entries);
+}