* Confusion with labels as values
@ 2019-06-19 13:05 Florian Rommel
2019-06-19 15:39 ` Jeff Law
0 siblings, 1 reply; 5+ messages in thread
From: Florian Rommel @ 2019-06-19 13:05 UTC (permalink / raw)
To: gcc
[-- Attachment #1: Type: text/plain, Size: 1861 bytes --]
Hi,
Recently I wanted to take and print the address of a label. When
compiling with -O2, I noticed that the address equals the function body
start address if the label is not used as a goto target.
Here is an example:
#include <stdio.h>
int main(void) {
printf("main: %p\n", main);
printf("label1: %p\n", &&label1);
label1:
puts("---");
return 0;
}
compile with:
$ gcc -O2 -o example1 example1.c
or more specifically:
$ gcc -O1 -fschedule-insns2 -o example1 example1.c
Output:
main: 0x562ed396216e
label1: 0x562ed396216e
---
(or compile with -S to see that the label is moved to the start of the
function)
That is not completely surprising because labels as values are not
really valid outside of the originating function [1].
However when I assign the two addresses to automatic variables (which
should be okay) and compare them, they are different (despite having
the same value; the substraction result is 0). Passing them to an
external function yields equality again (if the function is not
inlined).
#include <stdio.h>
void compare(size_t x, size_t y) {
printf("x == y : %d\n", x == y);
}
int main(void) {
size_t m = (size_t)main;
size_t l = (size_t)&&label1;
printf("m: %p\n", m);
printf("l: %p\n", l);
printf("m == l : %d\n", m == l);
printf("m - l :% d\n", m - l);
compare(m, l);
label1:
puts("---");
return 0;
}
Output:
m: 0x559a775cd16e
l: 0x559a775cd16e
m - l : 0
m == l : 0
x == y : 1
---
The reasons for this behavior probably lies in constant
folding/propagation.
I'm not sure whether this is technically a bug (Labels as Values /
Computed Gotos are not Standard C anyway). But this is at least
confusing. Maybe the label should not be moved in the first place?
Regards,
Flo
[1] https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
[-- Attachment #2: example2.c --]
[-- Type: text/x-csrc, Size: 477 bytes --]
// Compile with:
// $ gcc -O2 -o example2 example2.c
// or
// $ gcc -O1 -fschedule-insns2 -o example2 example2.c
#include <stdio.h>
void compare(size_t x, size_t y) {
printf("x == y : %d\n", x == y);
}
int main(void) {
size_t m = (size_t)main;
size_t l = (size_t)&&label1;
printf("m: %p\n", m);
printf("l: %p\n", l);
printf("m == l : %d\n", m == l);
printf("m - l :% d\n", m - l);
compare(m, l);
label1:
puts("---");
return 0;
}
[-- Attachment #3: example1.c --]
[-- Type: text/x-csrc, Size: 268 bytes --]
// Compile with:
// $ gcc -O2 -o example1 example1.c
// or
// $ gcc -O1 -fschedule-insns2 -o example1 example1.c
#include <stdio.h>
int main(void) {
printf("main: %p\n", main);
printf("label1: %p\n", &&label1);
label1:
puts("---");
return 0;
}
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Confusion with labels as values
2019-06-19 13:05 Confusion with labels as values Florian Rommel
@ 2019-06-19 15:39 ` Jeff Law
2019-06-19 17:09 ` Segher Boessenkool
0 siblings, 1 reply; 5+ messages in thread
From: Jeff Law @ 2019-06-19 15:39 UTC (permalink / raw)
To: Florian Rommel, gcc
On 6/19/19 7:04 AM, Florian Rommel wrote:
> Hi,
>
> Recently I wanted to take and print the address of a label. When
> compiling with -O2, I noticed that the address equals the function body
> start address if the label is not used as a goto target.
>
> Here is an example:
>
> #include <stdio.h>
> int main(void) {
> printf("main: %p\n", main);
> printf("label1: %p\n", &&label1);
> label1:
> puts("---");
> return 0;
> }
>
> compile with:
> $ gcc -O2 -o example1 example1.c
>
> or more specifically:
> $ gcc -O1 -fschedule-insns2 -o example1 example1.c
>
> Output:
> main: 0x562ed396216e
> label1: 0x562ed396216e
> ---
>
>
> (or compile with -S to see that the label is moved to the start of the
> function)
>
> That is not completely surprising because labels as values are not
> really valid outside of the originating function [1].
>
> However when I assign the two addresses to automatic variables (which
> should be okay) and compare them, they are different (despite having
> the same value; the substraction result is 0). Passing them to an
> external function yields equality again (if the function is not
> inlined).
>
> #include <stdio.h>
> void compare(size_t x, size_t y) {
> printf("x == y : %d\n", x == y);
> }
> int main(void) {
> size_t m = (size_t)main;
> size_t l = (size_t)&&label1;
> printf("m: %p\n", m);
> printf("l: %p\n", l);
> printf("m == l : %d\n", m == l);
> printf("m - l :% d\n", m - l);
> compare(m, l);
> label1:
> puts("---");
> return 0;
> }
>
> Output:
> m: 0x559a775cd16e
> l: 0x559a775cd16e
> m - l : 0
> m == l : 0
> x == y : 1
> ---
>
>
> The reasons for this behavior probably lies in constant
> folding/propagation.
>
> I'm not sure whether this is technically a bug (Labels as Values /
> Computed Gotos are not Standard C anyway). But this is at least
> confusing. Maybe the label should not be moved in the first place?
A label used as a value, but which is not a jump target will have an
indeterminate value -- it'll end up somewhere in its containing
function, that's all we guarantee in that case.
jeff
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Confusion with labels as values
2019-06-19 15:39 ` Jeff Law
@ 2019-06-19 17:09 ` Segher Boessenkool
2019-06-19 17:38 ` Jeff Law
0 siblings, 1 reply; 5+ messages in thread
From: Segher Boessenkool @ 2019-06-19 17:09 UTC (permalink / raw)
To: Jeff Law; +Cc: Florian Rommel, gcc
On Wed, Jun 19, 2019 at 09:39:01AM -0600, Jeff Law wrote:
> A label used as a value, but which is not a jump target will have an
> indeterminate value -- it'll end up somewhere in its containing
> function, that's all we guarantee in that case.
In gimple it was fine and expected, and expand *did* make a code_label,
it was just immediately optimised away:
===
;; Generating RTL for gimple basic block 3
;; label1:
(code_label/s 14 13 15 2 ("label1") [0 uses])
(note 15 14 0 NOTE_INSN_BASIC_BLOCK)
===
and then we get
===
Merging block 3 into block 2...
Merged blocks 2 and 3.
Merged 2 and 3 without moving.
===
leaving
===
(note/s 14 13 16 2 ("label1") NOTE_INSN_DELETED_LABEL 2)
===
Do we want this to work as expected?
Segher
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Confusion with labels as values
2019-06-19 17:09 ` Segher Boessenkool
@ 2019-06-19 17:38 ` Jeff Law
2019-06-20 7:29 ` Segher Boessenkool
0 siblings, 1 reply; 5+ messages in thread
From: Jeff Law @ 2019-06-19 17:38 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: Florian Rommel, gcc
On 6/19/19 11:09 AM, Segher Boessenkool wrote:
> On Wed, Jun 19, 2019 at 09:39:01AM -0600, Jeff Law wrote:
>> A label used as a value, but which is not a jump target will have an
>> indeterminate value -- it'll end up somewhere in its containing
>> function, that's all we guarantee in that case.
>
> In gimple it was fine and expected, and expand *did* make a code_label,
> it was just immediately optimised away:
Yea, because it wasn't used as a jump target. That's why it gets turned
into a NOTE_INSN_DELETED_LABEL rather than just deleted.
Jeff
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Confusion with labels as values
2019-06-19 17:38 ` Jeff Law
@ 2019-06-20 7:29 ` Segher Boessenkool
0 siblings, 0 replies; 5+ messages in thread
From: Segher Boessenkool @ 2019-06-20 7:29 UTC (permalink / raw)
To: Jeff Law; +Cc: Florian Rommel, gcc
On Wed, Jun 19, 2019 at 11:37:52AM -0600, Jeff Law wrote:
> On 6/19/19 11:09 AM, Segher Boessenkool wrote:
> > On Wed, Jun 19, 2019 at 09:39:01AM -0600, Jeff Law wrote:
> >> A label used as a value, but which is not a jump target will have an
> >> indeterminate value -- it'll end up somewhere in its containing
> >> function, that's all we guarantee in that case.
> >
> > In gimple it was fine and expected, and expand *did* make a code_label,
> > it was just immediately optimised away:
> Yea, because it wasn't used as a jump target. That's why it gets turned
> into a NOTE_INSN_DELETED_LABEL rather than just deleted.
My point was, we could change that. But the more I look at it the worse
plan that looks -- it's not as simple as it appears, and for what? :-)
Segher
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2019-06-20 7:29 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-19 13:05 Confusion with labels as values Florian Rommel
2019-06-19 15:39 ` Jeff Law
2019-06-19 17:09 ` Segher Boessenkool
2019-06-19 17:38 ` Jeff Law
2019-06-20 7:29 ` Segher Boessenkool
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).