I fixed this PR, and then it got reopened because the testcase triggered a different problem on Alpha, Mips, and other architectures. The problem is actually totally different than the previous fix for 51472, and has nothing to do with --param tm-max-aggregate-size.

This problem here is that a load is transformed into a transactional memmove in such a way that the subsequent SSA uses are pointing to the wrong thing. For example, originally we have:

    global_var_ssa_999 = global_var;
    *p = global_var_ssa_999;

Through expand_assign_tm -> gimplify_addr -> force_gimple_operand_gsi, the above gets transformed into this:

    D.1234 = global_var_ssa_999; <-- BOO HISS! Uninitialized.
    __builtin__ITM_memmoveRtWt (&D.1234, &global_var, 16);
    *p = global_var_ssa_999; <-- Wuuuut?

We should either propagate D.1234 to the uses of global_var_ssa_999, or copy D.1234 into global_var_ssa_999 and happily proceed. Option B is pretty straightforward, and with the attached patch we end up with:

__builtin__ITM_memmoveRtWt (&D.1234, &global_var, 16);
    global_var_ssa_999 = D.1234;

The attached patch fixes the ICE on alpha-linux-gnu as tested with a cross-cc1 build. Fully bootregtested on x86-64 Linux.

OK?
        PR middle-end/51472
        * trans-mem.c (expand_assign_tm): Handle TM_MEMMOVE loads correctly.
testsuite/
        PR middle-end/51472
        * gcc.dg/tm/memopt-6.c: Adjust regexp.

Index: testsuite/gcc.dg/tm/memopt-6.c
===================================================================
--- testsuite/gcc.dg/tm/memopt-6.c      (revision 182848)
+++ testsuite/gcc.dg/tm/memopt-6.c      (working copy)
@@ -17,5 +17,5 @@ int f()
   return lala.x[i];
 }
 
-/* { dg-final { scan-tree-dump-times "memmoveRtWt \\\(&lala, &lacopy" 1 
"tmedge" } } */
+/* { dg-final { scan-tree-dump-times "memmoveRtWt \\\(.*, &lacopy" 1 "tmedge" 
} } */
 /* { dg-final { cleanup-tree-dump "tmedge" } } */
Index: trans-mem.c
===================================================================
--- trans-mem.c (revision 182876)
+++ trans-mem.c (working copy)
@@ -2174,7 +2174,7 @@ expand_assign_tm (struct tm_region *regi
     }
   if (!gcall)
     {
-      tree lhs_addr, rhs_addr;
+      tree lhs_addr, rhs_addr, tmp;
 
       if (load_p)
        transaction_subcode_ior (region, GTMA_HAVE_LOAD);
@@ -2183,13 +2183,29 @@ expand_assign_tm (struct tm_region *regi
 
       /* ??? Figure out if there's any possible overlap between the LHS
         and the RHS and if not, use MEMCPY.  */
-      lhs_addr = gimplify_addr (gsi, lhs);
+
+      if (load_p && is_gimple_non_addressable (lhs))
+       {
+         tmp = create_tmp_var (TREE_TYPE (lhs), NULL);
+         lhs_addr = build_fold_addr_expr (tmp);
+       }
+      else
+       {
+         tmp = NULL_TREE;
+         lhs_addr = gimplify_addr (gsi, lhs);
+       }
       rhs_addr = gimplify_addr (gsi, rhs);
       gcall = gimple_build_call (builtin_decl_explicit (BUILT_IN_TM_MEMMOVE),
                                 3, lhs_addr, rhs_addr,
                                 TYPE_SIZE_UNIT (TREE_TYPE (lhs)));
       gimple_set_location (gcall, loc);
       gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
+
+      if (tmp)
+       {
+         gcall = gimple_build_assign (lhs, tmp);
+         gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
+       }
     }
 
   /* Now that we have the load/store in its instrumented form, add

Reply via email to