[Bug c++/100224] New: incorrect result when doing double vectorized

zhaoc at apache dot org gcc-bugzilla@gcc.gnu.org
Fri Apr 23 03:28:54 GMT 2021


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

            Bug ID: 100224
           Summary: incorrect result when doing double vectorized
           Product: gcc
           Version: 10.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: zhaoc at apache dot org
  Target Milestone: ---

When I use O3 to compile a code, I got an unexpected result.

test_murmur.cc

#include <cstdint>
#include <vector>
#include <iostream>

static const uint64_t MURMUR_PRIME = 0xc6a4a7935bd1e995ULL;
static const uint32_t MURMUR_SEED = 0xadc83b19ULL;

// Our hash function is MurmurHash2, 64 bit version.
// It was modified in order to provide the same result in
// big and little endian archs (endian neutral).
static uint64_t murmur_hash64A (const void* key, int32_t len, unsigned int
seed) {
    const uint64_t m = MURMUR_PRIME;
    const int r = 47;
    uint64_t h = seed ^ (len * m);
    const uint8_t *data = (const uint8_t *)key;
    const uint8_t *end = data + (len-(len&7));

    while(data != end) {
        uint64_t k;
        k = *((uint64_t*)data);

        k *= m;
        k ^= k >> r;
        k *= m;
        h ^= k;
        h *= m;
        data += 8;
    }

    switch(len & 7) {
    case 7: h ^= (uint64_t)data[6] << 48;
    case 6: h ^= (uint64_t)data[5] << 40;
    case 5: h ^= (uint64_t)data[4] << 32;
    case 4: h ^= (uint64_t)data[3] << 24;
    case 3: h ^= (uint64_t)data[2] << 16;
    case 2: h ^= (uint64_t)data[1] << 8;
    case 1: h ^= (uint64_t)data[0];
            h *= m;
    };

    h ^= h >> r;
    h *= m;
    h ^= h >> r;
    return h;
}

void update_double(const std::vector<double>& values, std::vector<uint64_t>&
hashes) {
    auto size = values.size();
    for (int i = 0; i < size; ++i) {
        auto v = values[i];
        uint64_t value = murmur_hash64A(&v, sizeof(v), MURMUR_SEED);
        hashes[i] = value;
    }
}

int main() {
    std::vector<double> values(3);
    std::vector<uint64_t> hashes(3);

    for (int i = 0; i < 3; ++i) {
        values[i] = i + 1;
    }
    update_double(values, hashes);
    for (auto hash : hashes) {
        std::cout << hash << std::endl;
    }
    return 0;
}

gcc-10.3.0/bin/g++  -std=gnu++17  -O3 -msse4.2 -mavx2 test_murmur.cc

output

4138674677912027985
4138674677912027985
4138674677912027985

When I used option O2 to compile this file,

gcc-10.3.0/bin/g++  -std=gnu++17  -O2 -msse4.2 -mavx2 test_murmur.cc

the output is following which is expected:

17614482930881034518
9674455539515676295
16429943614018478328

It seems something wrong when GCC generating optimized code for 'double'.


More information about the Gcc-bugs mailing list