Re: [PATCH 3/3] Misaligned MEM_REF reads

2012-03-16 Thread Richard Guenther
On Wed, 14 Mar 2012, Martin Jambor wrote:

 Hi,
 
 On Mon, Mar 12, 2012 at 03:09:04PM +0100, Martin Jambor wrote:
  Hi,
  
  this patch is very similar to the one I posted before
  (http://gcc.gnu.org/ml/gcc-patches/2012-02/msg01377.html) except that
  it is now adjusted to sit on top of the new one before this and does
  not ignore complex numbers...
 
 This is the same patch updated to apply on top of the new version of
 the previous one (which I have committed a moment ago).  Again,
 bootstrapped and tested on x86_64-linux (all languages including Ada
 and Java), usparc64-linux (without Java) and ia64-linux (without
 Ada), the i686 compile farm machine was not accessible yesterday so I
 don't have any results from it but will start a test right now.
 
 OK for trunk?

Ok.

Thanks,
Richard.

 Thanks,
 
 Martin
 
 
 
 2012-03-12  Martin Jambor  mjam...@suse.cz
 
   * expr.c (expand_expr_real_1): handle misaligned scalar reads from
   memory through MEM_REFs by calling extract_bit_field.
 
   * testsuite/gcc.dg/misaligned-expand-1.c: New test.
   * testsuite/gcc.dg/misaligned-expand-3.c: Likewise.
 
 
 Index: src/gcc/expr.c
 ===
 --- src.orig/gcc/expr.c
 +++ src/gcc/expr.c
 @@ -9411,21 +9411,27 @@ expand_expr_real_1 (tree exp, rtx target
 MEM_VOLATILE_P (temp) = 1;
   if (modifier != EXPAND_WRITE
mode != BLKmode
 -  align  GET_MODE_ALIGNMENT (mode)
 - /* If the target does not have special handling for unaligned
 -loads of mode then it can use regular moves for them.  */
 -  ((icode = optab_handler (movmisalign_optab, mode))
 - != CODE_FOR_nothing))
 +  align  GET_MODE_ALIGNMENT (mode))
 {
 - struct expand_operand ops[2];
 + if ((icode = optab_handler (movmisalign_optab, mode))
 + != CODE_FOR_nothing)
 +   {
 + struct expand_operand ops[2];
  
 - /* We've already validated the memory, and we're creating a
 -new pseudo destination.  The predicates really can't fail,
 -nor can the generator.  */
 - create_output_operand (ops[0], NULL_RTX, mode);
 - create_fixed_operand (ops[1], temp);
 - expand_insn (icode, 2, ops);
 - return ops[0].value;
 + /* We've already validated the memory, and we're creating a
 +new pseudo destination.  The predicates really can't fail,
 +nor can the generator.  */
 + create_output_operand (ops[0], NULL_RTX, mode);
 + create_fixed_operand (ops[1], temp);
 + expand_insn (icode, 2, ops);
 + return ops[0].value;
 +   }
 + else if (SLOW_UNALIGNED_ACCESS (mode, align))
 +   temp = extract_bit_field (temp, GET_MODE_BITSIZE (mode),
 + 0, TYPE_UNSIGNED (TREE_TYPE (exp)),
 + true, (modifier == EXPAND_STACK_PARM
 +? NULL_RTX : target),
 + mode, mode);
 }
   return temp;
}
 Index: src/gcc/testsuite/gcc.dg/misaligned-expand-1.c
 ===
 --- /dev/null
 +++ src/gcc/testsuite/gcc.dg/misaligned-expand-1.c
 @@ -0,0 +1,41 @@
 +/* Test that expand can generate correct loads of misaligned data even on
 +   strict alignment platforms.  */
 +
 +/* { dg-do run } */
 +/* { dg-options -O0 } */
 +
 +extern void abort ();
 +
 +typedef unsigned int myint __attribute__((aligned(1)));
 +
 +unsigned int
 +foo (myint *p)
 +{
 +  return *p;
 +}
 +
 +#define cst 0xdeadbeef
 +#define NUM 8
 +
 +struct blah
 +{
 +  char c;
 +  myint i[NUM];
 +};
 +
 +struct blah g;
 +
 +int
 +main (int argc, char **argv)
 +{
 +  int i, k;
 +  for (k = 0; k  NUM; k++)
 +{
 +  g.i[k] = cst;
 +  i = foo (g.i[k]);
 +
 +  if (i != cst)
 + abort ();
 +}
 +  return 0;
 +}
 Index: src/gcc/testsuite/gcc.dg/misaligned-expand-3.c
 ===
 --- /dev/null
 +++ src/gcc/testsuite/gcc.dg/misaligned-expand-3.c
 @@ -0,0 +1,43 @@
 +/* Test that expand can generate correct stores to misaligned data of complex
 +   type even on strict alignment platforms.  */
 +
 +/* { dg-do run } */
 +/* { dg-options -O0 } */
 +
 +extern void abort ();
 +
 +typedef _Complex float mycmplx __attribute__((aligned(1)));
 +
 +void
 +foo (mycmplx *p, float r, float i)
 +{
 +  __real__ *p = r;
 +  __imag__ *p = i;
 +}
 +
 +#define cvr 3.2f
 +#define cvi 2.5f
 +#define NUM 8
 +
 +struct blah
 +{
 +  char c;
 +  mycmplx x[NUM];
 +} __attribute__((packed));
 +
 +struct blah g;
 +
 +int
 +main (int argc, char **argv)
 +{
 +  int k;
 +
 +  for (k = 0; k  NUM; k++)
 +{
 +  foo (g.x[k], cvr, cvi);
 +  if (__real__ g.x[k] != cvr
 +   || __imag__ g.x[k] != cvi)
 + 

Re: [PATCH 3/3] Misaligned MEM_REF reads

2012-03-14 Thread Martin Jambor
Hi,

On Mon, Mar 12, 2012 at 03:09:04PM +0100, Martin Jambor wrote:
 Hi,
 
 this patch is very similar to the one I posted before
 (http://gcc.gnu.org/ml/gcc-patches/2012-02/msg01377.html) except that
 it is now adjusted to sit on top of the new one before this and does
 not ignore complex numbers...

This is the same patch updated to apply on top of the new version of
the previous one (which I have committed a moment ago).  Again,
bootstrapped and tested on x86_64-linux (all languages including Ada
and Java), usparc64-linux (without Java) and ia64-linux (without
Ada), the i686 compile farm machine was not accessible yesterday so I
don't have any results from it but will start a test right now.

OK for trunk?

Thanks,

Martin



2012-03-12  Martin Jambor  mjam...@suse.cz

* expr.c (expand_expr_real_1): handle misaligned scalar reads from
memory through MEM_REFs by calling extract_bit_field.

* testsuite/gcc.dg/misaligned-expand-1.c: New test.
* testsuite/gcc.dg/misaligned-expand-3.c: Likewise.


Index: src/gcc/expr.c
===
--- src.orig/gcc/expr.c
+++ src/gcc/expr.c
@@ -9411,21 +9411,27 @@ expand_expr_real_1 (tree exp, rtx target
  MEM_VOLATILE_P (temp) = 1;
if (modifier != EXPAND_WRITE
 mode != BLKmode
-align  GET_MODE_ALIGNMENT (mode)
-   /* If the target does not have special handling for unaligned
-  loads of mode then it can use regular moves for them.  */
-((icode = optab_handler (movmisalign_optab, mode))
-   != CODE_FOR_nothing))
+align  GET_MODE_ALIGNMENT (mode))
  {
-   struct expand_operand ops[2];
+   if ((icode = optab_handler (movmisalign_optab, mode))
+   != CODE_FOR_nothing)
+ {
+   struct expand_operand ops[2];
 
-   /* We've already validated the memory, and we're creating a
-  new pseudo destination.  The predicates really can't fail,
-  nor can the generator.  */
-   create_output_operand (ops[0], NULL_RTX, mode);
-   create_fixed_operand (ops[1], temp);
-   expand_insn (icode, 2, ops);
-   return ops[0].value;
+   /* We've already validated the memory, and we're creating a
+  new pseudo destination.  The predicates really can't fail,
+  nor can the generator.  */
+   create_output_operand (ops[0], NULL_RTX, mode);
+   create_fixed_operand (ops[1], temp);
+   expand_insn (icode, 2, ops);
+   return ops[0].value;
+ }
+   else if (SLOW_UNALIGNED_ACCESS (mode, align))
+ temp = extract_bit_field (temp, GET_MODE_BITSIZE (mode),
+   0, TYPE_UNSIGNED (TREE_TYPE (exp)),
+   true, (modifier == EXPAND_STACK_PARM
+  ? NULL_RTX : target),
+   mode, mode);
  }
return temp;
   }
Index: src/gcc/testsuite/gcc.dg/misaligned-expand-1.c
===
--- /dev/null
+++ src/gcc/testsuite/gcc.dg/misaligned-expand-1.c
@@ -0,0 +1,41 @@
+/* Test that expand can generate correct loads of misaligned data even on
+   strict alignment platforms.  */
+
+/* { dg-do run } */
+/* { dg-options -O0 } */
+
+extern void abort ();
+
+typedef unsigned int myint __attribute__((aligned(1)));
+
+unsigned int
+foo (myint *p)
+{
+  return *p;
+}
+
+#define cst 0xdeadbeef
+#define NUM 8
+
+struct blah
+{
+  char c;
+  myint i[NUM];
+};
+
+struct blah g;
+
+int
+main (int argc, char **argv)
+{
+  int i, k;
+  for (k = 0; k  NUM; k++)
+{
+  g.i[k] = cst;
+  i = foo (g.i[k]);
+
+  if (i != cst)
+   abort ();
+}
+  return 0;
+}
Index: src/gcc/testsuite/gcc.dg/misaligned-expand-3.c
===
--- /dev/null
+++ src/gcc/testsuite/gcc.dg/misaligned-expand-3.c
@@ -0,0 +1,43 @@
+/* Test that expand can generate correct stores to misaligned data of complex
+   type even on strict alignment platforms.  */
+
+/* { dg-do run } */
+/* { dg-options -O0 } */
+
+extern void abort ();
+
+typedef _Complex float mycmplx __attribute__((aligned(1)));
+
+void
+foo (mycmplx *p, float r, float i)
+{
+  __real__ *p = r;
+  __imag__ *p = i;
+}
+
+#define cvr 3.2f
+#define cvi 2.5f
+#define NUM 8
+
+struct blah
+{
+  char c;
+  mycmplx x[NUM];
+} __attribute__((packed));
+
+struct blah g;
+
+int
+main (int argc, char **argv)
+{
+  int k;
+
+  for (k = 0; k  NUM; k++)
+{
+  foo (g.x[k], cvr, cvi);
+  if (__real__ g.x[k] != cvr
+ || __imag__ g.x[k] != cvi)
+   abort ();
+}
+  return 0;
+}