CPUs offer feature flags that can be queried to learn about the availability of a particular extension. If a compiler wants to generate code that uses an extension if available, but falls back to an explicit (but slower) implementation if that's not the case, it can simply generate a branch instruction in front of the opcodes using the extension which checks for the feature flag first, branching into the fallback implementation if the extension isn't available.
That's true, though in practice - at least in C, C++, Rust, Go etc. - the compiler won't do that automatically. You need to write code to do it yourself (which very few people do for obvious reasons).