Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[libc] Workaround for gcc complaining about implicit conversions with the ternary ?: operator. #124820

Merged
merged 2 commits into from
Jan 28, 2025

Conversation

lntue
Copy link
Contributor

@lntue lntue commented Jan 28, 2025

Fixes #120427, #122745

This is caused by a -Wconversion false-positive bug in gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101537

@lntue lntue requested a review from nickdesaulniers January 28, 2025 18:54
@llvmbot llvmbot added the libc label Jan 28, 2025
@llvmbot
Copy link
Member

llvmbot commented Jan 28, 2025

@llvm/pr-subscribers-libc

Author: None (lntue)

Changes

Fixes #120427.


Full diff: https://github.com/llvm/llvm-project/pull/124820.diff

1 Files Affected:

  • (modified) libc/src/__support/FPUtil/except_value_utils.h (+8-4)
diff --git a/libc/src/__support/FPUtil/except_value_utils.h b/libc/src/__support/FPUtil/except_value_utils.h
index f8e4e92d3e1fb3..2e58bf2b287fdf 100644
--- a/libc/src/__support/FPUtil/except_value_utils.h
+++ b/libc/src/__support/FPUtil/except_value_utils.h
@@ -81,12 +81,16 @@ template <typename T, size_t N> struct ExceptValues {
         StorageType out_bits = values[i].rnd_towardzero_result;
         switch (fputil::quick_get_round()) {
         case FE_UPWARD:
-          out_bits += sign ? values[i].rnd_downward_offset
-                           : values[i].rnd_upward_offset;
+          if (sign)
+            out_bits += values[i].rnd_downward_offset;
+          else
+            out_bits += values[i].rnd_upward_offset;
           break;
         case FE_DOWNWARD:
-          out_bits += sign ? values[i].rnd_upward_offset
-                           : values[i].rnd_downward_offset;
+          if (sign)
+            out_bits += values[i].rnd_upward_offset;
+          else
+            out_bits += values[i].rnd_downward_offset;
           break;
         case FE_TONEAREST:
           out_bits += values[i].rnd_tonearest_offset;

@nickdesaulniers
Copy link
Member

Can you walk me through here (or in the PR/commit description) what's going on here? Where were the implicit conversions; how does this patch fix them?

@lntue
Copy link
Contributor Author

lntue commented Jan 28, 2025

Can you walk me through here (or in the PR/commit description) what's going on here? Where were the implicit conversions; how does this patch fix them?

For some reason, gcc promotes the ternary

sign ? values[i].rnd_downward_offset : values[i].rnd_upward_offset

to int when adding to out_bits +=, even though all of them are of StorageType, aka uint16_t, here.

And they stop the integer promotion when splitting the ternary operations to conditionals.

@nickdesaulniers
Copy link
Member

Hmm...the relevant parts of the ASTs still look the same between the two cases though.
https://godbolt.org/z/jEo97qPK1

It's still unclear...oh, I think https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101537 is the relevant bug.

Comment on lines +84 to +87
if (sign)
out_bits += values[i].rnd_downward_offset;
else
out_bits += values[i].rnd_upward_offset;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101537, I think you can keep the ternary, and instead work around this as such:

Suggested change
if (sign)
out_bits += values[i].rnd_downward_offset;
else
out_bits += values[i].rnd_upward_offset;
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101537
out_bits = out_bits + (sign ? values[i].rnd_downward_offset : values[i].rnd_upward_offset);

ah, but that's not much more readable. Please cite https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101537 in either a comment in the sources and/or the PR description.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for finding the root cause of it! I updated the comments.

@lntue lntue merged commit ed199c8 into llvm:main Jan 28, 2025
10 of 13 checks passed
@lntue lntue deleted the float16 branch January 28, 2025 21:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[libc] gcc build errors about conversion from 'int' to 'short unsigned int'
3 participants