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