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

--- Comment #31 from Vittorio Zecca <zeccav at gmail dot com> ---
It seems the following is related to the FF compilation issue:
The program runs differently depending on the optimization level.
With gcc 5.3.0 runs same regardless of the optimization level.
// g++ -Os/-O2/-O3/-Ofast
// 5.3.0 OK
// 6.1 & 7 FAIL
// 70526
#include <stdint.h>
#include <stdio.h>

template<typename T>
struct AlignedStorage2
{
  union U
  {
    char mBytes[sizeof(T)];
    uint64_t mDummy;
  } u;

  const T* addr() const { return reinterpret_cast<const T*>(u.mBytes); }
  T* addr() { return static_cast<T*>(static_cast<void*>(u.mBytes)); }
};

enum MIRType { MIRType_Object, MIRType_Value, MIRType_None };

struct Register {
    uint32_t reg_;
    static Register FromCode(uint32_t i) {
        Register r = { i };
        return r;
    }
    uint32_t code() const { return reg_; }
};

class TypedOrValueRegister
{
    MIRType type_;
    AlignedStorage2<Register> typed;
    __attribute__((noinline)) Register& dataTyped() { return *typed.addr(); }
  public:
    TypedOrValueRegister()
      : type_(MIRType_None) {}
    TypedOrValueRegister(MIRType type, Register reg)
      : type_(type)
    {
      dataTyped() = reg;
    }
    Register typedReg() const { return *typed.addr(); }
};

class ConstantOrRegister
{
    TypedOrValueRegister reg_;
  public:
    ConstantOrRegister(TypedOrValueRegister reg) : reg_(reg) {}
    TypedOrValueRegister reg() const { return reg_; }
};

class LAllocation
{
public:
  __attribute__((noinline)) bool isConstant() const { return false; }
};

class LInstruction {
  LAllocation alloc;
public:
  virtual __attribute__((noinline)) LAllocation* getOperand(size_t n)
{ return &alloc; }
};

__attribute__((noinline)) Register
ToAnyRegister(const LAllocation* a)
{
  return Register::FromCode(10);
}

__attribute__((noinline)) ConstantOrRegister
ToConstantOrRegister(LInstruction* lir, size_t n, MIRType type) {
    if (type == MIRType_Value)
        return TypedOrValueRegister();
    const LAllocation* value = lir->getOperand(n);
    if (value->isConstant())
        return TypedOrValueRegister();
    return TypedOrValueRegister(type, ToAnyRegister(value));
}

int main() {
    LInstruction lir;
    ConstantOrRegister cr = ToConstantOrRegister(&lir, 0, MIRType_Object);
    if (cr.reg().typedReg().code() != 10)
        fprintf(stderr, "Fail\n");
    return 0;
}

Reply via email to