From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1873 invoked by alias); 5 Feb 2010 13:17:39 -0000 Received: (qmail 1818 invoked by uid 48); 5 Feb 2010 13:17:23 -0000 Date: Fri, 05 Feb 2010 13:17:00 -0000 Message-ID: <20100205131723.1817.qmail@sourceware.org> X-Bugzilla-Reason: CC References: Subject: [Bug middle-end/42972] Very bad bit field code In-Reply-To: Reply-To: gcc-bugzilla@gcc.gnu.org To: gcc-bugs@gcc.gnu.org From: "rguenth 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: 2010-02/txt/msg00384.txt.bz2 ------- Comment #3 from rguenth at gcc dot gnu dot org 2010-02-05 13:17 ------- On the (retired) mem-ref branch bitfield loads/stores were lowered very early to read-extract-modify-write operations so the tree level would have optimized this. But of course people complained that architectures that can do bitfield stores would be pessimized if we do not retain the funny BIT_FIELD_REFs of memory. Basically without some form of lowering the tree level is lost. mem-ref branch lowered the fn to i = 0; :; D.1564 = (long unsigned int) i; D.1565 = D.1564 * 4; D.1566 = p + D.1565; MEML.0 = IMEM ; D.1567 = BIT_FIELD_REF ; if (D.1567 != 0) goto ; else goto ; :; D.1564 = (long unsigned int) i; D.1565 = D.1564 * 4; D.1566 = p + D.1565; D.1564 = (long unsigned int) i; D.1565 = D.1564 * 4; D.1566 = p + D.1565; MEML.1 = IMEM ; D.1568 = BIT_FIELD_REF ; D.1569 = (int) D.1568; D.1570 = D.1569 + a; D.1571 = (unsigned int) D.1570; D.1572 = () D.1571; MEML.2 = IMEM ; MEML.2 = BIT_FIELD_EXPR ; IMEM = MEML.2; :; i = i + 1; if (i < n) goto ; else goto ; :; return; so FRE sees the redundant load and we expand from : ivtmp.20_15 = (unsigned int *) p_5(D); : # ivtmp.20_13 = PHI # i_1 = PHI <0(2), i_24(5)> MEML.0_7 = IMEM ; D.1567_8 = BIT_FIELD_REF ; if (D.1567_8 != 0) goto ; else goto ; : D.1568_16 = BIT_FIELD_REF ; D.1569_17 = (int) D.1568_16; D.1570_19 = D.1569_17 + a_18(D); D.1571_20 = (unsigned int) D.1570_19; D.1572_21 = () D.1571_20; MEML.2_23 = BIT_FIELD_EXPR ; IMEM = MEML.2_23; : i_24 = i_1 + 1; ivtmp.20_22 = ivtmp.20_13 + 4; if (i_24 < n_25(D)) goto ; else goto ; : return; on x86_64 the generated code was func: .LFB2: movl %edx, %r8d xorl %ecx, %ecx .p2align 4,,10 .p2align 3 .L3: movl (%rdi), %eax testb $1, %al je .L2 movl %eax, %edx shrl %eax addl %r8d, %eax andl $1, %edx addl %eax, %eax orl %eax, %edx movl %edx, (%rdi) .L2: addl $1, %ecx addq $4, %rdi cmpl %esi, %ecx jl .L3 rep ret -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42972