[Solved] Illegal instruction on different machine

I sent my synth to a friend for testing and he is not able to even start it (Win and Linux).

On Linux (standalone application) he simply get the output

Illegal Instruction (core dumped)

On Windows (VST2 plugin) hosts will not see the plugin at all.

I did some research and found that at this is probably due to some optimization using CPU instructiions which might be not available on older CPU models. I looked into it and the release configs of my Linux release build are -O3, on Windows there seems to be no optimization (/Od).

Thinking about it, the Windows and Linux problems might be separate issues.
However at least the Linux build seems to be incorporating exotic CPU instructions.

Do I need to go lower than -O3?

1 Like

Changing the optimization level won’t help here, but changing the used vector extensions.
Try compiling with SSE2 or even lower. On MSVS you might find that setting in Project settings -> code generation. However I am not totally sure, as I am on mac :slight_smile:

1 Like

Ok thanks I will try this as soon as I get to my build machine!
Will this take a big toll on performance? (I guess the answer is “You’ll have to profile it”…? :grimacing:)

Also while we’re at it: Why is the default optimization level on windows set to /Od, even in the Release build?

It is :slight_smile:
Depends on how much the optimizer could make use of the advanced instruction set, which fully depends on the code itself. In a plug-in we made use of SIMDRegisters to increase performance of over 800 IIR filters, which helps a lot as it brings it down by a factor of 4 (SSE) or even 16 (AVX).

Cool thank you, I got it sorted for Visual Studio.

But the problem remains on Ubuntu. How can I tell the compiler to not use AVX2?
I just get the Makefile but have no options, beyond what is set in the Projucer.

Do I have to call make with options, set some compiler settings before compiling, set extra flags in the Projucer…?

1 Like

Ok I got it!

For anybody wondering: In Projucer go to your exporter tab (not Debug/Release but the header above which says “Linux Makefile”) where you can set “extra compiler flags”.

For GCC the flag to not use AVX2 is the flag to use anything up to AVX which is

1 Like

Normally, the compilation will target the base for the architecture in question (so, say, x64), and that doesn’t include AVX support since that isn’t required (it needs only SSE and SSE2). If however you’ve specified -march=native, then you’ll get a binary which takes advantage of the instructions available on your processor, and if it supports stuff like AVX2, the code generator could include these instructions, causing issues on earlier processors.

One of the reasons to use fancy libraries is that these often have runtime checks for processor capabilities, and are built with code paths optimised for different processor features, so enabling AVX2 for example, if it’s supported, but falling back to AVX, or SSE3 etc depending on the processor.

So, have a look to see if you’ve specified -march=native and if so, that’s the culprit

1 Like

-march=native is the default value in Projucer:

1 Like

Hmm, that doesn’t sound right to me…

1 Like

Whew that doesn’t sound right to me either…
I mean most developers will have rather fancy build machines I guess.
This should be an option really in the Projucer, so people don’t run into the same problem I think.

1 Like

The “Architecture” setting makes it possible to choose between no arch flag (when selecting <None>), -march=native, -m32, -m64, -march=armv6, and -march=armv7:

I have no idea why it defaults to -march=native though.

1 Like

Ah ok, I figured this was only for 32Bit vs 64Bit vs ARM… No idea this involved special instructions as well. This is what I would guess from the tooltip as well:


Thanks for clarifying though!

“Architecture” is actually a shortcut for “Instruction set architecture”.

The reason why you can run an x86 32-bit program on an x86 64-bit processor is because that processor also knows about the x86 32-bit instruction set (see https://en.wikipedia.org/wiki/X86 and https://en.wikipedia.org/wiki/X86-64 for more details).

The “R” in ARM is for “RISC”, which means " Reduced instruction set computer".