From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26264 invoked by alias); 4 Jun 2009 20:15:04 -0000 Received: (qmail 26077 invoked by uid 22791); 4 Jun 2009 20:15:02 -0000 X-SWARE-Spam-Status: No, hits=-2.3 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from mail3.caviumnetworks.com (HELO mail3.caviumnetworks.com) (12.108.191.235) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 04 Jun 2009 20:14:56 +0000 Received: from caexch01.caveonetworks.com (Not Verified[192.168.16.9]) by mail3.caviumnetworks.com with MailMarshal (v6,2,2,3503) id ; Thu, 04 Jun 2009 16:14:45 -0400 Received: from caexch01.caveonetworks.com ([192.168.16.9]) by caexch01.caveonetworks.com with Microsoft SMTPSVC(6.0.3790.3959); Thu, 4 Jun 2009 13:12:58 -0700 Received: from localhost ([64.169.86.201]) by caexch01.caveonetworks.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.3959); Thu, 4 Jun 2009 13:12:58 -0700 From: Adam Nemet To: gcc@gcc.gnu.org Subject: STRIP_NOPS and lower-precision/bit-field types Message-ID: Date: Thu, 04 Jun 2009 20:15:00 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org X-SW-Source: 2009-06/txt/msg00072.txt.bz2 In this testcase: struct s { unsigned long a:2; unsigned long b:40; unsigned long c:22; }; f (struct s s) { g (((unsigned long) (s.b-8)) + 8); } fold breaks the code. Specifically, after a few transformations we're asked to fold this. (I changed the big constant to be in symbolic form for better understanding): D.40719; (uint64_t) (D.40719 + ((1<<40) - 8)) + 8 The cast is removed by STRIP_NOPS so with explicit precision and signedness on the operations we have (the constants are of types of the corresponding operation): (D.40719 +:u40 ((1<<40) - 8)) +:u64 8 split_trees/associate_trees code combines the two constant resulting in: (uint64_t) D.40719 +:64 1<<40 Ouch. The problem is obviously that we remove a zero-extension that would ensure the modulo-2^40 nature of the addition (remove the overflow). I see two ways to fix this: 1. Change STRIP_NOPS not to remove the cast if it's changing the precision (not just when it changes machine modes). And then audit code quality where we need to and are allowed to look through these casts. The above case does not qualify because the first operation may not overflow into the >40 bits whereas the second may. For example with 2 as s.b the substraction should yield 0xff,ffff,fffa and the addition 0x100,0000,0002. (Note that there in *no* default integer promotion on bitfield types wider than int [1].) 2. Just fix this particular case of folding (split_trees/associate_trees) and hope everything else works ;). I am for 1, FWIW, but I know this issue has some history [2], so I'd like to hear others' opinion before I started working on a patch. Adam [1] http://gcc.gnu.org/ml/gcc/2008-01/msg00215.html [2] http://gcc.gnu.org/ml/gcc-patches/2004-07/msg01478.html