Bug 96019 - Optimization forgets non-default scalar_storage_order
Summary: Optimization forgets non-default scalar_storage_order
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 9.3.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2020-07-01 12:38 UTC by Mingye Wang
Modified: 2020-07-01 14:22 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
test case (301 bytes, text/x-csrc)
2020-07-01 12:38 UTC, Mingye Wang
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Mingye Wang 2020-07-01 12:38:09 UTC
Created attachment 48818 [details]
test case

The attached code uses a scalar_storage_order to access a byte field in big endian. 

On an x86-64 Windows system, the output without optimization, as expected, is "aabbccdd 1122". The output with optimization (Og) is "ddccbbaa 2211".

The same happens on the https://gcc.godbolt.org/ site. With O0 a bswap can be found, but it is gone in -O1 and -Og.

I was unable to find the responsible option by bisection on the godbolt instance, but that could just be a godbolt thing.
Comment 1 Richard Biener 2020-07-01 12:52:09 UTC
I think Eric posted patches for this?
Comment 2 Eric Botcazou 2020-07-01 13:36:10 UTC
See the manual:

     Moreover, the use of type punning or aliasing to toggle the
     storage order is not supported; that is to say, a given scalar
     object cannot be accessed through distinct types that assign a
     different storage order to it.
Comment 3 Richard Biener 2020-07-01 14:00:19 UTC
So AFAIU

int main(int argc, char *argv[]) {
    uint8_t raw[] = { 0xaa, 0xbb, 0xcc, 0xdd, 0x11, 0x22 };
    SS instance;
    memcpy (&instance, raw, sizeof (SS));
    printf("%x, %x\n", instance.a, instance.b);
    return 0;
}

would be OK(?)
Comment 4 Eric Botcazou 2020-07-01 14:22:20 UTC
> So AFAIU
> 
> int main(int argc, char *argv[]) {
>     uint8_t raw[] = { 0xaa, 0xbb, 0xcc, 0xdd, 0x11, 0x22 };
>     SS instance;
>     memcpy (&instance, raw, sizeof (SS));
>     printf("%x, %x\n", instance.a, instance.b);
>     return 0;
> }
> 
> would be OK(?)

Yes, this should work once the patch (or a variant thereof) I posted some time ago to make memcpy a storage order barrier is installed. :-)