https://gcc.gnu.org/g:4b0443361a82ef89d519c9ae6d4d3bec74376e8f

commit r14-9694-g4b0443361a82ef89d519c9ae6d4d3bec74376e8f
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Wed Mar 27 19:38:06 2024 +0100

    c-family: Cast __atomic_load_*/__atomic_exchange_* result to _BitInt rather 
then VCE it [PR114469]
    
    As written in the PR, torture/bitint-64.c test fails with -O2 -flto
    and the reason is that on _BitInt arches where the padding bits
    are undefined, the padding bits in the _Atomic vars are also undefined,
    but when __atomic_load or __atomic_exchange on a _BitInt _Atomic variable
    with some padding bits is lowered into __atomic_load_{1,2,4,8,16} or
    __atomic_exchange_*, the mode precision unsigned result is VIEW_CONVERT_EXPR
    converted to _BitInt and because of the VCE nothing actually sign/zero
    extends it as needed for later uses - the var is no longer addressable and
    expansion assumes such automatic vars are properly extended.
    
    The following patch fixes that by using NOP_EXPR on it (the
    VIEW_CONVERT_EXPR after it will then be optimized away during
    gimplification, didn't want to repeat it in the code as else result = build1
    (VIEW_CONVERT_EXPR, ...); twice.
    
    2024-03-27  Jakub Jelinek  <ja...@redhat.com>
    
            PR tree-optimization/114469
            * c-common.cc (resolve_overloaded_builtin): For _BitInt result
            on !extended targets convert result to the _BitInt type before
            using VIEW_CONVERT_EXPR.

Diff:
---
 gcc/c-family/c-common.cc | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 48844b17f77..6fa8243b02b 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -8461,7 +8461,19 @@ resolve_overloaded_builtin (location_t loc, tree 
function,
        if (new_return)
          {
            /* Cast function result from I{1,2,4,8,16} to the required type.  */
-           result = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (new_return), result);
+           if (TREE_CODE (TREE_TYPE (new_return)) == BITINT_TYPE)
+             {
+               struct bitint_info info;
+               unsigned prec = TYPE_PRECISION (TREE_TYPE (new_return));
+               targetm.c.bitint_type_info (prec, &info);
+               if (!info.extended)
+                 /* For _BitInt which has the padding bits undefined
+                    convert to the _BitInt type rather than VCE to force
+                    zero or sign extension.  */
+                 result = build1 (NOP_EXPR, TREE_TYPE (new_return), result);
+             }
+           result
+             = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (new_return), result);
            result = build2 (MODIFY_EXPR, TREE_TYPE (new_return), new_return,
                             result);
            TREE_SIDE_EFFECTS (result) = 1;

Reply via email to