avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-gcc-list] Optimisation mixes up registers in inline assembly


From: Michael Kwasnicki
Subject: [avr-gcc-list] Optimisation mixes up registers in inline assembly
Date: Wed, 24 Jul 2019 18:55:00 +0200

Hello dear list members,

I am new to this list because I need someone to discuss a potential compiler bug.


I try to mix inline assembly in C code. In the assembly I use passed in variables which are named:

https://godbolt.org/z/w8wuJy

The register mapping is:
[rZero] -> R20
[rOne] -> R21
[rStart] -> R18
[rStop] -> R19
[rSize] -> R22
[bits] -> R19

If I look at the output assembly I can see the compiler did some optimisation.
R19 is shared between [bits] and [rStop].
In this case this is okay as the bit count reaches zero at the end and thus [bits] and [rStop] have the same value then.


But when I change the initial value of `bitcount` in C to 7 all hell breaks loose.

https://godbolt.org/z/F7rrB_

The register mapping is:
[rZero] -> R20
[rOne] -> R18
[rStart] -> R19
[rStop] -> R21
[rSize] -> R22
[bits] -> R18

This time the compiler optimisation corrupted the program.
R18 is shared between [rOne] and [bits]. [rOne] was supposed to be a constant that is cached in a register. But [bits] gets decremented.
Thus the value passed to OCR0B varies and is not constant any more changing the logic of the inline assembly.

I am not experienced with inline assembly so I might have missed something but my general expectation for assembly is that if I name things differently, they are different things (registers in this case).

The issue does not show up with -O0 but anything above.
Locally I am running avr-gcc (GCC) 9.1.0. Not sure what the exact version at godbolt is.

Cheers,

Michael

reply via email to

[Prev in Thread] Current Thread [Next in Thread]