Bug 64953

Summary: Compiling sourcecode for STM32F103 causes USB errors with some optimization settings
Product: gcc Reporter: manuel.reimer
Component: targetAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED INVALID    
Severity: normal    
Priority: P3    
Version: 4.9.2   
Target Milestone: ---   
Host: Target: arm
Build: Known to work:
Known to fail: Last reconfirmed: 2015-02-10 00:00:00
Attachments: Preprocessed file for "usb.c"

Description manuel.reimer 2015-02-05 19:30:16 UTC
I've tried to compile this sourcecode for an STM32F103 controller:

https://github.com/tormodvolden/maple-bootloader/tree/unify_platforms

I've modified the Makefile to use "-Os" to reduce size used in flash.

This worked well, so far, with an gcc 4.8 compiler. But if I do this with a 4.9.2 compiler, then the USB handshake fails with ugly errors on dmesg:

[ 2068.103728] usb 1-1: new full-speed USB device number 2 using xhci_hcd
[ 2068.217014] usb 1-1: device descriptor read/64, error -71
[ 2068.323573] xhci_hcd 0000:02:00.0: Setup ERROR: setup context command for slot 1.
[ 2068.327349] usb 1-1: hub failed to enable device, error -22
[ 2068.436815] usb 1-1: new full-speed USB device number 3 using xhci_hcd
[ 2068.550102] usb 1-1: device descriptor read/64, error 18
[ 2068.656663] xhci_hcd 0000:02:00.0: Setup ERROR: setup context command for slot 1.
[ 2068.660448] usb 1-1: hub failed to enable device, error -22
[ 2068.773235] usb 1-1: new full-speed USB device number 4 using xhci_hcd
[ 2068.773866] xhci_hcd 0000:02:00.0: ERROR: unexpected setup address command completion code 0x6.
[ 2068.980792] xhci_hcd 0000:02:00.0: ERROR: unexpected setup address command completion code 0x6.
[ 2069.186265] usb 1-1: device not accepting address 4, error -22
[ 2069.296195] usb 1-1: new full-speed USB device number 5 using xhci_hcd
[ 2069.296483] xhci_hcd 0000:02:00.0: ERROR: unexpected setup address command completion code 0x6.
[ 2069.503332] xhci_hcd 0000:02:00.0: ERROR: unexpected setup address command completion code 0x6.
[ 2069.709220] usb 1-1: device not accepting address 5, error -22
[ 2069.713114] usb usb1-port1: unable to enumerate USB device

After some trying I've found out that the key in this case is the optimization setting. If I use "-O3", then the resulting binary works again if I use the 4.9.2 compiler.

So "something" is wrong with the optimization.

Can someone give me a hint about what changed between 4.8 and 4.9.2? Is this a bug in the gcc compiler or do I just need some new "compiler switch" to disable "some new feature" and get a valid binary, again?
Comment 1 manuel.reimer 2015-02-05 19:33:57 UTC
One addition: The same problem exists with other "USB based" sourcecode. For example with this one:

https://github.com/j1rie/IRMP_STM32/

olebowle at vdr-portal.de did a nice overview on which optimization settings cause the resulting software to fail on which compiler:

http://www.vdr-portal.de/board18-vdr-hardware/board13-fernbedienungen/p1231315-irmp-auf-stm32-ein-usb-ir-empf%C3%A4nger-sender-einschalter-mit-wakeup-timer/#post1231315
Comment 2 Markus Trippelsdorf 2015-02-05 19:44:28 UTC
(In reply to manuel.reimer from comment #0)
> After some trying I've found out that the key in this case is the
> optimization setting. If I use "-O3", then the resulting binary works again
> if I use the 4.9.2 compiler.
> 
> So "something" is wrong with the optimization.
> 
> Can someone give me a hint about what changed between 4.8 and 4.9.2? Is this
> a bug in the gcc compiler or do I just need some new "compiler switch" to
> disable "some new feature" and get a valid binary, again?

Try to narrow the issue down to a single source file. Once you have found
the file in question, you may narrow the problem down to a single function
by using __attribute__((optimize("-Os"))).

You could also try to build the application with -fsanitize=undefined
and see if any issue pops up.
Comment 3 manuel.reimer 2015-02-06 17:59:47 UTC
Thank you for your suggestion. This helped me to narrow this down to the function "usbReset":

https://github.com/tormodvolden/maple-bootloader/blob/unify_platforms/usb.c#L258

If I use "-Os" on everything but this one function, then the result still produces one error if I plug in, but stabilizes shortly after that and then works well.
Comment 4 Markus Trippelsdorf 2015-02-06 18:23:25 UTC
Ok, thanks.

Now please attach the preprocessed source of that file (by adding
--save-temps to the compiler invocation). Also post the exact
command line you use to compile that file. 
Maybe something obvious will show up.
Comment 5 manuel.reimer 2015-02-06 18:27:10 UTC
Created attachment 34690 [details]
Preprocessed file for "usb.c"
Comment 6 manuel.reimer 2015-02-06 18:28:13 UTC
The exact command line is:

arm-none-eabi-gcc -c -mthumb -mcpu=cortex-m3 -mthumb-interwork -I.  -Os -ffunction-sections -fdata-sections -Wall -Wimplicit -Wcast-align -Wpointer-arith -Wswitch -Wredundant-decls -Wreturn-type -Wshadow -Wunused -Wa,-adhlns=build/usb.lst -I./stm32_lib -I./usb_lib -DMAPLE --save-temps -MD -MP -MF .dep/usb.o.d usb.c -o build/usb.o
Comment 7 manuel.reimer 2015-02-08 21:23:12 UTC
I've tried to find out when the bug first occured.

This one (oldes 4.9 snapshot, I can get) already has the problem:
ftp://gcc.gnu.org/pub/gcc/snapshots/4.9-20140302/

And this one (newest 4.8 snapshot) doesn't have the problem:
ftp://gcc.gnu.org/pub/gcc/snapshots/4.8-20150129/

Is there any easy way to get snapshots between these two?
Comment 8 Markus Trippelsdorf 2015-02-08 21:33:51 UTC
(In reply to manuel.reimer from comment #7)
> I've tried to find out when the bug first occured.
> 
> This one (oldes 4.9 snapshot, I can get) already has the problem:
> ftp://gcc.gnu.org/pub/gcc/snapshots/4.9-20140302/
> 
> And this one (newest 4.8 snapshot) doesn't have the problem:
> ftp://gcc.gnu.org/pub/gcc/snapshots/4.8-20150129/
> 
> Is there any easy way to get snapshots between these two?

Sure. Just use git or svn and bisect...
Comment 9 manuel.reimer 2015-02-08 21:45:46 UTC
The two commits are in different branches. How to bisect in this case?
Comment 10 Markus Trippelsdorf 2015-02-09 05:50:54 UTC
(In reply to manuel.reimer from comment #9)
> The two commits are in different branches. How to bisect in this case?

gcc's history is linear in git. So you could start with a 
bad commit on 20140302 and go back a year and use e.g. a commit on 
20130302 as good.

(Or you could wait until an ARM guy takes a look at this bug...)
Comment 11 Richard Earnshaw 2015-02-10 11:40:59 UTC
(In reply to manuel.reimer from comment #0)
> So "something" is wrong with the optimization.

Not necessarily.  Your program may have a bug in it: many bugs are only shown up by higher levels of optimization.

We don't have your hardware and we don't have the full code to your application, so we aren't going to be able to help you debug this.

To take this any further you'll need to show us why you think the compiler has mis-optimized your code.  I think that's a more useful approach than trying to identify the change in GCC that causes the code to fail.
Comment 12 manuel.reimer 2015-02-10 16:17:08 UTC
(In reply to Richard Earnshaw from comment #11)
> We don't have your hardware and we don't have the full code to your
> application, so we aren't going to be able to help you debug this.

The hardware is basically something like a "reference application" for the STM32F103 available for a few bucks on ebay: http://www.ebay.com/itm/400608858461

The software is just the bootloader, I will need to flash new software directly via USB: https://github.com/tormodvolden/maple-bootloader/tree/unify_platforms

> To take this any further you'll need to show us why you think the compiler
> has mis-optimized your code.

I won't be able to.

I'm just a hobby programmer trying to help with this project: https://github.com/j1rie/IRMP_STM32/ with the goal to create a cheap USB based infrared remote control receiver.

I'm able to compile the code, flash the binary and up to now I was able to provide the required information in this bug report. I don't understand in detail what the C code does and I don't know anything about how compilers and their optimization work.
Comment 13 Richard Earnshaw 2015-02-10 16:51:55 UTC
gcc developers are volunteers.  Sorry, but they're not going to go around buying random bits of hardware to search for problems that may not even be bugs in the compiler.

In the absense of any concrete information, I'm closing this as invalid.  If you can provide more details as to exactly how the code has been mis-compiled, then please feel free to re-open and append that information.
Comment 14 manuel.reimer 2015-02-10 17:17:36 UTC
You are a bit fast with closing bugs, aren't you?

I think you should give me at least a chance to get feedback on my "git bisect" result, I'll be able to present in a few minutes. I took me a few hours to track this down and maybe the affected commit at least makes it possible that someone can give me a hint what else I could try to find the real reason for the problem?
Comment 15 manuel.reimer 2015-02-10 17:23:37 UTC
This is what "git bisect" ended with. Maybe someone can at least have a look at this. Feel free to close again if this really doesn't help at all.


$ git bisect bad9eec20bfd5806dd0380e07dbc0f03409ce3d4efb is the first bad commit
commit 9eec20bfd5806dd0380e07dbc0f03409ce3d4efb
Author: rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Tue Mar 26 09:14:59 2013 +0000

    2013-03-26  Richard Biener  <rguenther@suse.de>
    
        * emit-rtl.c (set_mem_attributes_minus_bitpos): Remove
        alignment computations and rely on get_object_alignment_1
        for the !TYPE_P case.
        Commonize DECL/COMPONENT_REF handling in the ARRAY_REF path.
    
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@197095 138bc75d-0d04-0410-961f-82ee72b054a4

:040000 040000 f4fa27b8adaec983566fb9cb72d1165d10c86048 a13a68729d60b22dd6c45edb3ef7c3c52b3a2f41 M    gcc
Comment 16 Andrew Pinski 2015-02-10 18:38:37 UTC
You need to compile with -mno-unaligned-access when compiling the firmware.
This is mentioned in https://gcc.gnu.org/gcc-4.7/changes.html:
On ARM, when compiling for ARMv6 (but not ARMv6-M), ARMv7-A, ARMv7-R, or ARMv7-M, the new option -munaligned-access is active by default, which for some sources generates code that accesses memory on unaligned addresses. This requires the kernel of those systems to enable such accesses (controlled by CP15 register c1, refer to ARM documentation). Alternatively, or for compatibility with kernels where unaligned accesses are not supported, all code has to be compiled with -mno-unaligned-access. Upstream Linux kernel releases have automatically and unconditionally supported unaligned accesses as emitted by GCC due to this option being active since version 2.6.28.
Comment 17 manuel.reimer 2015-02-10 19:44:35 UTC
I've tried that and unfortunately I still get the errors when connecting my STM32 via USB.

So the only solution, available for me, seems to be to add a note to the sourcecode that it has to be built with GCC 4.8.

Thank you anyway to everyone who tried to help.
Comment 18 Mikhail Maltsev 2015-02-13 08:34:18 UTC
Is your firmware (or some similar one, which also has this bug) suitable for STM32F20x MCUs? I have a development board with such controller (specifically, this one: http://www.wvshare.com/product/Open207Z-Standard.htm). Perhaps, I could assist with debugging.