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

            Bug ID: 106542
           Summary: -O2 sign-extended uint32 to uint64
           Product: gcc
           Version: 9.3.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: wuz73 at hotmail dot com
  Target Milestone: ---

#include <iostream>

unsigned Msb(uint64_t x) { return 63 - __builtin_clzl(x); }

template<typename T>
void f(T r, T p)
{
    if (p > r)
    {
        auto d = p - r;
        unsigned k = Msb(sizeof(T) == 4 ? unsigned(d) : d);
        std::cout << sizeof(T) << " k=" << k << "\n";
    }
}

int main()
{
  int data[] = {-1610499096,2086724600};
  f(data[0],data[1]);
}

When compiled with "g++ -O2" the output is "4 k=63". Apparently before calling
Msb(), g++ sign-extended unsigned(d). static_cast<unsigend>(d) yields the same
result. However, "g++ -O0" is correct (k=31), so are earlier versions of g++
such as 4.8.5 and 5.3.1.

Reply via email to