This is an archive of the discontinued LLVM Phabricator instance.

[sema] Disallow __builtin_mul_overflow under special condition.
AbandonedPublic

Authored by FreddyYe on Aug 3 2021, 8:01 PM.

Diff Detail

Event Timeline

FreddyYe requested review of this revision.Aug 3 2021, 8:01 PM
FreddyYe created this revision.
Herald added a project: Restricted Project. · View Herald TranscriptAug 3 2021, 8:01 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
FreddyYe updated this revision to Diff 363950.Aug 3 2021, 8:06 PM

update commit message

FreddyYe edited the summary of this revision. (Show Details)Aug 3 2021, 8:07 PM
FreddyYe retitled this revision from [sema] Disallow __builtin_mul_overflow under special condition. to [WIP][sema] Disallow __builtin_mul_overflow under special condition..Aug 3 2021, 10:28 PM
FreddyYe added a comment.EditedAug 3 2021, 10:43 PM

https://gcc.godbolt.org/z/ex9MYan84 is the example bug this patch to fix.
https://gcc.godbolt.org/z/Mjsn5n99h is the reason why I'd like to abort this builtin on this special input combination.

FreddyYe updated this revision to Diff 363991.Aug 4 2021, 12:52 AM

rebase and refactor clang-format and clang-tidy.

This seems lie an incomplete fix. Is this the ONLY configuration that this has trouble with?

Also, the error message seems awkward, @aaron.ballman : Can you suggest a better spelling?

aaron.ballman added inline comments.Aug 4 2021, 6:12 AM
clang/lib/Sema/SemaChecking.cpp
334–335
340

Isn't the result type a pointer type?

clang/test/Sema/builtins-overflow.c
45

Yeah, this diagnostic really doesn't tell me what's going wrong with the code or how to fix it. Do we basically want to prevent using larger-than-64-bit argument types with mixed signs? Or are there other problematic circumstances?

FreddyYe updated this revision to Diff 364154.Aug 4 2021, 9:19 AM
FreddyYe marked 2 inline comments as done.

Address comments. I'll refactor clang-format later. Pls help review the new condition and diagnostic.

FreddyYe retitled this revision from [WIP][sema] Disallow __builtin_mul_overflow under special condition. to [sema] Disallow __builtin_mul_overflow under special condition..Aug 4 2021, 9:19 AM
FreddyYe marked an inline comment as done.

Addressed. THX review!

clang/test/Sema/builtins-overflow.c
45

Yes, let me try to refine. I can explain more what happened to such input combination.
According to gcc's the definition on this builtin: https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
'These built-in functions promote the first two operands into infinite precision signed type and perform multiply on those promoted operands. The result is then cast to the type the third pointer argument points to and stored there.'

Since signing integer has a smaller range than unsigned integer. And now the API in compiler-rt (__muloti4) to checking 128 integer's multiplying is implemented in signed version. So the overflow max absolute value it can check is 2^127. When the result input is larger equal than 128 bits, __muloti4 has no usage. We should prevent this situation for now. Or the backend will crush as the example shows.

I found the input operand doesn't need both of them larger than 64 bits, but just the sum of their larger 128. I'll refine in my patch.

FreddyYe marked an inline comment as done.Aug 4 2021, 9:22 AM
FreddyYe added inline comments.
clang/include/clang/Basic/DiagnosticSemaKinds.td
8351–8353

The new diagnostic is here. Forgot to update tests since I've not rebuilt completely.

FreddyYe updated this revision to Diff 364349.Aug 4 2021, 10:31 PM

update lit test, clang-format, if condition, diagnostic

I don't personally care, but i think this diag doesn't make sense.
What is "backend"? Which one? All of them? What happens when one, but not all of them supports it?
What if i don't intend to codegen this into an assembly, but only want to produce the IR?

I don't personally care, but i think this diag doesn't make sense.
What is "backend"? Which one? All of them? What happens when one, but not all of them supports it?
What if i don't intend to codegen this into an assembly, but only want to produce the IR?

THX for comment. The root cause unable to support this is same as the code added before (line 328-329). I'm suppossing we can view this patch as a supplementary patch of the old one?

FreddyYe edited the summary of this revision. (Show Details)Aug 5 2021, 5:16 AM

I put up a patch for a simple fix for this in the backend. https://reviews.llvm.org/D107581 The generated code is not optimal, but maybe better than frontend workarounds.

I put up a patch for a simple fix for this in the backend. https://reviews.llvm.org/D107581 The generated code is not optimal, but maybe better than frontend workarounds.

Thanks for putting up the backend fix! That's much better than frontend workarounds.

I put up a patch for a simple fix for this in the backend. https://reviews.llvm.org/D107581 The generated code is not optimal, but maybe better than frontend workarounds.

Thanks for putting up the backend fix! That's much better than frontend workarounds.

Looks like I may have opened a small can of worms. In 32-bit mode, a __builtin_mul_overflow of _ExtInt(128) producing a signed result generates a call to _muloti4 which neither compiler-rt or libgcc implement in 32-bit mode. In 64-bit mode only compiler-rt implements _muloti4 for x86-64.

I put up a patch for a simple fix for this in the backend. https://reviews.llvm.org/D107581 The generated code is not optimal, but maybe better than frontend workarounds.

Thanks for putting up the backend fix! That's much better than frontend workarounds.

Looks like I may have opened a small can of worms. In 32-bit mode, a __builtin_mul_overflow of _ExtInt(128) producing a signed result generates a call to _muloti4 which neither compiler-rt or libgcc implement in 32-bit mode. In 64-bit mode only compiler-rt implements _muloti4 for x86-64.

We also lack a proper codegen implementation of 'div' in cases of ints larger than 128. Since _ExtIntis now part of the C23 standard (spelled as _BitInt), we should probably be supporting these as much as we can. I would think we'd have to compose the _muloti and _divoti calls somehow for those.

I put up a patch for a simple fix for this in the backend. https://reviews.llvm.org/D107581 The generated code is not optimal, but maybe better than frontend workarounds.

THX for fix! LGTM.

I put up a patch for a simple fix for this in the backend. https://reviews.llvm.org/D107581 The generated code is not optimal, but maybe better than frontend workarounds.

Thanks for putting up the backend fix! That's much better than frontend workarounds.

Looks like I may have opened a small can of worms. In 32-bit mode, a __builtin_mul_overflow of _ExtInt(128) producing a signed result generates a call to _muloti4 which neither compiler-rt or libgcc implement in 32-bit mode. In 64-bit mode only compiler-rt implements _muloti4 for x86-64.

I think this is also producing references to __mulodi4 for signed long long on 32b targets, see: https://bugs.llvm.org/show_bug.cgi?id=28629.

I put up a patch for a simple fix for this in the backend. https://reviews.llvm.org/D107581 The generated code is not optimal, but maybe better than frontend workarounds.

Thanks for putting up the backend fix! That's much better than frontend workarounds.

Looks like I may have opened a small can of worms. In 32-bit mode, a __builtin_mul_overflow of _ExtInt(128) producing a signed result generates a call to _muloti4 which neither compiler-rt or libgcc implement in 32-bit mode. In 64-bit mode only compiler-rt implements _muloti4 for x86-64.

I think this is also producing references to __mulodi4 for signed long long on 32b targets, see: https://bugs.llvm.org/show_bug.cgi?id=28629.

That's true. I only fixed the case that didn't work with either library.

FreddyYe abandoned this revision.Oct 7 2021, 10:41 PM