New user self-registration is disabled due to spam. For an account please email bugs-admin@lists.llvm.org with your e-mail address and full name.

Bug 33610 - Semantics of __attribute__((target("..."))) on platforms without the feature
Summary: Semantics of __attribute__((target("..."))) on platforms without the feature
Status: NEW
Alias: None
Product: clang
Classification: Unclassified
Component: Documentation (show other bugs)
Version: trunk
Hardware: PC All
: P enhancement
Assignee: Unassigned Clang Bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-06-27 06:40 PDT by Gonzalo BG
Modified: 2017-06-29 00:17 PDT (History)
5 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Gonzalo BG 2017-06-27 06:40:32 PDT
Intrinsics in the AVX headers are annotated with __attribute__((__target__("avx"))) and have no preconditions. 

The documentation of the target attribute is here: https://clang.llvm.org/docs/AttributeReference.html#target-gnu-target

It doesn't specify any pre/post conditions either.

What are the semantics of calling such a function on a target that does not support the feature specified by the target attribute?

In practice I can get a SIGILL exception, but am I guaranteed to get one (and can I reliably catch it?)? That is, is this defined or implementation defined behavior? If is so, how and where is it defined? Otherwise, is this undefined behavior? And if so, where is this undefined(clang, llvm, the assembler, the cpu)?
Comment 1 Richard Smith 2017-06-28 14:27:28 PDT
(In reply to Gonzalo BG from comment #0)
> What are the semantics of calling such a function on a target that does not
> support the feature specified by the target attribute?

The function is compiled with different target options. So it's analogous to the case where you compiled the function in a separate source file with those other options and then linked against it.

> In practice I can get a SIGILL exception, but am I guaranteed to get one
> (and can I reliably catch it?)?

You're not guaranteed to get a SIGILL. We do not guarantee that any particular instructions will get generated for particular intrinsics, but they're compiled with instructions for the selected target *available*.

What actually happens will depend on the target you selected on both sides of the call -- you're trying to run code generated for CPU X on CPU Y; we'll generate correct code for CPU X (if not, that's a bug), but what actually happens will depend on the behavior of CPU Y.

Some special, but common, cases:

If X's ISA is a subset of Y's ISA, then you get correct behavior. (Eg, running non-AVX code on a CPU that actually has AVX support is fine.)

If X's ISA is a superset of Y's ISA, and your execution environment guarantees that all additional instructions produce SIGILL, then I think you can reasonably deduce you would get either correct behavior or a SIGILL. But we don't control the execution environment, so we can't really say.
Comment 2 Gonzalo BG 2017-06-29 00:17:10 PDT
Since Clang/LLVM does not define this behavior, nor it can require that all execution environments do define this behavior, nor also can guarantee that this will not be used for optimizations in the future, the behavior is, at least from the POV of somebody using clang/LLVM, undefined. 

Maybe one can add this as a note to the clang docs of the target attribute, and also mention there that clang provides the __builtin_cpu_supports intrinsic to query at run-time whether the execution environment supports a target feature.

Maybe also ping the UBSan folks since they might want to check that calls annotated with target are only called on execution environments that can properly execute them.