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;
}