From patchwork Wed Aug 17 15:27:17 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Biener X-Patchwork-Id: 110333 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]) by ozlabs.org (Postfix) with SMTP id 7A7B7B6F8C for ; Thu, 18 Aug 2011 01:27:39 +1000 (EST) Received: (qmail 4623 invoked by alias); 17 Aug 2011 15:27:36 -0000 Received: (qmail 4611 invoked by uid 22791); 17 Aug 2011 15:27:34 -0000 X-SWARE-Spam-Status: No, hits=-3.9 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from cantor2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 17 Aug 2011 15:27:19 +0000 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.221.2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id 9F5528EE65 for ; Wed, 17 Aug 2011 17:27:17 +0200 (CEST) Date: Wed, 17 Aug 2011 17:27:17 +0200 (CEST) From: Richard Guenther To: gcc-patches@gcc.gnu.org Subject: [PATCH][1/n] Make sizetype no longer sign-extended Message-ID: User-Agent: Alpine 2.00 (LNX 1167 2008-08-23) MIME-Version: 1.0 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 Of course when you work on one thing (do not force sizetype for POINTER_PLUS_EXPR) you run into that other thing you had in the works (but abandoned because it's sooo boring). Thus, here we come, the appearant (huh!?) only pre-requesites to making sizetypes no longer sign-extended (well, unsigned ones). The issue is as usual - we think of these sizetype things as twos-complement stuff (and thus are not worrying about signs), but then go on and do arbitrary (signed) precision arithmetic on them (using HOST_WIDE_INTs or double_ints) and interpret the result, especially sometimes the sign-bit. To preserve previous (albeit also questionable) behavior simply sign-extend that twos-complement quantity if we want to end up with something suitable for a signed HOST_WIDE_INT. That's certainly easier than trying to think of a way to make callers of get_inner_reference recognize that this bit_offset is a pointer-bits + log2(BITS_PER_UNITS) twos-complement thing. Joseph mentioned during the GCC Gathering that we shouldn't really do so much with bit offsets (which later are usually just divided by BITS_PER_UNIT anyway ...) and thus properly split in a BITS_PER_UNIT and a remainder. That doesn't solve the issue completely, but at least it would make issues less likely to show up. Anyway, too much for now. Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. I don't expect any issues, the patch is a noop right now (because of that sign-extension of unsigned sizetype), but I'll leave it until tomorrow for comments anyway. Thanks, Richard. 2011-08-17 Richard Guenther * expr.c (get_inner_reference): Sign-extend the constant twos-complement offset before doing arbitrary precision arithmetic on it. * tree-ssa-structalias.c (get_constraint_for_ptr_offset): Likewise. (get_constraint_for_1): Pass the offset of a MEM_REF unchanged to get_constraint_for_ptr_offset. * tree-cfg.c (verify_types_in_gimple_reference): Do not compare integer constants by pointer. Index: trunk/gcc/expr.c =================================================================== --- trunk.orig/gcc/expr.c 2011-08-17 16:28:06.000000000 +0200 +++ trunk/gcc/expr.c 2011-08-17 16:24:58.000000000 +0200 @@ -6502,12 +6502,14 @@ get_inner_reference (tree exp, HOST_WIDE /* If OFFSET is constant, see if we can return the whole thing as a constant bit position. Make sure to handle overflow during this conversion. */ - if (host_integerp (offset, 0)) + if (TREE_CODE (offset) == INTEGER_CST) { - double_int tem = double_int_lshift (tree_to_double_int (offset), - BITS_PER_UNIT == 8 - ? 3 : exact_log2 (BITS_PER_UNIT), - HOST_BITS_PER_DOUBLE_INT, true); + double_int tem = tree_to_double_int (offset); + tem = double_int_sext (tem, TYPE_PRECISION (sizetype)); + tem = double_int_lshift (tree_to_double_int (offset), + BITS_PER_UNIT == 8 + ? 3 : exact_log2 (BITS_PER_UNIT), + HOST_BITS_PER_DOUBLE_INT, true); tem = double_int_add (tem, bit_offset); if (double_int_fits_in_shwi_p (tem)) { Index: trunk/gcc/tree-cfg.c =================================================================== --- trunk.orig/gcc/tree-cfg.c 2011-08-17 14:03:15.000000000 +0200 +++ trunk/gcc/tree-cfg.c 2011-08-17 16:27:30.000000000 +0200 @@ -3030,7 +3030,8 @@ verify_types_in_gimple_reference (tree e return true; } else if (TREE_CODE (op) == SSA_NAME - && TYPE_SIZE (TREE_TYPE (expr)) != TYPE_SIZE (TREE_TYPE (op))) + && !tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (expr)), + TYPE_SIZE (TREE_TYPE (op)))) { error ("conversion of register to a different size"); debug_generic_stmt (expr); Index: trunk/gcc/tree-ssa-structalias.c =================================================================== --- trunk.orig/gcc/tree-ssa-structalias.c 2011-08-17 14:13:21.000000000 +0200 +++ trunk/gcc/tree-ssa-structalias.c 2011-08-17 16:08:25.000000000 +0200 @@ -2876,7 +2876,7 @@ get_constraint_for_ptr_offset (tree ptr, { struct constraint_expr c; unsigned int j, n; - HOST_WIDE_INT rhsunitoffset, rhsoffset; + HOST_WIDE_INT rhsoffset; /* If we do not do field-sensitive PTA adding offsets to pointers does not change the points-to solution. */ @@ -2891,15 +2891,24 @@ get_constraint_for_ptr_offset (tree ptr, solution which includes all sub-fields of all pointed-to variables of ptr. */ if (offset == NULL_TREE - || !host_integerp (offset, 0)) + || TREE_CODE (offset) != INTEGER_CST) rhsoffset = UNKNOWN_OFFSET; else { - /* Make sure the bit-offset also fits. */ - rhsunitoffset = TREE_INT_CST_LOW (offset); - rhsoffset = rhsunitoffset * BITS_PER_UNIT; - if (rhsunitoffset != rhsoffset / BITS_PER_UNIT) + /* Sign-extend the offset. */ + double_int soffset + = double_int_sext (tree_to_double_int (offset), + TYPE_PRECISION (TREE_TYPE (offset))); + if (!double_int_fits_in_shwi_p (soffset)) rhsoffset = UNKNOWN_OFFSET; + else + { + /* Make sure the bit-offset also fits. */ + HOST_WIDE_INT rhsunitoffset = soffset.low; + rhsoffset = rhsunitoffset * BITS_PER_UNIT; + if (rhsunitoffset != rhsoffset / BITS_PER_UNIT) + rhsoffset = UNKNOWN_OFFSET; + } } get_constraint_for_rhs (ptr, results); @@ -3260,8 +3269,8 @@ get_constraint_for_1 (tree t, VEC (ce_s, { struct constraint_expr cs; varinfo_t vi, curr; - tree off = convert_to_ptrofftype (TREE_OPERAND (t, 1)); - get_constraint_for_ptr_offset (TREE_OPERAND (t, 0), off, results); + get_constraint_for_ptr_offset (TREE_OPERAND (t, 0), + TREE_OPERAND (t, 1), results); do_deref (results); /* If we are not taking the address then make sure to process