This is an archive of the discontinued LLVM Phabricator instance.

[Clang] Add C++2b attribute [[assume(expression)]]
Needs ReviewPublic

Authored by Izaron on Feb 18 2023, 1:16 PM.

Details

Reviewers
aaron.ballman
rsmith
nikic
Group Reviewers
Restricted Project
Summary

Clang already supports assumes for optimizing. Now it is standardized
in C++2b via a new attribute - https://wg21.link/p1774r8.

Diff Detail

Event Timeline

Izaron created this revision.Feb 18 2023, 1:16 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 18 2023, 1:16 PM
Herald added a subscriber: StephenFan. · View Herald Transcript
Izaron requested review of this revision.Feb 18 2023, 1:16 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 18 2023, 1:16 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
Izaron updated this revision to Diff 498622.Feb 18 2023, 1:21 PM

A small fix for def FutureAttrs

Izaron added inline comments.Feb 18 2023, 1:22 PM
clang/include/clang/Basic/Attr.td
1448

Honestly I don't have a clue what these numbers 202302 (apparently the yyyymm format) would mean :( I'd be grateful if you could help me with the right value for this.

philnik added inline comments.
clang/include/clang/Basic/Attr.td
1448

https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations has generally the correct values for this. In this case it's 202207.

Izaron updated this revision to Diff 498625.Feb 18 2023, 1:32 PM

More thorough AST test.

Set the right macros number - thanks to @philnik!

Izaron marked an inline comment as done.Feb 18 2023, 1:32 PM

If you are not familiar with the [[assume(expr]] concept and want to know more, I wrote a small article about it recently, with a lot of additional links (including to the author of the proposal) - https://izaron.github.io/posts/assume/

nikic resigned from this revision.Feb 20 2023, 1:20 AM

(not a clang reviewer)

clang/test/CodeGenCXX/cxx2b-assume.cpp
55

Isn't the assume expression supposed to be unevaluated?

Can you add a test to check __has_cpp_attribute(assume) ?

clang/lib/CodeGen/CGStmt.cpp
723–727

I'm not familiar with codegen. what makes the expression non-evaluated here?

So one thing to note here: I'm on the fence as to whether we want to implement this feature at all. As was discussed extensively during the EWG meetings on this: multiple implementers are against this attribute for a variety of reasons, and at least 1 other implementer has stated they might 'implementer veto' this. I think there is discussion to be had among the code owners here as to whether we even want this.

clang/include/clang/Basic/AttrDocs.td
2107
2112

This last sentence is inaccurate. As discussed in EWG, this attribute has some pretty painful side-effects (instantiation, lambda creation/etc).

clang/test/CodeGenCXX/cxx2b-assume.cpp
2

Having a CFE test depend on the optimizer like this is EXTREMELY frowned upon. We shouldn't have clang tests depend on optimizer performance.

55

We need MUCH more complicated tests (including just any expression/function call/etc) to ensure that the side-effects aren't going to cause problems, particularly in -O0. I am somewhat confident that the middle-end is going to be willing to do the work to figure out that something passed to 'assume' is passed out correctly, but I'm not convinced that this will prevent all side-effects from escaping.

tahonermann added inline comments.
clang/include/clang/Basic/Attr.td
1448

The draft standard is a better reference (http://eel.is/c++draft/cpp.cond#6). Fortunately, it agrees with SD6.

philnik added inline comments.Feb 21 2023, 9:44 AM
clang/include/clang/Basic/Attr.td
1448

The problem with the standard is that it doesn't list the old values, so it's useless if you want to implement a paper for which the FTM has already been bumped by another paper (or you don't know whether there is another paper).

I'm on the fence as to whether we want to implement this feature at all. As was discussed extensively during the EWG meetings on this: multiple implementers are against this attribute for a variety of reasons, and at least 1 other implementer has stated they might 'implementer veto' this.

I don't quite understand how it works. The feature has been approved for C++2b, but it should have not been approved if there were concerns from implementers.

A friend of mine got his proposal rejected because MSVC said they are unable to support the new feature.

But it seems like not the case with the assume attribute. Could you please elaborate: if you decide to not implement this feature, you will kind of revoke the proposal or just deliberately do not support a part of C++2b in Clang?

I'm on the fence as to whether we want to implement this feature at all. As was discussed extensively during the EWG meetings on this: multiple implementers are against this attribute for a variety of reasons, and at least 1 other implementer has stated they might 'implementer veto' this.

I don't quite understand how it works. The feature has been approved for C++2b, but it should have not been approved if there were concerns from implementers.

You're preaching to the choir on that one. Two of the implementers (including our code owner, and MSVC reps) stated a distinct dislike for this, and that they were considering implementer veto on it.

A friend of mine got his proposal rejected because MSVC said they are unable to support the new feature.

"Unable to support" and "dont want to support" are different, but EWG is nothing if not consistently inconsistent.

But it seems like not the case with the assume attribute. Could you please elaborate: if you decide to not implement this feature, you will kind of revoke the proposal or just deliberately do not support a part of C++2b in Clang?

Just deliberately not support a part of C++2b. Implementers have veto'ed features in the past exactly that way.

Izaron marked an inline comment as done.Feb 21 2023, 11:54 AM

Just deliberately not support a part of C++2b. Implementers have veto'ed features in the past exactly that way.

That's sad. Let's at least write some warning on the cxx_status.html like "we aren't gonna implement it".

clang/lib/CodeGen/CGStmt.cpp
723–727

The LLVM docs says it: https://llvm.org/docs/LangRef.html#llvm-assume-intrinsic

No code is generated for this intrinsic, and instructions that contribute only to the provided condition are not used for code generation

The ArgValue and FnAssume are the instructions to be discarded according to this sentence.

I guess they do it via dead code elimination (at any optimization level).

Izaron marked an inline comment as done.Feb 21 2023, 11:54 AM
erichkeane added inline comments.Feb 21 2023, 12:01 PM
clang/lib/CodeGen/CGStmt.cpp
723–727

So interestingly, with __builtin_assume, we have some code that checks for side-effects (https://godbolt.org/z/fo73TvY68) and just doesn't emit the assume at all into IR. I believe we are not able to do that (as side-effects don't prevent attribute-assume from having 'an effect'), so additional work needs to happen to make sure an example like the above has those side effects removed, but considered by the backend.

I'm on the fence as to whether we want to implement this feature at all. As was discussed extensively during the EWG meetings on this: multiple implementers are against this attribute for a variety of reasons, and at least 1 other implementer has stated they might 'implementer veto' this.

I don't quite understand how it works. The feature has been approved for C++2b, but it should have not been approved if there were concerns from implementers.

Agreed, (IMO) it should not have been approved given how many implementer concerns were expressed. But what goes into the standard is whatever gains consensus in the committee, so the committee occasionally runs the risk of voting in something that won't be implemented. We try to avoid it whenever possible, but it still happens with some regularity.

But it seems like not the case with the assume attribute. Could you please elaborate: if you decide to not implement this feature, you will kind of revoke the proposal or just deliberately do not support a part of C++2b in Clang?

To me, it's not clear whether we will or won't implement this particular attribute at the moment. Because Clang aims for compatibility with both GCC and MSVC, I'd like Clang to be the *last* to implement this attribute so we know exactly what we're signing up for in terms of compatibility requirements. We were bitten by no_unique_address and it's sporadic adoption and we do not want to get into the same situation with assumes because (as with no_unique_address) this attribute *cannot be ignored* (it can trigger template instantiations and other things that impact ABI, so a correct program with the attribute might not remain correct without the attribute). So that's not a "no, we'll never do it!" kind of situation so much as a "we're proceeding with extreme caution" situation. If every other C++ implementation supports this attribute, I see no reason why Clang wouldn't as well. But if either MSVC or GCC elect not to implement this attribute, we should understand why and decide our implementation strategy accordingly.

In terms of C++2b, we (the Clang community) have no more chances to change things. A national body comment was filed to consider removing the feature from C++2b or altering it to be acceptable to implementers with concerns and WG21 rejected the comment, so about the only other option left is for companies who are members of a WG21 national body to vote NO on the C++2b DIS.