Hi! The following testcases weren't vectorized, because the simd lane accesses weren't recognized there. Usually SIMD lane accesses look like: _22 = .GOMP_SIMD_LANE (simduid.0_14(D), ??); ... MEM <struct S[16]> [(struct S *)&D.2456][_22].s = _25; but on these two testcases we ended up with: _18 = .GOMP_SIMD_LANE (simduid.0_14(D), ??); ... _11 = (sizetype) _18; _9 = _11 * 4; _28 = &D.2456 + _9; _32 = MEM[(int *)_28]; which nothing folded. create_data_ref in this case sets DR_BASE_ADDRESS to POINTER_PLUS_EXPR of &D.2456 and _11 * 4, while the code in vect_find_stmt_data_reference expected that _11 * 4 to be in DR_OFFSET instead; furthermore there is the unsigned int -> sizetype promotion that wasn't recognized either, but it is just fine too.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk. 2019-06-21 Jakub Jelinek <ja...@redhat.com> * tree-vect-data-refs.c (vect_find_stmt_data_reference): Handle even zero DR_OFFSET, but DR_BASE_ADDRESS of POINTER_PLUS_EXPR containing the offset as possible simd lane access. Look through widening conversion. Move the TREE_CODE (DR_INIT (newdr)) == INTEGER_CST test earlier and reindent. * g++.dg/vect/simd-2.cc: Don't xfail, instead expect vectorization on x86. * g++.dg/vect/simd-5.cc: Likewise. --- gcc/tree-vect-data-refs.c.jj 2019-06-21 08:47:04.171673314 +0200 +++ gcc/tree-vect-data-refs.c 2019-06-21 21:03:15.592941224 +0200 @@ -4072,10 +4072,18 @@ vect_find_stmt_data_reference (loop_p lo && DR_OFFSET (newdr) && DR_INIT (newdr) && DR_STEP (newdr) + && TREE_CODE (DR_INIT (newdr)) == INTEGER_CST && integer_zerop (DR_STEP (newdr))) { + tree base_address = DR_BASE_ADDRESS (newdr); tree off = DR_OFFSET (newdr); tree step = ssize_int (1); + if (integer_zerop (off) + && TREE_CODE (base_address) == POINTER_PLUS_EXPR) + { + off = TREE_OPERAND (base_address, 1); + base_address = TREE_OPERAND (base_address, 0); + } STRIP_NOPS (off); if (TREE_CODE (off) == MULT_EXPR && tree_fits_uhwi_p (TREE_OPERAND (off, 1))) @@ -4084,39 +4092,47 @@ vect_find_stmt_data_reference (loop_p lo off = TREE_OPERAND (off, 0); STRIP_NOPS (off); } - if (TREE_CODE (DR_INIT (newdr)) == INTEGER_CST) + if (CONVERT_EXPR_P (off) + && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (off, 0))) + < TYPE_PRECISION (TREE_TYPE (off)))) + off = TREE_OPERAND (off, 0); + if (TREE_CODE (off) == SSA_NAME) { - if (CONVERT_EXPR_P (off) - && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (off, 0))) - < TYPE_PRECISION (TREE_TYPE (off)))) - off = TREE_OPERAND (off, 0); - if (TREE_CODE (off) == SSA_NAME) + gimple *def = SSA_NAME_DEF_STMT (off); + /* Look through widening conversion. */ + if (is_gimple_assign (def) + && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def))) + { + tree rhs1 = gimple_assign_rhs1 (def); + if (TREE_CODE (rhs1) == SSA_NAME + && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)) + && (TYPE_PRECISION (TREE_TYPE (off)) + > TYPE_PRECISION (TREE_TYPE (rhs1)))) + def = SSA_NAME_DEF_STMT (rhs1); + } + if (is_gimple_call (def) + && gimple_call_internal_p (def) + && (gimple_call_internal_fn (def) == IFN_GOMP_SIMD_LANE)) { - gimple *def = SSA_NAME_DEF_STMT (off); + tree arg = gimple_call_arg (def, 0); tree reft = TREE_TYPE (DR_REF (newdr)); - if (is_gimple_call (def) - && gimple_call_internal_p (def) - && (gimple_call_internal_fn (def) == IFN_GOMP_SIMD_LANE)) + gcc_assert (TREE_CODE (arg) == SSA_NAME); + arg = SSA_NAME_VAR (arg); + if (arg == loop->simduid + /* For now. */ + && tree_int_cst_equal (TYPE_SIZE_UNIT (reft), step)) { - tree arg = gimple_call_arg (def, 0); - gcc_assert (TREE_CODE (arg) == SSA_NAME); - arg = SSA_NAME_VAR (arg); - if (arg == loop->simduid - /* For now. */ - && tree_int_cst_equal (TYPE_SIZE_UNIT (reft), step)) - { - DR_OFFSET (newdr) = ssize_int (0); - DR_STEP (newdr) = step; - DR_OFFSET_ALIGNMENT (newdr) = BIGGEST_ALIGNMENT; - DR_STEP_ALIGNMENT (newdr) - = highest_pow2_factor (step); - /* Mark as simd-lane access. */ - tree arg2 = gimple_call_arg (def, 1); - newdr->aux = (void *) (-1 - tree_to_uhwi (arg2)); - free_data_ref (dr); - datarefs->safe_push (newdr); - return opt_result::success (); - } + DR_BASE_ADDRESS (newdr) = base_address; + DR_OFFSET (newdr) = ssize_int (0); + DR_STEP (newdr) = step; + DR_OFFSET_ALIGNMENT (newdr) = BIGGEST_ALIGNMENT; + DR_STEP_ALIGNMENT (newdr) = highest_pow2_factor (step); + /* Mark as simd-lane access. */ + tree arg2 = gimple_call_arg (def, 1); + newdr->aux = (void *) (-1 - tree_to_uhwi (arg2)); + free_data_ref (dr); + datarefs->safe_push (newdr); + return opt_result::success (); } } } --- gcc/testsuite/g++.dg/vect/simd-2.cc.jj 2019-06-17 23:18:53.621850057 +0200 +++ gcc/testsuite/g++.dg/vect/simd-2.cc 2019-06-21 21:05:47.290572866 +0200 @@ -1,7 +1,7 @@ // { dg-require-effective-target size32plus } // { dg-additional-options "-fopenmp-simd" } // { dg-additional-options "-mavx" { target avx_runtime } } -// { dg-final { scan-tree-dump-times "vectorized \[1-3] loops" 2 "vect" { xfail *-*-* } } } +// { dg-final { scan-tree-dump-times "vectorized \[1-3] loops" 2 "vect" { target i?86-*-* x86_64-*-* } } } #include "../../gcc.dg/vect/tree-vect.h" --- gcc/testsuite/g++.dg/vect/simd-5.cc.jj 2019-06-19 10:25:08.423001090 +0200 +++ gcc/testsuite/g++.dg/vect/simd-5.cc 2019-06-21 21:06:00.755362646 +0200 @@ -1,7 +1,7 @@ // { dg-require-effective-target size32plus } // { dg-additional-options "-fopenmp-simd" } // { dg-additional-options "-mavx" { target avx_runtime } } -// { dg-final { scan-tree-dump-times "vectorized \[1-3] loops" 2 "vect" { xfail *-*-* } } } +// { dg-final { scan-tree-dump-times "vectorized \[1-3] loops" 2 "vect" { target i?86-*-* x86_64-*-* } } } #include "../../gcc.dg/vect/tree-vect.h" Jakub