From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11961 invoked by alias); 4 Sep 2007 12:47:50 -0000 Received: (qmail 11872 invoked by uid 48); 4 Sep 2007 12:47:22 -0000 Date: Tue, 04 Sep 2007 12:47:00 -0000 Subject: [Bug tree-optimization/33301] New: wrong vectorization factor due to an invariant type-promotion in the loop X-Bugzilla-Reason: CC Message-ID: Reply-To: gcc-bugzilla@gcc.gnu.org To: gcc-bugs@gcc.gnu.org From: "dorit at gcc dot gnu dot org" Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2007-09/txt/msg00246.txt.bz2 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: : # 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 ; else goto ; (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