https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98582

            Bug ID: 98582
           Summary: Optimization combined with aliasing generating wrong
                    code
           Product: gcc
           Version: 10.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ferruh.yigit at intel dot com
  Target Milestone: ---

This is reported by "George Prekas <preka...@amazon.com>" to the DPDK mailing
list, also following sample code to reproduce the error is by him:

-------------------------------

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct rte_ipv4_hdr {
        uint8_t  version_ihl;
        uint8_t  type_of_service;
        uint16_t total_length;
        uint16_t packet_id;
        uint16_t fragment_offset;
        uint8_t  time_to_live;
        uint8_t  next_proto_id;
        uint16_t hdr_checksum;
        uint32_t src_addr;
        uint32_t dst_addr;
};

static inline uint16_t ip_sum(const uint16_t *hdr, int hdr_len)
{
        uint32_t sum = 0;

        while (hdr_len > 1)
        {
                sum += *hdr++;
                if (sum & 0x80000000)
                        sum = (sum & 0xFFFF) + (sum >> 16);
                hdr_len -= 2;
        }

        while (sum >> 16)
                sum = (sum & 0xFFFF) + (sum >> 16);

        return ~sum;
}

static void pkt_burst_flow_gen(void)
{
        struct rte_ipv4_hdr *ip_hdr = (struct rte_ipv4_hdr *) malloc(4096);
        memset(ip_hdr, 0, sizeof(*ip_hdr));
        ip_hdr->version_ihl     = 1;
        ip_hdr->type_of_service = 2;
        ip_hdr->fragment_offset = 3;
        ip_hdr->time_to_live    = 4;
        ip_hdr->next_proto_id   = 5;
        ip_hdr->packet_id       = 6;
        ip_hdr->src_addr        = 7;
        ip_hdr->dst_addr        = 8;
        ip_hdr->total_length    = 9;
        ip_hdr->hdr_checksum    = ip_sum((uint16_t *)ip_hdr, sizeof(*ip_hdr));
        printf("%x\n", ip_hdr->hdr_checksum);
}

int main(void)
{
        pkt_burst_flow_gen();
        return 0;
}

-------------------------------

with -O0 it outputs: f8d9
With -O3 it outputs: ffed
With -O2 it outputs: fdec


"-O3 -fno-strict-aliasing" is also works and outputs: f8d9

clang 11, with "-O3" returns: f8d9

With gcc 10.2 the value is calculated in the compile-time:
mov    $0xffed,%esi

and calculated value is wrong, not quite sure if a violation of the strict
aliasing or gcc internal defect. Reporting here to get more insight.

The header banner suggests the code is wrong [1], if that is the case you
please help to figure out what is wrong.

Thanks,
ferruh

[1]
"Similarly, if compiling with -fno-strict-aliasing -fwrapv makes a difference,
your code probably is not correct."

Reply via email to