From patchwork Thu Aug 5 22:18:56 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 61054 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 0A1A5B70A7 for ; Fri, 6 Aug 2010 08:19:18 +1000 (EST) Received: (qmail 16203 invoked by alias); 5 Aug 2010 22:19:15 -0000 Received: (qmail 16190 invoked by uid 22791); 5 Aug 2010 22:19:13 -0000 X-SWARE-Spam-Status: No, hits=-1.6 required=5.0 tests=AWL, BAYES_00, KAM_ADVERT2 X-Spam-Check-By: sourceware.org Received: from mel.act-europe.fr (HELO mel.act-europe.fr) (212.99.106.210) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 05 Aug 2010 22:19:07 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id AE286CB020C; Fri, 6 Aug 2010 00:19:04 +0200 (CEST) Received: from mel.act-europe.fr ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id QqDdW-RR3MMV; Fri, 6 Aug 2010 00:19:04 +0200 (CEST) Received: from adijon-256-1-59-59.w81-51.abo.wanadoo.fr (ADijon-256-1-59-59.w81-51.abo.wanadoo.fr [81.51.194.59]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mel.act-europe.fr (Postfix) with ESMTP id 6FAB6CB01D7; Fri, 6 Aug 2010 00:19:03 +0200 (CEST) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: Re: some integer undefined behaviors in gcc Date: Fri, 6 Aug 2010 00:18:56 +0200 User-Agent: KMail/1.9.9 Cc: John Regehr References: <4C58A5E8.4040108@cs.utah.edu> <201008042242.24773.ebotcazou@adacore.com> In-Reply-To: <201008042242.24773.ebotcazou@adacore.com> MIME-Version: 1.0 Message-Id: <201008060018.57171.ebotcazou@adacore.com> 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 > * rtlanal.c (nonzero_bits1): Use unsigned HOST_WIDE_INT in all mask > computations. Fix formatting issues. Here is what I've commited. Tested on i586-suse-linux. 2010-08-05 Eric Botcazou * rtlanal.c (nonzero_bits1): Use unsigned HOST_WIDE_INT in all mask computations. Fix formatting issues. (num_sign_bit_copies1): Likewise. (canonicalize_condition): Likewise. Index: rtlanal.c =================================================================== --- rtlanal.c (revision 162897) +++ rtlanal.c (working copy) @@ -3802,12 +3802,14 @@ nonzero_bits1 (const_rtx x, enum machine case CONST_INT: #ifdef SHORT_IMMEDIATES_SIGN_EXTEND /* If X is negative in MODE, sign-extend the value. */ - if (INTVAL (x) > 0 && mode_width < BITS_PER_WORD - && 0 != (INTVAL (x) & ((HOST_WIDE_INT) 1 << (mode_width - 1)))) - return (INTVAL (x) | ((HOST_WIDE_INT) (-1) << mode_width)); + if (INTVAL (x) > 0 + && mode_width < BITS_PER_WORD + && (UINTVAL (x) & ((unsigned HOST_WIDE_INT) 1 << (mode_width - 1))) + != 0) + return UINTVAL (x) | ((unsigned HOST_WIDE_INT) (-1) << mode_width); #endif - return INTVAL (x); + return UINTVAL (x); case MEM: #ifdef LOAD_EXTEND_OP @@ -3884,7 +3886,7 @@ nonzero_bits1 (const_rtx x, enum machine { inner_nz &= GET_MODE_MASK (GET_MODE (XEXP (x, 0))); if (inner_nz - & (((HOST_WIDE_INT) 1 + & (((unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) - 1)))) inner_nz |= (GET_MODE_MASK (mode) & ~GET_MODE_MASK (GET_MODE (XEXP (x, 0)))); @@ -3903,9 +3905,9 @@ nonzero_bits1 (const_rtx x, enum machine case XOR: case IOR: case UMIN: case UMAX: case SMIN: case SMAX: { - unsigned HOST_WIDE_INT nonzero0 = - cached_nonzero_bits (XEXP (x, 0), mode, - known_x, known_mode, known_ret); + unsigned HOST_WIDE_INT nonzero0 + = cached_nonzero_bits (XEXP (x, 0), mode, + known_x, known_mode, known_ret); /* Don't call nonzero_bits for the second time if it cannot change anything. */ @@ -3925,21 +3927,21 @@ nonzero_bits1 (const_rtx x, enum machine computing the width (position of the highest-order nonzero bit) and the number of low-order zero bits for each value. */ { - unsigned HOST_WIDE_INT nz0 = - cached_nonzero_bits (XEXP (x, 0), mode, - known_x, known_mode, known_ret); - unsigned HOST_WIDE_INT nz1 = - cached_nonzero_bits (XEXP (x, 1), mode, - known_x, known_mode, known_ret); + unsigned HOST_WIDE_INT nz0 + = cached_nonzero_bits (XEXP (x, 0), mode, + known_x, known_mode, known_ret); + unsigned HOST_WIDE_INT nz1 + = cached_nonzero_bits (XEXP (x, 1), mode, + known_x, known_mode, known_ret); int sign_index = GET_MODE_BITSIZE (GET_MODE (x)) - 1; int width0 = floor_log2 (nz0) + 1; int width1 = floor_log2 (nz1) + 1; int low0 = floor_log2 (nz0 & -nz0); int low1 = floor_log2 (nz1 & -nz1); - HOST_WIDE_INT op0_maybe_minusp - = (nz0 & ((HOST_WIDE_INT) 1 << sign_index)); - HOST_WIDE_INT op1_maybe_minusp - = (nz1 & ((HOST_WIDE_INT) 1 << sign_index)); + unsigned HOST_WIDE_INT op0_maybe_minusp + = nz0 & ((unsigned HOST_WIDE_INT) 1 << sign_index); + unsigned HOST_WIDE_INT op1_maybe_minusp + = nz1 & ((unsigned HOST_WIDE_INT) 1 << sign_index); unsigned int result_width = mode_width; int result_low = 0; @@ -3959,7 +3961,7 @@ nonzero_bits1 (const_rtx x, enum machine case DIV: if (width1 == 0) break; - if (! op0_maybe_minusp && ! op1_maybe_minusp) + if (!op0_maybe_minusp && !op1_maybe_minusp) result_width = width0; break; case UDIV: @@ -3970,7 +3972,7 @@ nonzero_bits1 (const_rtx x, enum machine case MOD: if (width1 == 0) break; - if (! op0_maybe_minusp && ! op1_maybe_minusp) + if (!op0_maybe_minusp && !op1_maybe_minusp) result_width = MIN (width0, width1); result_low = MIN (low0, low1); break; @@ -3985,10 +3987,10 @@ nonzero_bits1 (const_rtx x, enum machine } if (result_width < mode_width) - nonzero &= ((HOST_WIDE_INT) 1 << result_width) - 1; + nonzero &= ((unsigned HOST_WIDE_INT) 1 << result_width) - 1; if (result_low > 0) - nonzero &= ~(((HOST_WIDE_INT) 1 << result_low) - 1); + nonzero &= ~(((unsigned HOST_WIDE_INT) 1 << result_low) - 1); #ifdef POINTERS_EXTEND_UNSIGNED /* If pointers extend unsigned and this is an addition or subtraction @@ -4009,7 +4011,7 @@ nonzero_bits1 (const_rtx x, enum machine case ZERO_EXTRACT: if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT) - nonzero &= ((HOST_WIDE_INT) 1 << INTVAL (XEXP (x, 1))) - 1; + nonzero &= ((unsigned HOST_WIDE_INT) 1 << INTVAL (XEXP (x, 1))) - 1; break; case SUBREG: @@ -4074,9 +4076,9 @@ nonzero_bits1 (const_rtx x, enum machine unsigned int width = GET_MODE_BITSIZE (inner_mode); int count = INTVAL (XEXP (x, 1)); unsigned HOST_WIDE_INT mode_mask = GET_MODE_MASK (inner_mode); - unsigned HOST_WIDE_INT op_nonzero = - cached_nonzero_bits (XEXP (x, 0), mode, - known_x, known_mode, known_ret); + unsigned HOST_WIDE_INT op_nonzero + = cached_nonzero_bits (XEXP (x, 0), mode, + known_x, known_mode, known_ret); unsigned HOST_WIDE_INT inner = op_nonzero & mode_mask; unsigned HOST_WIDE_INT outer = 0; @@ -4092,8 +4094,9 @@ nonzero_bits1 (const_rtx x, enum machine /* If the sign bit may have been nonzero before the shift, we need to mark all the places it could have been copied to by the shift as possibly nonzero. */ - if (inner & ((HOST_WIDE_INT) 1 << (width - 1 - count))) - inner |= (((HOST_WIDE_INT) 1 << count) - 1) << (width - count); + if (inner & ((unsigned HOST_WIDE_INT) 1 << (width - 1 - count))) + inner |= (((unsigned HOST_WIDE_INT) 1 << count) - 1) + << (width - count); } else if (code == ASHIFT) inner <<= count; @@ -4108,14 +4111,15 @@ nonzero_bits1 (const_rtx x, enum machine case FFS: case POPCOUNT: /* This is at most the number of bits in the mode. */ - nonzero = ((HOST_WIDE_INT) 2 << (floor_log2 (mode_width))) - 1; + nonzero = ((unsigned HOST_WIDE_INT) 2 << (floor_log2 (mode_width))) - 1; break; case CLZ: /* If CLZ has a known value at zero, then the nonzero bits are that value, plus the number of bits in the mode minus one. */ if (CLZ_DEFINED_VALUE_AT_ZERO (mode, nonzero)) - nonzero |= ((HOST_WIDE_INT) 1 << (floor_log2 (mode_width))) - 1; + nonzero + |= ((unsigned HOST_WIDE_INT) 1 << (floor_log2 (mode_width))) - 1; else nonzero = -1; break; @@ -4124,7 +4128,8 @@ nonzero_bits1 (const_rtx x, enum machine /* If CTZ has a known value at zero, then the nonzero bits are that value, plus the number of bits in the mode minus one. */ if (CTZ_DEFINED_VALUE_AT_ZERO (mode, nonzero)) - nonzero |= ((HOST_WIDE_INT) 1 << (floor_log2 (mode_width))) - 1; + nonzero + |= ((unsigned HOST_WIDE_INT) 1 << (floor_log2 (mode_width))) - 1; else nonzero = -1; break; @@ -4135,9 +4140,9 @@ nonzero_bits1 (const_rtx x, enum machine case IF_THEN_ELSE: { - unsigned HOST_WIDE_INT nonzero_true = - cached_nonzero_bits (XEXP (x, 1), mode, - known_x, known_mode, known_ret); + unsigned HOST_WIDE_INT nonzero_true + = cached_nonzero_bits (XEXP (x, 1), mode, + known_x, known_mode, known_ret); /* Don't call nonzero_bits for the second time if it cannot change anything. */ @@ -4310,9 +4315,9 @@ num_sign_bit_copies1 (const_rtx x, enum case CONST_INT: /* If the constant is negative, take its 1's complement and remask. Then see how many zero bits we have. */ - nonzero = INTVAL (x) & GET_MODE_MASK (mode); + nonzero = UINTVAL (x) & GET_MODE_MASK (mode); if (bitwidth <= HOST_BITS_PER_WIDE_INT - && (nonzero & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0) + && (nonzero & ((unsigned HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0) nonzero = (~nonzero) & GET_MODE_MASK (mode); return (nonzero == 0 ? bitwidth : bitwidth - floor_log2 (nonzero) - 1); @@ -4414,7 +4419,7 @@ num_sign_bit_copies1 (const_rtx x, enum return bitwidth; if (num0 > 1 - && (((HOST_WIDE_INT) 1 << (bitwidth - 1)) & nonzero)) + && (((unsigned HOST_WIDE_INT) 1 << (bitwidth - 1)) & nonzero)) num0--; return num0; @@ -4435,7 +4440,8 @@ num_sign_bit_copies1 (const_rtx x, enum && num1 > 1 && bitwidth <= HOST_BITS_PER_WIDE_INT && CONST_INT_P (XEXP (x, 1)) - && !(INTVAL (XEXP (x, 1)) & ((HOST_WIDE_INT) 1 << (bitwidth - 1)))) + && (UINTVAL (XEXP (x, 1)) + & ((unsigned HOST_WIDE_INT) 1 << (bitwidth - 1))) == 0) return num1; /* Similarly for IOR when setting high-order bits. */ @@ -4443,7 +4449,8 @@ num_sign_bit_copies1 (const_rtx x, enum && num1 > 1 && bitwidth <= HOST_BITS_PER_WIDE_INT && CONST_INT_P (XEXP (x, 1)) - && (INTVAL (XEXP (x, 1)) & ((HOST_WIDE_INT) 1 << (bitwidth - 1)))) + && (UINTVAL (XEXP (x, 1)) + & ((unsigned HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0) return num1; return MIN (num0, num1); @@ -4458,7 +4465,7 @@ num_sign_bit_copies1 (const_rtx x, enum && bitwidth <= HOST_BITS_PER_WIDE_INT) { nonzero = nonzero_bits (XEXP (x, 0), mode); - if ((((HOST_WIDE_INT) 1 << (bitwidth - 1)) & nonzero) == 0) + if ((((unsigned HOST_WIDE_INT) 1 << (bitwidth - 1)) & nonzero) == 0) return (nonzero == 1 || nonzero == 0 ? bitwidth : bitwidth - floor_log2 (nonzero) - 1); } @@ -4501,9 +4508,10 @@ num_sign_bit_copies1 (const_rtx x, enum if (result > 0 && (bitwidth > HOST_BITS_PER_WIDE_INT || (((nonzero_bits (XEXP (x, 0), mode) - & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0) + & ((unsigned HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0) && ((nonzero_bits (XEXP (x, 1), mode) - & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)))) + & ((unsigned HOST_WIDE_INT) 1 << (bitwidth - 1))) + != 0)))) result--; return MAX (1, result); @@ -4515,7 +4523,7 @@ num_sign_bit_copies1 (const_rtx x, enum if (bitwidth > HOST_BITS_PER_WIDE_INT) return 1; else if ((nonzero_bits (XEXP (x, 0), mode) - & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0) + & ((unsigned HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0) return 1; else return cached_num_sign_bit_copies (XEXP (x, 0), mode, @@ -4528,7 +4536,7 @@ num_sign_bit_copies1 (const_rtx x, enum if (bitwidth > HOST_BITS_PER_WIDE_INT) return 1; else if ((nonzero_bits (XEXP (x, 1), mode) - & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0) + & ((unsigned HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0) return 1; else return cached_num_sign_bit_copies (XEXP (x, 1), mode, @@ -4543,7 +4551,7 @@ num_sign_bit_copies1 (const_rtx x, enum if (result > 1 && (bitwidth > HOST_BITS_PER_WIDE_INT || (nonzero_bits (XEXP (x, 1), mode) - & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)) + & ((unsigned HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)) result--; return result; @@ -4554,7 +4562,7 @@ num_sign_bit_copies1 (const_rtx x, enum if (result > 1 && (bitwidth > HOST_BITS_PER_WIDE_INT || (nonzero_bits (XEXP (x, 1), mode) - & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)) + & ((unsigned HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)) result--; return result; @@ -4598,7 +4606,7 @@ num_sign_bit_copies1 (const_rtx x, enum Then see how many zero bits we have. */ nonzero = STORE_FLAG_VALUE; if (bitwidth <= HOST_BITS_PER_WIDE_INT - && (nonzero & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0) + && (nonzero & ((unsigned HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0) nonzero = (~nonzero) & GET_MODE_MASK (mode); return (nonzero == 0 ? bitwidth : bitwidth - floor_log2 (nonzero) - 1); @@ -4617,7 +4625,7 @@ num_sign_bit_copies1 (const_rtx x, enum return 1; nonzero = nonzero_bits (x, mode); - return nonzero & ((HOST_WIDE_INT) 1 << (bitwidth - 1)) + return nonzero & ((unsigned HOST_WIDE_INT) 1 << (bitwidth - 1)) ? 1 : bitwidth - floor_log2 (nonzero) - 1; } @@ -4803,7 +4811,7 @@ canonicalize_condition (rtx insn, rtx co && (GET_MODE_BITSIZE (inner_mode) <= HOST_BITS_PER_WIDE_INT) && (STORE_FLAG_VALUE - & ((HOST_WIDE_INT) 1 + & ((unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (inner_mode) - 1)))) #ifdef FLOAT_STORE_FLAG_VALUE || (code == LT @@ -4823,7 +4831,7 @@ canonicalize_condition (rtx insn, rtx co <= HOST_BITS_PER_WIDE_INT) && GET_MODE_CLASS (inner_mode) == MODE_INT && (STORE_FLAG_VALUE - & ((HOST_WIDE_INT) 1 + & ((unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (inner_mode) - 1)))) #ifdef FLOAT_STORE_FLAG_VALUE || (code == GE @@ -4906,9 +4914,9 @@ canonicalize_condition (rtx insn, rtx co /* When cross-compiling, const_val might be sign-extended from BITS_PER_WORD to HOST_BITS_PER_WIDE_INT */ case GE: - if ((HOST_WIDE_INT) (const_val & max_val) - != (((HOST_WIDE_INT) 1 - << (GET_MODE_BITSIZE (GET_MODE (op0)) - 1)))) + if ((const_val & max_val) + != ((unsigned HOST_WIDE_INT) 1 + << (GET_MODE_BITSIZE (GET_MODE (op0)) - 1))) code = GT, op1 = gen_int_mode (const_val - 1, GET_MODE (op0)); break;