Ok, so my question is the following: why does the code between both branches need to differ? Why cannot it be the same?
Example: you write:
if cfg!(runtime_target_feature = "avx2") {
... some code here that uses avx2, throught the simd crate, intrinsics or just letting the compiler optimize ...
} else {
... some equivalent code that doesn't use avx2...
}
but this is a run-time check, not a compile-time one IIUC correctly.
If this were a compile-time check, I can understand how you want to generate different code for different branches:
fn foo() {
if cfg!(compile_time_target_feature = "avx2") {
... do something with avx2 unsafe intrinsics ...
} else {
... do something else without avx2 and safe code...
}
}
// somewhere else call different versions of foo at run-time:
if cfg!(run_time_target_feature = "avx2") {
foo() // calls version of foo compiled with avx2 enabled
} else {
foo() // calls version of foo compiled without avx2
}
But then my questions are, what if foo comes for a third-party library that doesn’t want to give you the code? You cannot recompile it with avx2 enabled, how can this library provide on its ABI functions specific for different target features? (that’s what #[target_feature =...] as a function attribute does. It instructs the compiler to generate this functions that can be used on ABI boundaries).
Second, why do you need that run-time if at all?
Can’t you just say:
#[ifunc("default; sse4; avx; avx2")] // compiles 4 versions of foo
fn foo() {
if cfg!(compile_time_target_feature = "default") {
// provide a default implementation without vectorization
} else if ... {
// provide some other versions without the SIMD crate
}
}
// somewhere else:
foo(); // calls best implementation at run-time
the compiler could then, on binary initialization, set some function pointers based on target features, so that you just need to call foo() and always the best thing is chosen at run-time.
I agree that this is useful, but this is ifunc, not target_feature, and the main difference is that this call to foo doesn’t have the same cost as one call to foo using target feature.