This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug tree-optimization/33301] New: wrong vectorization factor due to an invariant type-promotion in the loop


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]