re PR tree-optimization/68786 (Aligned masked store is generated for unaligned pointer)
authorJakub Jelinek <jakub@redhat.com>
Wed, 9 Dec 2015 13:42:06 +0000 (14:42 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 9 Dec 2015 13:42:06 +0000 (14:42 +0100)
PR tree-optimization/68786
* tree-if-conv.c: Include builtins.h.
(predicate_mem_writes): Put result of get_object_alignment (ref)
into second argument's value.
* tree-vect-stmts.c (vectorizable_mask_load_store): Put minimum
pointer alignment into second argument's value.
* tree-data-ref.c (get_references_in_stmt): Use value of second
argument for build_aligned_type, and only the type to build
a zero second argument for MEM_REF.
* internal-fn.c (expand_mask_load_optab_fn,
expand_mask_store_optab_fn): Likewise.

From-SVN: r231454

gcc/ChangeLog
gcc/internal-fn.c
gcc/tree-data-ref.c
gcc/tree-if-conv.c
gcc/tree-vect-stmts.c

index 3da8d1b..8526be6 100644 (file)
@@ -1,3 +1,17 @@
+2015-12-09  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/68786
+       * tree-if-conv.c: Include builtins.h.
+       (predicate_mem_writes): Put result of get_object_alignment (ref)
+       into second argument's value.
+       * tree-vect-stmts.c (vectorizable_mask_load_store): Put minimum
+       pointer alignment into second argument's value.
+       * tree-data-ref.c (get_references_in_stmt): Use value of second
+       argument for build_aligned_type, and only the type to build
+       a zero second argument for MEM_REF.
+       * internal-fn.c (expand_mask_load_optab_fn,
+       expand_mask_store_optab_fn): Likewise.
+
 2015-12-09  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/68583
index 2be2d88..3ceaffe 100644 (file)
@@ -1911,16 +1911,20 @@ static void
 expand_mask_load_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
 {
   struct expand_operand ops[3];
-  tree type, lhs, rhs, maskt;
+  tree type, lhs, rhs, maskt, ptr;
   rtx mem, target, mask;
+  unsigned align;
 
   maskt = gimple_call_arg (stmt, 2);
   lhs = gimple_call_lhs (stmt);
   if (lhs == NULL_TREE)
     return;
   type = TREE_TYPE (lhs);
-  rhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0),
-                    gimple_call_arg (stmt, 1));
+  ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0);
+  align = tree_to_shwi (gimple_call_arg (stmt, 1));
+  if (TYPE_ALIGN (type) != align)
+    type = build_aligned_type (type, align);
+  rhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), ptr);
 
   mem = expand_expr (rhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
   gcc_assert (MEM_P (mem));
@@ -1940,14 +1944,18 @@ static void
 expand_mask_store_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
 {
   struct expand_operand ops[3];
-  tree type, lhs, rhs, maskt;
+  tree type, lhs, rhs, maskt, ptr;
   rtx mem, reg, mask;
+  unsigned align;
 
   maskt = gimple_call_arg (stmt, 2);
   rhs = gimple_call_arg (stmt, 3);
   type = TREE_TYPE (rhs);
-  lhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0),
-                    gimple_call_arg (stmt, 1));
+  ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0);
+  align = tree_to_shwi (gimple_call_arg (stmt, 1));
+  if (TYPE_ALIGN (type) != align)
+    type = build_aligned_type (type, align);
+  lhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), ptr);
 
   mem = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
   gcc_assert (MEM_P (mem));
index 74f7614..ec80055 100644 (file)
@@ -3872,6 +3872,8 @@ get_references_in_stmt (gimple *stmt, vec<data_ref_loc, va_heap> *references)
   else if (stmt_code == GIMPLE_CALL)
     {
       unsigned i, n;
+      tree ptr, type;
+      unsigned int align;
 
       ref.is_read = false;
       if (gimple_call_internal_p (stmt))
@@ -3882,12 +3884,16 @@ get_references_in_stmt (gimple *stmt, vec<data_ref_loc, va_heap> *references)
              break;
            ref.is_read = true;
          case IFN_MASK_STORE:
-           ref.ref = fold_build2 (MEM_REF,
-                                  ref.is_read
-                                  ? TREE_TYPE (gimple_call_lhs (stmt))
-                                  : TREE_TYPE (gimple_call_arg (stmt, 3)),
-                                  gimple_call_arg (stmt, 0),
-                                  gimple_call_arg (stmt, 1));
+           ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0);
+           align = tree_to_shwi (gimple_call_arg (stmt, 1));
+           if (ref.is_read)
+             type = TREE_TYPE (gimple_call_lhs (stmt));
+           else
+             type = TREE_TYPE (gimple_call_arg (stmt, 3));
+           if (TYPE_ALIGN (type) != align)
+             type = build_aligned_type (type, align);
+           ref.ref = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0),
+                                  ptr);
            references->safe_push (ref);
            return false;
          default:
index 637fa22..55b590b 100644 (file)
@@ -111,6 +111,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "dbgcnt.h"
 #include "tree-hash-traits.h"
 #include "varasm.h"
+#include "builtins.h"
 
 /* List of basic blocks in if-conversion-suitable order.  */
 static basic_block *ifc_bbs;
@@ -2056,7 +2057,8 @@ predicate_mem_writes (loop_p loop)
                vect_sizes.safe_push (bitsize);
                vect_masks.safe_push (mask);
              }
-           ptr = build_int_cst (reference_alias_ptr_type (ref), 0);
+           ptr = build_int_cst (reference_alias_ptr_type (ref),
+                                get_object_alignment (ref));
            /* Copy points-to info if possible.  */
            if (TREE_CODE (addr) == SSA_NAME && !SSA_NAME_PTR_INFO (addr))
              copy_ref_info (build2 (MEM_REF, TREE_TYPE (ref), addr, ptr),
index 1a65c03..56aa2c8 100644 (file)
@@ -2058,10 +2058,11 @@ vectorizable_mask_load_store (gimple *stmt, gimple_stmt_iterator *gsi,
            misalign = DR_MISALIGNMENT (dr);
          set_ptr_info_alignment (get_ptr_info (dataref_ptr), align,
                                  misalign);
+         tree ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)),
+                                   misalign ? misalign & -misalign : align);
          new_stmt
            = gimple_build_call_internal (IFN_MASK_STORE, 4, dataref_ptr,
-                                         gimple_call_arg (stmt, 1),
-                                         vec_mask, vec_rhs);
+                                         ptr, vec_mask, vec_rhs);
          vect_finish_stmt_generation (stmt, new_stmt, gsi);
          if (i == 0)
            STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
@@ -2107,10 +2108,11 @@ vectorizable_mask_load_store (gimple *stmt, gimple_stmt_iterator *gsi,
            misalign = DR_MISALIGNMENT (dr);
          set_ptr_info_alignment (get_ptr_info (dataref_ptr), align,
                                  misalign);
+         tree ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)),
+                                   misalign ? misalign & -misalign : align);
          new_stmt
            = gimple_build_call_internal (IFN_MASK_LOAD, 3, dataref_ptr,
-                                         gimple_call_arg (stmt, 1),
-                                         vec_mask);
+                                         ptr, vec_mask);
          gimple_call_set_lhs (new_stmt, make_ssa_name (vec_dest));
          vect_finish_stmt_generation (stmt, new_stmt, gsi);
          if (i == 0)