That's not a very good analogy, as it's really a "reference" in both cases. Rather than value vs. reference, think const vs. non-const. When you only mark something as an input, you're effectively making it a const reference, so the compiler will make optimizations that rely on you not changing it (such as combining it with other things that happen to be equal to it). When you make it an output too, you're effectively making it a non-const reference.
Joseph C. Sible On Wed, Jul 24, 2019, 15:41 Michael Kwasnicki <avr-...@kwasi-ich.de> wrote: > So the inputs to inline assembly are by value and not by reference, as I > thought. Right? > The correlation between my named registers and those C variables was pure > coincidence. > And by making the named registers both - input and output - it creates a > reference to the original C variable. > > Regards, > > Michael K. > > > > Am 24.07.2019 um 19:17 schrieb Joseph C. Sible <josephcsi...@gmail.com>: > > Since you intend to modify the inputs, you need to declare them as outputs > as well (with the + constraint). If you don't do this, GCC is allowed to > assume you don't write to them, and can share any that have the same values. > > Joseph C. Sible > > > On Wed, Jul 24, 2019, 13:04 Michael Kwasnicki <avr-...@kwasi-ich.de> > wrote: > >> 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 <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 >> _______________________________________________ >> AVR-GCC-list mailing list >> AVR-GCC-list@nongnu.org >> https://lists.nongnu.org/mailman/listinfo/avr-gcc-list >> > >
_______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org https://lists.nongnu.org/mailman/listinfo/avr-gcc-list