This is an archive of the discontinued LLVM Phabricator instance.

clang: Fix handling of __builtin_elementwise_copysign
ClosedPublic

Authored by arsenm on Dec 23 2022, 3:13 PM.

Details

Summary
I realized the handling of copysign made no sense at all.
Only the type of the first operand should really matter, and
it should not perform a conversion between them.

Also fixes misleading errors and producing broken IR for
integers.

We could accept different FP types for the sign argument,
if the intrinsic permitted different types like the DAG node.
As it is we would need to insert a cast, which could have
other effects (like trapping on snan) which should not happen
for a copysign.

Diff Detail

Event Timeline

arsenm created this revision.Dec 23 2022, 3:13 PM
Herald added a project: Restricted Project. · View Herald TranscriptDec 23 2022, 3:13 PM
arsenm requested review of this revision.Dec 23 2022, 3:13 PM

1 nit, and 1 trying to see what is going on. I don't have a good feeling what the purpose of this builtin is, nor whether it matches the desire/intent of this builtin, I'm hopeful one of the other reviewers has the ability to check that.

clang/lib/Sema/SemaChecking.cpp
2048

you can just do "return S.Diag", which always returns 'true'. This will save a line, and the need for curleys.

2658

What is the point of the Unary Conversions here? Its a touch surprising to see a builtin do that? Note that it does quite a bit of FP related conversions, so are you sure you want those?

arsenm added a comment.Jan 5 2023, 7:55 AM

1 nit, and 1 trying to see what is going on. I don't have a good feeling what the purpose of this builtin is,

The point of every builtin is direct access to llvm intrinsics, in this case llvm.copysign. I need it on vectors and not the set of 3 scalars it handles now.

clang/lib/Sema/SemaChecking.cpp
2658

Copied from the other elementwise intrinsics, and this is at the edges of my frontend knowledge (I guess it's to avoid qualifiers mattering?). The tests seem to behave as I expect

1 nit, and 1 trying to see what is going on. I don't have a good feeling what the purpose of this builtin is,

The point of every builtin is direct access to llvm intrinsics, in this case llvm.copysign. I need it on vectors and not the set of 3 scalars it handles now.

I'm unfamiliar with the semantics of that builtin other than what i can read here: https://llvm.org/docs/LangRef.html#llvm-copysign-intrinsic

clang/lib/Sema/SemaChecking.cpp
2658

It really depends on what behavior you're looking to get out of this. UnaryConversions are usually for operators, not 'function like' things, so it is a touch jarring to me.

I guess I would have expected DefaultFunctionArrayLValueConversion (which calls DefaultLValueConversion after doing array-to-pointer conversions).

If the idea is for this builtin to act more like a variadic arg, I'd expect to see DefaultArgumentPromotion.

@aaron.ballman I think is smarter than me in regards to how these should work, so perhaps he can comment here?

I DO note one of the things that UsualUnaryConversions is doing is removing 'half' types on platforms without a 'native' half type. I would expect those sorts of conversions wouldn't be right?

2672

curleys not used for single-statement if-statement bodies.

aaron.ballman added inline comments.Jan 5 2023, 8:38 AM
clang/lib/Sema/SemaChecking.cpp
2658

I think we need to do the usual unary conversions because that's what handles the floating point evaluation method stuff, and if I'm reading this properly, it seems that copysign() does perform these conversions: https://godbolt.org/z/eWjEqvvjd. I would not expect to handle this with default argument promotion given the signature of copysign().

erichkeane added inline comments.Jan 5 2023, 8:40 AM
clang/lib/Sema/SemaChecking.cpp
2658

Got it, thanks for the clarification.

arsenm added inline comments.Jan 5 2023, 9:09 AM
clang/lib/Sema/SemaChecking.cpp
2672

It covers 3 lines, it should have braces

erichkeane added inline comments.Jan 5 2023, 9:10 AM
clang/lib/Sema/SemaChecking.cpp
2672
arsenm added inline comments.Jan 5 2023, 11:24 AM
clang/lib/Sema/SemaChecking.cpp
2672

Also says 'Similarly, braces should be used when a single-statement body is complex enough that it becomes difficult to see where the block containing the following statement began.'

Which is any case where it covers multiple lines

arsenm added inline comments.Jan 5 2023, 11:25 AM
clang/lib/Sema/SemaChecking.cpp
2672

Plus I'd go by clang-format does not add braces here

erichkeane added inline comments.Jan 5 2023, 11:27 AM
clang/lib/Sema/SemaChecking.cpp
2672

I don't see the 'difficult to see when the following statement began' bit in this code, particularly with the new line.

By policy, I don't think we have curleys here. I'm of the opinion of 'almost always curleys', but our policy.

aaron.ballman added inline comments.Jan 5 2023, 11:38 AM
clang/lib/Sema/SemaChecking.cpp
2672

I think a strict reading of our policy is that the preference is to elide the braces in this case, but FWIW, I'm perfectly fine with leaving the braces in as they (ever-so-slightly) improve the readability of the code given that it spans multiple source lines.

I still want someone more familiar with LLVM to review this, but code wise I think we're ok (modulus 1 suggestion I made in checkFPMathBuiltinElementType).

clang/lib/Sema/SemaChecking.cpp
2672

Thanks, I really dislike that it is 'single statement' with some vague extensions, but not my decision :/

arsenm updated this revision to Diff 486643.Jan 5 2023, 11:44 AM

Return S.Diag

ping, I think this should get in before the branch date to fix the current broken behavior before this is in a release

This revision is now accepted and ready to land.Jan 10 2023, 9:57 AM