bad assembler produced: Error: bit-field extends past end of register -- `ubfx r0,r0,#30,#10'

Bug #771903 reported by Dr. David Alan Gilbert
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Linaro GCC
Fix Released
Low
Unassigned
4.5
Won't Fix
Low
Unassigned
gcc
Confirmed
Medium

Bug Description

The attached example program, kindly generated by a colleague, fails with:

gcc -O3 arm_bit_extract.c
/tmp/ccOOK26S.s: Assembler messages:
/tmp/ccOOK26S.s:97: Error: bit-field extends past end of register -- `ubfx r0,r0,#30,#10'

The compiler is 4.5.2-8ubuntu1

It's questionable whether the results of the shifts done by the original program are actually defined,
but it shouldn't produce bad asm.

Dave

Revision history for this message
Dr. David Alan Gilbert (davidgil-uk) wrote :
Revision history for this message
Michael Hope (michaelh1) wrote :

Thank you for the bug report. I've confirmed this with gcc-linaro-4.5-2011.04-0 on ARM:

michaelh@ursa1:~/linaro/bugs$ /tools/toolchains/arch/armv7l/gcc-linaro-4.5-2011.04-0-armv7l-maverick-cbuild112-ursa3-cortexa8r1/bin/gcc -O3 -c arm_bit_extract.c
/tmp/ccl0OX6a.s: Assembler messages:
/tmp/ccl0OX6a.s:97: Error: bit-field extends past end of register -- `ubfx r0,r0,#30,#10'

The assembler is correct - the instruction attempts to extract bits 30 to 39 from a 32 bit register.

The fault also exists in gcc-4.5.2. It does not exist in gcc-4.6.0. Could you please also report this in GCC bugzilla and attach it to this ticket?

I've set it to low priority as it is a ftbfs, occurs at high optimisation levels, the fault exists upstream, and the code uses undefined behavior by shifting by a negative amount.

Changed in gcc-linaro:
status: New → Triaged
importance: Undecided → Low
Revision history for this message
Chung-Lin Tang (cltang) wrote :

Looking at the ARM backend patterns, I cannot rule out that 4.6 or upstream trunk is free of this bug. The current reason that it only shows in Linaro 4.5 (haven't checked FSF 4.5), is because both calls to getBits() get inlined into main().

The 4.6/4.7 inliner heuristics have changed somewhat, so getBits() do not get the same inlining no matter how hard I've tried so far :P

As for Linaro 4.5, the offending pattern appears after combine. I'll look into this later.

Revision history for this message
In , Dr. David Alan Gilbert (davidgil-uk) wrote :

Created attachment 24123
Produces bad assembler

This was originally reported as Linaro-gcc bug in Launchpad here:
https://bugs.launchpad.net/gcc-linaro/+bug/771903

The attached small test case fails with the assembler error:
gcc -O3 arm_bit_extract.c
/tmp/ccOOK26S.s: Assembler messages:
/tmp/ccOOK26S.s:97: Error: bit-field extends past end of register -- `ubfx r0,r0,#30,#10'

when compiled -O3 for ARMv7 on Ubuntu's gcc 4.5.2-8ubuntu1.
I'm told it also fails on vanilla 4.5.2

The shift that the source is trying to do is a bit bogus, however it shouldn't produce bad assembler.

Dave

Revision history for this message
Dr. David Alan Gilbert (davidgil-uk) wrote :
Revision history for this message
In , Ramana-gcc (ramana-gcc) wrote :

Occurs on gcc 4.5 branch but not on 4.6 branch or trunk. Need to see where and why it got "fixed" .

Ramana

Revision history for this message
In , Michael Hope (michaelh1) wrote :

Part of the difference is that 4.5 inlines the other functions and 4.6 doesn't. Adding an __attribute__((always_inline)) to both gives the following:

For 4.5, main is:

main:
        movw r3, #22136
        movt r3, 4660
        and r3, r0, r3
        cbnz r3, .L10
        mvn r3, #15
        lsls r2, r0, r3
        ubfx r0, r0, #30, #10
        and r3, r0, #768
        lsrs r0, r2, #24
        orr r0, r3, r0
        bx lr
.L10:
        ubfx r3, r0, #22, #2
        lsrs r0, r0, #24
        lsls r3, r3, #8
        orr r0, r3, r0
        bx lr

For 4.6 it becomes:

main:
        movw r3, #22136
        movt r3, 4660
        ands r3, r3, r0
        cbz r3, .L13
        ubfx r3, r0, #22, #2
        lsrs r0, r0, #24
        lsls r3, r3, #8
.L12:
        orrs r0, r0, r3
        bx lr
.L13:
        mov r0, r3
        b .L12

Revision history for this message
Michael Hope (michaelh1) wrote :

Attached the upstream bug and followed up there.

Changed in gcc:
importance: Unknown → Medium
status: Unknown → Confirmed
Revision history for this message
In , Mikpe (mikpe) wrote :

This test case stopped failing, sort of, for 4.6 by r162943, the introduction of tree-bit-ccp optimization. However that revision merely masked the problem by default, as compiling with 4.6.[01] and -fno-tree-bit-ccp makes it reappear. The bug was finally fixed for 4.7 by r176911, the fix for the similar PR49799. That fix was also applied for 4.6.2 in r176917.

Backporting r176917 to 4.5 and 4.4 fixes both PRs there too.

Revision history for this message
Michael Hope (michaelh1) wrote :

The fault was fixed in the upstream release branch. Confirmed fixed in gcc-linaro-4.6-2011.09.

Revision history for this message
Michael Hope (michaelh1) wrote :

...but the original report was against 4.5. Exists in 4.5-2011.09-1.

Revision history for this message
Michael Hope (michaelh1) wrote :

I'm having a spring clean. Dave, this has been fixed in trunk and 4.6. Being aggressive and marking it as 'wont fix' for 4.5.

Changed in gcc-linaro:
status: Triaged → Fix Released
Revision history for this message
In , Ramana-gcc (ramana-gcc) wrote :

This is a 4.5 only bug and should probably be closed as 4.5 is now kind of dead.

Ramana

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.