I restored a couple of functions which have gotten partially wiped by gsfopt, by hand.
I know the gsfopt (VBA-M) and foo_input_gsf (mGBA) are using different emulation core, but I don't understand the exact point of the cause of the issue. I think WAITCNT relates to the issue, but have no more idea than that.
TL;DR Make sure to remove every Cart RAM accesses before the optimization.
I have experienced similar cases in multiple games and I have concluded that the issue is caused by Cart RAM (SRAM/Flash/EEPROM etc.) access. A good rip should not have such an extra I/O access, however, it can be missed easily on manual rips, since there was no auto detection mechanisms and it somewhat works well on the emulator.
My gsfopt (based on old viogsf of VBA-M core) doesn't emulate Cart RAM accesses and always returns 0 for read access. This behavior obviously makes unexpected branching. GSF player will try to operate unknown opcode and stops working, when the player reaches to the code wiped by unexpected Cart RAM handling.
I have added a little code to my gsfopt, which will generate warnings on the Cart RAM access. I hope it will help rippers to notice that the gsf contains unwanted code inside.
While debugging on no$gba, the following breakpoint syntax is handy to check the Cart RAM access.
[0d000000..0effffff]!!? !? ... syntax for breaking on any read or any write
I don't know whether VRAM/OAM/Pallete accesses may cause a playback/optimization issue, however, they should be removed as well. They can roughly checked via the addrest range [05000000..07ffffff]
Edit: The F-Zero gsflib above still have some VRAM write accesses. Oh! I probably won't try to fix it for a while, since it probably won't cause any problems.