Open
Description
This should panic but it doesn`t
#[target_feature = "+avx"]
pub fn should_panic() {
#[cfg(target_feature = "avx")]
panic!("have_avx");
}
I would like for this to work because I have a macro that generates 2 copys of a function, one with #[target_feature = "+feat"]
and one without and I want to conditionally use some assembly when the feature is available.
CC #29717
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
BurntSushi commentedon Jun 8, 2017
It does panic.
If you don't compile with the appropriate target-feature settings, then the
cfg
is not set and the program (correctly) does not panic. I think you can think of-C target-feature=+avx
similarly as gcc's-mavx
flag.parched commentedon Jun 8, 2017
But
#[target_feature = "+avx"]
should set it for that function without passing anything extra on the command line.BurntSushi commentedon Jun 8, 2017
What do gcc and clang do? Can you explain more about your use case and why you expect this to happen?
parched commentedon Jun 8, 2017
Well gcc and c only have the preprocessor macros so that would behave like cfg_target_feature currently does. However, I assumed rust attributes are more context aware.
parched commentedon Jun 8, 2017
My use case is for this procedural macro attribute I've written https://github.com/parched/runtime-target-feature-rs which generates 2 copies of the function, one with
#[target_feature = "+feat"]
and one without. I would like to have some conditional code based on which copies is being compiled.BurntSushi commentedon Jun 8, 2017
@parched gcc and Clang have the equivalent of
#[target_feature]
as well, e.g.,__target__("avx")
can be applied to functions. Both gcc and Clang support that. So I would be very interested to see how their preprocessor macros interact with__target__("avx")
(if at all).To give you some context, the
#[target_feature]
attribute is highly experimental. Its only purpose is to expose an LLVM feature directly so that we can experiment with it to help move along the SIMD stabilization effort. What its iteraction with#[cfg(target_feature)]
is isn't clear at this time, so detailed use cases would be very helpful.But
#[target_feature]
isn't a conditional compilation flag. You need to do some kind of runtime dispatch using cpuid to figure out which function to execute. I still don't understand the use case for usingcfg(target_feature)
inside a#[target_feature]
function.parched commentedon Jun 8, 2017
More explicitly the macro I've written,
runtime_target_feature
turnsparched commentedon Jun 8, 2017
@BurntSushi I mean they only have macros for detecting the target features so the couldn't possibly change inside a function with
__target__("avx")
which is annoying. It would be great if rust cfg could be smarter than that though :)BurntSushi commentedon Jun 8, 2017
@parched Sorry, but I still don't understand your use case. What problem are you trying to solve at a high level? For example, having a
cfg(not(target_feature = "avx"))
inside a#[target_feature = "+avx"]
function just doesn't make any sense to me at all. If you wind up calling a#[target_feature = "+avx"]
function whenavx
isn't actually enabled, then you're in trouble no matter what.BurntSushi commentedon Jun 8, 2017
And I still don't understand what's fundamentally different between Rust's system and gcc's/Clang's. I think you need to back way up and help me try to understand what specific problems you're facing.
TimNN commentedon Jun 8, 2017
@BurntSushi: I think the use case here is a matter of convenience: Write a function in which some parts are marked
#[cfg(target_feature = "avx")]
or#[cfg(not(target_feature = "avx"))]
, then use a macro to create two versions (copies) of that function, one with#[target_feature = "+avx"]
and one without, along with supporting code to choose the correct one at runtime.The difference to gcc/Clang is, as I understand it, that since the preprocessor runs before any c parsing happens it cannot know if it is inside a function marked
__target__("avx")
, whereas the rust compiler should be / is / could be well aware that it's currently looking at a#[cfg(target_feature = "avx")]
inside a function marked#[target_feature = "+avx"]
.BurntSushi commentedon Jun 8, 2017
@TimNN Thanks for explaining that. It makes a little more sense, although I don't understand why the macro can't just strip out the cfg'd code that's never going to execute.
Popping up a level, I'm not particularly familiar with this aspect of the compiler (can arbitrary attributes impact the resolution of
cfg
s?) and I don't know if we have any precedent for it.parched commentedon Jun 8, 2017
Yes just what TimNN says. @BurntSushi I was actually just thinking that on my bike ride home and that would definitely work. It would mean the macro would need to know all the target features and their hierarchy. I.e., if the feature enabled was sse3 the macro would have to know to strip out any cfg not sse2.
17 remaining items