]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
vect, aarch64: Fix alignment units for IFN_MASK* [PR95401]
authorRichard Sandiford <richard.sandiford@arm.com>
Tue, 12 Jan 2021 09:55:47 +0000 (09:55 +0000)
committerRichard Sandiford <richard.sandiford@arm.com>
Tue, 12 Jan 2021 09:55:47 +0000 (09:55 +0000)
The IFN_MASK* functions take two leading arguments: a load or
store pointer and a “cookie”.  The type of the cookie is the
type of the access for TBAA purposes (like for MEM_REFs)
while the value of the cookie is the alignment of the access.
This PR was caused by a disagreement about whether the alignment
is measured in bits or bytes.

It looks like this goes back to PR68786, which made the
vectoriser create its own cookie argument rather than reusing
the one created by ifcvt.  The alignment value of the new cookie
was measured in bytes (as needed by set_ptr_info_alignment)
while the existing code expected it to be measured in bits.
The folds I added for IFN_MASK_LOAD and STORE then made
things worse.

gcc/
PR tree-optimization/95401
* config/aarch64/aarch64-sve-builtins.cc
(gimple_folder::load_store_cookie): Use bits rather than bytes
for the alignment argument to IFN_MASK_LOAD and IFN_MASK_STORE.
* gimple-fold.c (gimple_fold_mask_load_store_mem_ref): Likewise.
* tree-vect-stmts.c (vectorizable_store): Likewise.
(vectorizable_load): Likewise.

gcc/testsuite/
PR tree-optimization/95401
* g++.dg/vect/pr95401.cc: New test.
* g++.dg/vect/pr95401a.cc: Likewise.

(cherry picked from commit aa204d511859e4859cbe35a867ac407addb4ff54)

gcc/config/aarch64/aarch64-sve-builtins.cc
gcc/gimple-fold.c
gcc/testsuite/g++.dg/vect/pr95401.cc [new file with mode: 0644]
gcc/testsuite/g++.dg/vect/pr95401a.cc [new file with mode: 0644]
gcc/tree-vect-stmts.c

index 4473f26a651a6fe5e4557692d90a6df200e7525c..d1a7e0fc421125f256ea5daafbb7949a318190ee 100644 (file)
@@ -2576,7 +2576,7 @@ gimple_folder::fold_contiguous_base (gimple_seq &stmts, tree vectype)
 tree
 gimple_folder::load_store_cookie (tree type)
 {
-  return build_int_cst (build_pointer_type (type), TYPE_ALIGN_UNIT (type));
+  return build_int_cst (build_pointer_type (type), TYPE_ALIGN (type));
 }
 
 /* Fold the call to a call to INSTANCE, with the same arguments.  */
index 37e8ae7df9970743496a1cfab40fed80ccc1d8ee..2d7c529215190ef929adf67dab95d6fa21175bc3 100644 (file)
@@ -4302,7 +4302,7 @@ gimple_fold_mask_load_store_mem_ref (gcall *call, tree vectype)
   if (!tree_fits_uhwi_p (alias_align) || !integer_all_onesp (mask))
     return NULL_TREE;
 
-  unsigned HOST_WIDE_INT align = tree_to_uhwi (alias_align) * BITS_PER_UNIT;
+  unsigned HOST_WIDE_INT align = tree_to_uhwi (alias_align);
   if (TYPE_ALIGN (vectype) != align)
     vectype = build_aligned_type (vectype, align);
   tree offset = build_zero_cst (TREE_TYPE (alias_align));
diff --git a/gcc/testsuite/g++.dg/vect/pr95401.cc b/gcc/testsuite/g++.dg/vect/pr95401.cc
new file mode 100644 (file)
index 0000000..6a56dab
--- /dev/null
@@ -0,0 +1,13 @@
+// { dg-additional-options "-mavx2 -O3" { target avx2_runtime } }
+// { dg-additional-sources pr95401a.cc }
+
+extern int var_9;
+extern unsigned var_14;
+extern int arr_16[];
+#include <algorithm>
+void test() {
+  for (short a = 0; a < (short)var_9; a += 12140)
+    for (short b = 0; b < 8; b++)
+      if (std::max(var_14, 1U))
+        arr_16[a + b] = 0;
+}
diff --git a/gcc/testsuite/g++.dg/vect/pr95401a.cc b/gcc/testsuite/g++.dg/vect/pr95401a.cc
new file mode 100644 (file)
index 0000000..71b054c
--- /dev/null
@@ -0,0 +1,13 @@
+// { dg-do compile }
+
+#include "../../gcc.dg/vect/tree-vect.h"
+
+int var_9 = 1693986256, var_14;
+int arr_16[11];
+void test();
+int main()
+{
+  check_vect();
+  test();
+  return 0;
+}
index 65b258d249dba9bedf69c06f183bed855fd679ec..c2d1f39fe0f4bbc90ffa079cb6a8fcf87b76b3af 100644 (file)
@@ -8276,7 +8276,7 @@ vectorizable_store (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
              /* Emit:
                   MASK_STORE_LANES (DATAREF_PTR, ALIAS_PTR, VEC_MASK,
                                     VEC_ARRAY).  */
-             unsigned int align = TYPE_ALIGN_UNIT (TREE_TYPE (vectype));
+             unsigned int align = TYPE_ALIGN (TREE_TYPE (vectype));
              tree alias_ptr = build_int_cst (ref_type, align);
              call = gimple_build_call_internal (IFN_MASK_STORE_LANES, 4,
                                                 dataref_ptr, alias_ptr,
@@ -8390,7 +8390,7 @@ vectorizable_store (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
              if (final_mask)
                {
                  align = least_bit_hwi (misalign | align);
-                 tree ptr = build_int_cst (ref_type, align);
+                 tree ptr = build_int_cst (ref_type, align * BITS_PER_UNIT);
                  gcall *call
                    = gimple_build_call_internal (IFN_MASK_STORE, 4,
                                                  dataref_ptr, ptr,
@@ -9470,7 +9470,7 @@ vectorizable_load (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
              /* Emit:
                   VEC_ARRAY = MASK_LOAD_LANES (DATAREF_PTR, ALIAS_PTR,
                                                VEC_MASK).  */
-             unsigned int align = TYPE_ALIGN_UNIT (TREE_TYPE (vectype));
+             unsigned int align = TYPE_ALIGN (TREE_TYPE (vectype));
              tree alias_ptr = build_int_cst (ref_type, align);
              call = gimple_build_call_internal (IFN_MASK_LOAD_LANES, 3,
                                                 dataref_ptr, alias_ptr,
@@ -9571,7 +9571,8 @@ vectorizable_load (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
                    if (final_mask)
                      {
                        align = least_bit_hwi (misalign | align);
-                       tree ptr = build_int_cst (ref_type, align);
+                       tree ptr = build_int_cst (ref_type,
+                                                 align * BITS_PER_UNIT);
                        gcall *call
                          = gimple_build_call_internal (IFN_MASK_LOAD, 3,
                                                        dataref_ptr, ptr,