This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/33301] New: wrong vectorization factor due to an invariant type-promotion in the loop
- From: "dorit at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 4 Sep 2007 12:47:22 -0000
- Subject: [Bug tree-optimization/33301] New: wrong vectorization factor due to an invariant type-promotion in the loop
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
This testcase: gfortran.dg/g77/990115-1.f
ICEs when compiled with vectorization enabled:
gfortran 990115-1.f -O -pedantic-errors -S -O2 -ftree-vectorize -msse2
-fdump-tree-vect-details -g -o 990115-1.s
990115-1.f: In function 'zgelsx':^M
990115-1.f:3: internal compiler error: in vectorizable_type_promotion, at
tree-vect-transform.c:3959
This is because of this assumption in
tree-vect-analyze.c:vect_determine_vectorization_factor:
"
/* We set the vectype according to the type of the result (lhs).
For stmts whose result-type is different than the type of the
arguments (e.g. demotion, promotion), vectype will be reset
appropriately (later). Note that we have to visit the smallest
datatype in this function, because that determines the VF.
If the smallest datatype in the loop is present only as the
rhs of a promotion operation - we'd miss it here.
However, in such a case, that a variable of this datatype
does not appear in the lhs anywhere in the loop, it shouldn't
affect the vectorization factor. */
"
It so happens that we can have a situation in which the smallest type in the
loop nevers appears in the lhs: in the above testcase we have an invariant
type-promotion stmts that is not taken out of the loop before vectorization:
<bb 4>:
# i_1 = PHI <1(3), i_17(5)>
D.1363_9 = (real8) s2_8(D); //<--- HERE
D.1361_11 = ismax_5(D) + -2;
D.1362_12 = D.1361_11 + i_1;
CR.22_27 = REALPART_EXPR <(*work_13(D))[D.1362_12]>;
CI.23_28 = IMAGPART_EXPR <(*work_13(D))[D.1362_12]>;
CR.24_29 = D.1363_9 * CR.22_27;
CI.25_30 = D.1363_9 * CI.23_28;
REALPART_EXPR <(*work_13(D))[D.1362_12]> = CR.24_29;
IMAGPART_EXPR <(*work_13(D))[D.1362_12]> = CI.25_30;
i_17 = i_1 + 1;
if (i_1 == D.1355_3)
goto <bb 6>;
else
goto <bb 5>;
(Indeed when compiling also with --param lim-expensive=1, the invariant stmt is
taken out of the loop and the testcase passes).
I am testing the following patch:
Index: tree-vect-analyze.c
===================================================================
*** tree-vect-analyze.c (revision 128037)
--- tree-vect-analyze.c (working copy)
*************** vect_determine_vectorization_factor (loo
*** 216,236 ****
}
else
{
gcc_assert (! STMT_VINFO_DATA_REF (stmt_info)
&& !is_pattern_stmt_p (stmt_info));
! /* We set the vectype according to the type of the result (lhs).
For stmts whose result-type is different than the type of the
arguments (e.g. demotion, promotion), vectype will be reset
appropriately (later). Note that we have to visit the
smallest
datatype in this function, because that determines the VF.
If the smallest datatype in the loop is present only as the
rhs of a promotion operation - we'd miss it here.
! However, in such a case, that a variable of this datatype
! does not appear in the lhs anywhere in the loop, it shouldn't
! affect the vectorization factor. */
scalar_type = TREE_TYPE (GIMPLE_STMT_OPERAND (stmt, 0));
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "get vectype for scalar type: ");
--- 216,253 ----
}
else
{
+ tree operation;
+
gcc_assert (! STMT_VINFO_DATA_REF (stmt_info)
&& !is_pattern_stmt_p (stmt_info));
! /* We generally set the vectype according to the type of the
! result (lhs).
For stmts whose result-type is different than the type of the
arguments (e.g. demotion, promotion), vectype will be reset
appropriately (later). Note that we have to visit the
smallest
datatype in this function, because that determines the VF.
If the smallest datatype in the loop is present only as the
rhs of a promotion operation - we'd miss it here.
! Such a case, where a variable of this datatype does not appear
! in the lhs anywhere in the loop, can only occur if it's an
! invariant: e.g.: 'int_x = (int) short_inv', which we'd expect
! to have been optimized away by invariant motion. However, we
! cannot rely on invariant motion to always take invariants out
! of the loop, and so in the case of promotion we also have to
! check the rhs. */
scalar_type = TREE_TYPE (GIMPLE_STMT_OPERAND (stmt, 0));
+ operation = GIMPLE_STMT_OPERAND (stmt, 1);
+ if (TREE_CODE (operation) == NOP_EXPR
+ || TREE_CODE (operation) == CONVERT_EXPR
+ || TREE_CODE (operation) == WIDEN_MULT_EXPR)
+ {
+ tree rhs_type = TREE_TYPE (TREE_OPERAND (operation, 0));
+ if (TYPE_SIZE_UNIT (rhs_type) < TYPE_SIZE_UNIT (scalar_type))
+ scalar_type = TREE_TYPE (TREE_OPERAND (operation, 0));
+ }
+
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "get vectype for scalar type: ");
--
Summary: wrong vectorization factor due to an invariant type-
promotion in the loop
Product: gcc
Version: 4.3.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
AssignedTo: dorit at gcc dot gnu dot org
ReportedBy: dorit at gcc dot gnu dot org
GCC build triplet: i386-linux
GCC host triplet: i386-linux
GCC target triplet: i386-linux
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33301