/* { dg-do run } */ /* { dg-options "-O2" } */ struct emac { unsigned reg[23]; }; struct mop { unsigned long long addr; unsigned int size; }; unsigned int __attribute__((__noinline__)) level(const struct emac *obj) { return 0; } void __attribute__((__noinline__)) info(struct emac *dev, unsigned long long addr) { asm("" : : : "memory"); } unsigned long long __attribute__((__noinline__)) get_value(const struct mop *mop) { return 0x1234567890abcdefull; } int __attribute__((__noinline__)) emac_operation(struct emac *obj, struct mop *mop) { unsigned long long addr = mop->addr; int index = addr >> 2; unsigned int value, old_value; if (mop->size != 4) return 0; if (index >= 23) { if (level(obj) >= 1) info(obj, addr); return 0; } value = get_value(mop); old_value = obj->reg[index]; info(obj, 0); switch (index) { case 0: obj->reg[0] = old_value; break; case 7: case 8: obj->reg[index] = value; break; } return 0; } int main(void) { struct emac e = { { 0 } }; struct mop mop = { 32, 4 }; e.reg[8] = 0xdeadbeef; emac_operation(&e, &mop); if (e.reg[8] != 0x90abcdef) __builtin_abort(); return 0; }