re PR middle-end/60092 (posix_memalign not recognized to derive alias and alignment...
authorRichard Biener <rguenther@suse.de>
Wed, 12 Feb 2014 13:36:08 +0000 (13:36 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 12 Feb 2014 13:36:08 +0000 (13:36 +0000)
2014-02-12  Richard Biener  <rguenther@suse.de>

PR middle-end/60092
* gimple-low.c (lower_builtin_posix_memalign): Lower conditional
of posix_memalign being successful.
(lower_stmt): Restrict lowering of posix_memalign to when
-ftree-bit-ccp is enabled.

* gcc.dg/torture/pr60092.c: New testcase.
* gcc.dg/tree-ssa/alias-31.c: Disable SRA.

From-SVN: r207720

gcc/ChangeLog
gcc/gimple-low.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr60092.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/alias-31.c

index 4f22604..1f4ddb8 100644 (file)
@@ -1,3 +1,11 @@
+2014-02-12  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/60092
+       * gimple-low.c (lower_builtin_posix_memalign): Lower conditional
+       of posix_memalign being successful.
+       (lower_stmt): Restrict lowering of posix_memalign to when
+       -ftree-bit-ccp is enabled.
+
 2014-02-12  Senthil Kumar Selvaraj  <senthil_kumar.selvaraj@atmel.com>
 
        * config/avr/avr-c.c (avr_resolve_overloaded_builtin): Pass vNULL for
index 01e9e9c..80fd786 100644 (file)
@@ -336,7 +336,8 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data)
                data->cannot_fallthru = false;
                return;
              }
-           else if (DECL_FUNCTION_CODE (decl) == BUILT_IN_POSIX_MEMALIGN)
+           else if (DECL_FUNCTION_CODE (decl) == BUILT_IN_POSIX_MEMALIGN
+                    && flag_tree_bit_ccp)
              {
                lower_builtin_posix_memalign (gsi);
                return;
@@ -781,37 +782,47 @@ lower_builtin_setjmp (gimple_stmt_iterator *gsi)
 }
 
 /* Lower calls to posix_memalign to
-     posix_memalign (ptr, align, size);
-     tem = *ptr;
-     tem = __builtin_assume_aligned (tem, align);
-     *ptr = tem;
+     res = posix_memalign (ptr, align, size);
+     if (res == 0)
+       *ptr = __builtin_assume_aligned (*ptr, align);
    or to
      void *tem;
-     posix_memalign (&tem, align, size);
-     ttem = tem;
-     ttem = __builtin_assume_aligned (ttem, align);
-     ptr = tem;
+     res = posix_memalign (&tem, align, size);
+     if (res == 0)
+       ptr = __builtin_assume_aligned (tem, align);
    in case the first argument was &ptr.  That way we can get at the
    alignment of the heap pointer in CCP.  */
 
 static void
 lower_builtin_posix_memalign (gimple_stmt_iterator *gsi)
 {
-  gimple stmt = gsi_stmt (*gsi);
-  tree pptr = gimple_call_arg (stmt, 0);
-  tree align = gimple_call_arg (stmt, 1);
+  gimple stmt, call = gsi_stmt (*gsi);
+  tree pptr = gimple_call_arg (call, 0);
+  tree align = gimple_call_arg (call, 1);
+  tree res = gimple_call_lhs (call);
   tree ptr = create_tmp_reg (ptr_type_node, NULL);
   if (TREE_CODE (pptr) == ADDR_EXPR)
     {
       tree tem = create_tmp_var (ptr_type_node, NULL);
       TREE_ADDRESSABLE (tem) = 1;
-      gimple_call_set_arg (stmt, 0, build_fold_addr_expr (tem));
+      gimple_call_set_arg (call, 0, build_fold_addr_expr (tem));
       stmt = gimple_build_assign (ptr, tem);
     }
   else
     stmt = gimple_build_assign (ptr,
                                fold_build2 (MEM_REF, ptr_type_node, pptr,
                                             build_int_cst (ptr_type_node, 0)));
+  if (res == NULL_TREE)
+    {
+      res = create_tmp_reg (integer_type_node, NULL);
+      gimple_call_set_lhs (call, res);
+    }
+  tree align_label = create_artificial_label (UNKNOWN_LOCATION);
+  tree noalign_label = create_artificial_label (UNKNOWN_LOCATION);
+  gimple cond = gimple_build_cond (EQ_EXPR, res, integer_zero_node,
+                                  align_label, noalign_label);
+  gsi_insert_after (gsi, cond, GSI_NEW_STMT);
+  gsi_insert_after (gsi, gimple_build_label (align_label), GSI_NEW_STMT);
   gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
   stmt = gimple_build_call (builtin_decl_implicit (BUILT_IN_ASSUME_ALIGNED),
                            2, ptr, align);
@@ -821,6 +832,7 @@ lower_builtin_posix_memalign (gimple_stmt_iterator *gsi)
                                           build_int_cst (ptr_type_node, 0)),
                              ptr);
   gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
+  gsi_insert_after (gsi, gimple_build_label (noalign_label), GSI_NEW_STMT);
 }
 \f
 
index 5555d3e..c87966d 100644 (file)
@@ -1,3 +1,9 @@
+2014-02-12  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/60092
+       * gcc.dg/torture/pr60092.c: New testcase.
+       * gcc.dg/tree-ssa/alias-31.c: Disable SRA.
+
 2014-02-12  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gcc.c-torture/execute/20140212-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/torture/pr60092.c b/gcc/testsuite/gcc.dg/torture/pr60092.c
new file mode 100644 (file)
index 0000000..f1ff80d
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+/* { dg-require-weak "" } */
+
+typedef __SIZE_TYPE__ size_t;
+extern int posix_memalign(void **memptr, size_t alignment, size_t size) __attribute__((weak));
+extern void abort(void);
+int
+main (void)
+{
+  void *p;
+  int ret;
+
+  if (!posix_memalign)
+    return 0;
+
+  p = (void *)&ret;
+  ret = posix_memalign (&p, sizeof (void *), -1);
+  if (p != (void *)&ret)
+    abort ();
+  return 0;
+}
index f1aefbd..622df80 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-cddce1" } */
+/* { dg-options "-O2 -fno-tree-sra -fdump-tree-cddce1" } */
 
 extern int posix_memalign(void **memptr,
                          __SIZE_TYPE__ alignment, __SIZE_TYPE__ size);