From patchwork Fri Jul 12 22:13:53 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cong Hou X-Patchwork-Id: 258813 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 2651F2C0371 for ; Sat, 13 Jul 2013 08:14:09 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:date:message-id:subject:from:to:cc:content-type; q=dns; s=default; b=JDKEFz4uc2Uc/Yz812GFp8HKhd1uhy9/qC9CFeCM2y1 xUDiPpWrjhOM2DDNp+7owyrSapG0Kv0JZ6apbcGK6huvY0gbOFcuqMDlGT2yWklb vH9ZebuqOgb8qYLF9GVWjtl6A6l45w+g9/PBhK9uPFq0T2vodYBlTAPoZilWLi6M = DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:date:message-id:subject:from:to:cc:content-type; s=default; bh=fDcYeJ8D0zTB6fbARjxONekpHKg=; b=IQ7qGGeYFfnPfTfdn j/GpjZdhk0t1Ezp0YxHGk7XX6rFdgYRopch8XeYz81CZs4MQu2Qk5ybpdwPRZ3TF WG6EhkDGV/4aaLQZ8vg9RwYVeaNKW65l0Kd7joAyYMr8C4ylbcbvejHy0zDdf9DK FYcBhy1gEivR4yGLKmT0+8klu4= Received: (qmail 19550 invoked by alias); 12 Jul 2013 22:14:02 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 19541 invoked by uid 89); 12 Jul 2013 22:14:02 -0000 X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00, RCVD_IN_HOSTKARMA_YE, RDNS_NONE, SPF_PASS, TW_DR, TW_TM autolearn=no version=3.3.1 Received: from Unknown (HELO mail-ie0-f181.google.com) (209.85.223.181) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Fri, 12 Jul 2013 22:14:00 +0000 Received: by mail-ie0-f181.google.com with SMTP id x12so20573529ief.26 for ; Fri, 12 Jul 2013 15:13:53 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=mime-version:date:message-id:subject:from:to:cc:content-type :x-gm-message-state; bh=8qyXloLXPsox+pilxZwAeE09r5DEp/7ZjNAI9t1o2VA=; b=fRwbF6epp3m50X+f1ihwvdBbTv+mN0O8LBLUawNs9QAK4WPdL3vLjFjkAViqCVvH5Q CIg8JYmxOqcM4eeKQapJKfeOVKSLq12i6mk8mJYtuUi3zGcq8cx6yFp8WDuPB2tb8zkH I7Jz6tRelZ/RzlmxDRbceUGK+ik0VoxljYOAYP3ZTkg2C5NFmUVBo/xzTlV4xlQGPGeh MVAE1KGd8Tj4pWalWOCR51mO9nxqL6SqGKHzEHaBVfFwVXasUZ4YxZJe/jul+JX1xK1I 4Jx0c5E0/o5rrqOgg+2kyAh17kEZ+oe0iKe9nt0YpBrACDC7xakD8EyyFCuwQja888zB +4ww== MIME-Version: 1.0 X-Received: by 10.50.153.4 with SMTP id vc4mr1592051igb.23.1373667233271; Fri, 12 Jul 2013 15:13:53 -0700 (PDT) Received: by 10.231.51.194 with HTTP; Fri, 12 Jul 2013 15:13:53 -0700 (PDT) Date: Fri, 12 Jul 2013 15:13:53 -0700 Message-ID: Subject: Fix GCC bug causing bootstrap failure with vectorizer turned on From: Cong Hou To: gcc-patches@gcc.gnu.org Cc: David Li X-Gm-Message-State: ALoCoQltS1veaO/nAcI2C4P/xCXiGFjjQxSGVm6sAgaMbpI4hxIEEll+py/EOZcyyEqohSZBQqa5+QxnH5tjCk4sk3+p+ZFZrDFltsQ6zI08vJzLunTGu0V7rAlDOafQ+AqC4jqXE9yghDDzqeVh0uRndfvS5vepqs1JJ0PLKuXwd6hf5Ob+J9U3C1CZJh1o9+NwuZoKMlSpQf/X4TYvbe5+Vq8gZBVLeg== X-Virus-Found: No GCC bootstrap failed with loop vectorizer turned on by default at O2. The symptom is that the comparison between stage2&3 compilers fails. The root cause is a bug in the file "tree-vect-data-refs.c", where a qsort() function call is used to sort a group of data references using a comparison function called "dr_group_sort_cmp()". In this function, the iterative hash values of tree nodes are used for comparisons. For a declaration tree node, its UID participates in the calculation of the hash value. However, a specific declaration may have different UIDs whether the debug information is switched on/off (-gtoggle). In consequence, the results of comparisons may vary in stage 2&3 during bootstrapping. The following patch fixed the bug. Compiler bootstraps and there is no regressions in regression test. Compiler also bootstraps fine when turning on vectorizer by default. Since this patch may produce difference result (but still correct) than before due to the modification to the comparison function, four test cases are adjusted accordingly. OK for trunk? Cong stmt UID. */ Index: gcc/testsuite/gcc.target/i386/l_fma_double_1.c =================================================================== --- gcc/testsuite/gcc.target/i386/l_fma_double_1.c (revision 200893) +++ gcc/testsuite/gcc.target/i386/l_fma_double_1.c (working copy) @@ -10,9 +10,9 @@ #include "l_fma_1.h" /* { dg-final { scan-assembler-times "vfmadd132pd" 4 } } */ -/* { dg-final { scan-assembler-times "vfmadd213pd" 4 } } */ +/* { dg-final { scan-assembler-times "vfmadd231pd" 4 } } */ /* { dg-final { scan-assembler-times "vfmsub132pd" 4 } } */ -/* { dg-final { scan-assembler-times "vfmsub213pd" 4 } } */ +/* { dg-final { scan-assembler-times "vfmsub231pd" 4 } } */ /* { dg-final { scan-assembler-times "vfnmadd132pd" 4 } } */ /* { dg-final { scan-assembler-times "vfnmadd231pd" 4 } } */ /* { dg-final { scan-assembler-times "vfnmsub132pd" 4 } } */ Index: gcc/testsuite/gcc.target/i386/l_fma_float_1.c =================================================================== --- gcc/testsuite/gcc.target/i386/l_fma_float_1.c (revision 200893) +++ gcc/testsuite/gcc.target/i386/l_fma_float_1.c (working copy) @@ -9,9 +9,9 @@ #include "l_fma_1.h" /* { dg-final { scan-assembler-times "vfmadd132ps" 4 } } */ -/* { dg-final { scan-assembler-times "vfmadd213ps" 4 } } */ +/* { dg-final { scan-assembler-times "vfmadd231ps" 4 } } */ /* { dg-final { scan-assembler-times "vfmsub132ps" 4 } } */ -/* { dg-final { scan-assembler-times "vfmsub213ps" 4 } } */ +/* { dg-final { scan-assembler-times "vfmsub231ps" 4 } } */ /* { dg-final { scan-assembler-times "vfnmadd132ps" 4 } } */ /* { dg-final { scan-assembler-times "vfnmadd231ps" 4 } } */ /* { dg-final { scan-assembler-times "vfnmsub132ps" 4 } } */ Index: gcc/testsuite/gcc.target/i386/l_fma_double_3.c =================================================================== --- gcc/testsuite/gcc.target/i386/l_fma_double_3.c (revision 200893) +++ gcc/testsuite/gcc.target/i386/l_fma_double_3.c (working copy) @@ -10,9 +10,9 @@ #include "l_fma_3.h" /* { dg-final { scan-assembler-times "vfmadd132pd" 4 } } */ -/* { dg-final { scan-assembler-times "vfmadd213pd" 4 } } */ +/* { dg-final { scan-assembler-times "vfmadd231pd" 4 } } */ /* { dg-final { scan-assembler-times "vfmsub132pd" 4 } } */ -/* { dg-final { scan-assembler-times "vfmsub213pd" 4 } } */ +/* { dg-final { scan-assembler-times "vfmsub231pd" 4 } } */ /* { dg-final { scan-assembler-times "vfnmadd132pd" 4 } } */ /* { dg-final { scan-assembler-times "vfnmadd231pd" 4 } } */ /* { dg-final { scan-assembler-times "vfnmsub132pd" 4 } } */ Index: gcc/testsuite/gcc.target/i386/l_fma_float_3.c =================================================================== --- gcc/testsuite/gcc.target/i386/l_fma_float_3.c (revision 200893) +++ gcc/testsuite/gcc.target/i386/l_fma_float_3.c (working copy) @@ -9,9 +9,9 @@ #include "l_fma_3.h" /* { dg-final { scan-assembler-times "vfmadd132ps" 4 } } */ -/* { dg-final { scan-assembler-times "vfmadd213ps" 4 } } */ +/* { dg-final { scan-assembler-times "vfmadd231ps" 4 } } */ /* { dg-final { scan-assembler-times "vfmsub132ps" 4 } } */ -/* { dg-final { scan-assembler-times "vfmsub213ps" 4 } } */ +/* { dg-final { scan-assembler-times "vfmsub231ps" 4 } } */ /* { dg-final { scan-assembler-times "vfnmadd132ps" 4 } } */ /* { dg-final { scan-assembler-times "vfnmadd231ps" 4 } } */ /* { dg-final { scan-assembler-times "vfnmsub132ps" 4 } } */ Index: gcc/tree-vect-data-refs.c =================================================================== --- gcc/tree-vect-data-refs.c (revision 200893) +++ gcc/tree-vect-data-refs.c (working copy) @@ -2311,6 +2311,80 @@ return vect_analyze_group_access (dr); } + + +/* Compare two tree nodes. This function is used to compare two + data-references as below. */ + +static int +compare_tree (tree t1, tree t2) +{ + int i, cmp; + enum tree_code code; + char tclass; + + if (t1 == t2) + return 0; + if (t1 == NULL) + return -1; + if (t2 == NULL) + return 1; + + + if (TREE_CODE (t1) != TREE_CODE (t2)) + return TREE_CODE (t1) < TREE_CODE (t2) ? -1 : 1; + + code = TREE_CODE (t1); + switch (code) + { + /* For const values, we can just use hash values for comparisons. */ + case INTEGER_CST: + case REAL_CST: + case FIXED_CST: + case STRING_CST: + case COMPLEX_CST: + case VECTOR_CST: + { + hashval_t h1 = iterative_hash_expr (t1, 0); + hashval_t h2 = iterative_hash_expr (t2, 0); + if (h1 != h2) + return h1 < h2 ? -1 : 1; + break; + } + + case SSA_NAME: + cmp = compare_tree (SSA_NAME_VAR (t1), SSA_NAME_VAR (t2)); + if (cmp != 0) + return cmp; + + if (SSA_NAME_VERSION (t1) != SSA_NAME_VERSION (t2)) + return SSA_NAME_VERSION (t1) < SSA_NAME_VERSION (t2) ? -1 : 1; + break; + + default: + tclass = TREE_CODE_CLASS (code); + + /* For var-decl, we could compare their UIDs. */ + if (tclass == tcc_declaration) + { + if (DECL_UID (t1) != DECL_UID (t2)) + return DECL_UID (t1) < DECL_UID (t2) ? -1 : 1; + break; + } + + /* For expressions with operands, compare their operands recursively. */ + for (i = TREE_OPERAND_LENGTH (t1) - 1; i >= 0; --i) + { + cmp = compare_tree (TREE_OPERAND (t1, i), TREE_OPERAND (t2, i)); + if (cmp != 0) + return cmp; + } + } + + return 0; +} + + /* Compare two data-references DRA and DRB to group them into chunks suitable for grouping. */ @@ -2319,7 +2393,6 @@ { data_reference_p dra = *(data_reference_p *)const_cast(dra_); data_reference_p drb = *(data_reference_p *)const_cast(drb_); - hashval_t h1, h2; int cmp; /* Stabilize sort. */ @@ -2329,19 +2402,17 @@ /* Ordering of DRs according to base. */ if (!operand_equal_p (DR_BASE_ADDRESS (dra), DR_BASE_ADDRESS (drb), 0)) { - h1 = iterative_hash_expr (DR_BASE_ADDRESS (dra), 0); - h2 = iterative_hash_expr (DR_BASE_ADDRESS (drb), 0); - if (h1 != h2) - return h1 < h2 ? -1 : 1; + cmp = compare_tree (DR_BASE_ADDRESS (dra), DR_BASE_ADDRESS (drb)); + if (cmp != 0) + return cmp; } /* And according to DR_OFFSET. */ if (!dr_equal_offsets_p (dra, drb)) { - h1 = iterative_hash_expr (DR_OFFSET (dra), 0); - h2 = iterative_hash_expr (DR_OFFSET (drb), 0); - if (h1 != h2) - return h1 < h2 ? -1 : 1; + cmp = compare_tree (DR_OFFSET (dra), DR_OFFSET (drb)); + if (cmp != 0) + return cmp; } /* Put reads before writes. */ @@ -2352,19 +2423,18 @@ if (!operand_equal_p (TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dra))), TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (drb))), 0)) { - h1 = iterative_hash_expr (TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dra))), 0); - h2 = iterative_hash_expr (TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (drb))), 0); - if (h1 != h2) - return h1 < h2 ? -1 : 1; + cmp = compare_tree (TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dra))), + TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (drb)))); + if (cmp != 0) + return cmp; } /* And after step. */ if (!operand_equal_p (DR_STEP (dra), DR_STEP (drb), 0)) { - h1 = iterative_hash_expr (DR_STEP (dra), 0); - h2 = iterative_hash_expr (DR_STEP (drb), 0); - if (h1 != h2) - return h1 < h2 ? -1 : 1; + cmp = compare_tree (DR_STEP (dra), DR_STEP (drb)); + if (cmp != 0) + return cmp; } /* Then sort after DR_INIT. In case of identical DRs sort after