This is an archive of the discontinued LLVM Phabricator instance.

[Clang] Emit error when caller cannot meet target feature requirement from always-inlining callee
ClosedPublic

Authored by qiucf on Feb 7 2023, 1:51 AM.

Details

Summary

Currently clang emits error when both always_inline and target attributes are on callee, but caller doesn't have some feature:

// RUN: %clang_cc1 -triple powerpc64le -target-feature -htm

__attribute__((always_inline))
__attribute__((target("htm")))
void foo() {}

void bar() { foo(); }

// error: always_inline function 'foo' requires target feature 'htm', but would be inlined into function 'bar' that is compiled without support for 'htm'

But when the always_inline attribute is on caller, clang has no diagnose. If any builtin or inline asm really need the feature, backend will crash.

// RUN: %clang_cc1 -triple powerpc64le -target-feature +htm

__attribute__((always_inline))
void foo() {
  // No error, but uncommenting line below triggers ICE
  // __builtin_ttest();
}

__attribute__((target("no-htm")))
void bar() { foo(); }

This patch will fix the second case.

Diff Detail

Event Timeline

qiucf created this revision.Feb 7 2023, 1:51 AM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 7 2023, 1:51 AM
qiucf requested review of this revision.Feb 7 2023, 1:51 AM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 7 2023, 1:51 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript

Gentle ping

erichkeane accepted this revision.Mar 14 2023, 7:25 AM

Thanks for your patience, I was buried trying to get the 16.0 release done. This LGTM!

This revision is now accepted and ready to land.Mar 14 2023, 7:25 AM
This revision was automatically updated to reflect the committed changes.

Hi-
We've actually seen some regressions internally thanks to this patch, which boil down to:

https://godbolt.org/z/WEer4M6ha

// compiled with -march=skylake
__attribute__((always_inline)) inline void foo(){}

__attribute__((target("arch=core-avx2")))
void bar() {
foo();
}

I believe @craig.topper and I spent a long time on these things, but I'm now questioning what arch= is supposed to do in this case. We're compiling bar as if it is an avx2 function, so it cannot call foo, which has additional features. However, they were not 'disabled'. A part of me thinks that the arch=... should mean "has at least these features", and the bug is thus in the code that sets the features list.

What does everyone think? attn: @FreddyYe

Hi-
We've actually seen some regressions internally thanks to this patch, which boil down to:

https://godbolt.org/z/WEer4M6ha

// compiled with -march=skylake
__attribute__((always_inline)) inline void foo(){}

__attribute__((target("arch=core-avx2")))
void bar() {
foo();
}

I believe @craig.topper and I spent a long time on these things, but I'm now questioning what arch= is supposed to do in this case. We're compiling bar as if it is an avx2 function, so it cannot call foo, which has additional features. However, they were not 'disabled'. A part of me thinks that the arch=... should mean "has at least these features", and the bug is thus in the code that sets the features list.

What does everyone think? attn: @FreddyYe

Based on GCC's behavior: https://godbolt.org/z/fxWzPTT9P I suspect our behavior is consistent/correct now, and the 'regressions' are to be expected, since GCC diagnoses the same things we do (just nicer, albeit, less informative).

qiucf added a comment.Apr 5 2023, 7:22 PM

Based on GCC's behavior: https://godbolt.org/z/fxWzPTT9P I suspect our behavior is consistent/correct now, and the 'regressions' are to be expected, since GCC diagnoses the same things we do (just nicer, albeit, less informative).

This is expected. But we can do better like GCC to find 'real target requirements from called intrinsics' of a function, which may be a larger change though.