With LTO we fail to ensure signed and unsigned _BitInt of the same
precision get the same alias set.  Without LTO this is ensured
by c_common_get_alias_set which uses the other signedness variants
alias-set.  With LTO this is complicated by streaming not populating
the bitint_type_cache so a similar approach cannot work.  The
following instead handles this during canonical type merging.
I have still fixed gimple_signed_or_unsigned_type to support _BitInt
and amended gimple_get_alias_set with a comment.

Bootstrapped and tested on x86_64-unknown-linux-gnu.

OK?

Thanks,
Richard.

        PR lto/127922
        * tree.cc (type_with_interoperable_signedness): Return true
        for BITINT_TYPE.
        * gimple.cc (gimple_signed_or_unsigned_type): Properly
        handle BITINT_TYPE.
        (gimple_get_alias_set): Add comment about signed/unsigned
        BITINT_TYPE.

        * gcc.dg/lto/bitint-lto-1_0.c: New testcase.
---
 gcc/gimple.cc                             |  6 +++++-
 gcc/testsuite/gcc.dg/lto/bitint-lto-1_0.c | 22 ++++++++++++++++++++++
 gcc/tree.cc                               | 14 ++++++++++----
 3 files changed, 37 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/lto/bitint-lto-1_0.c

diff --git a/gcc/gimple.cc b/gcc/gimple.cc
index 44fc8df46e4..45e7d8ad7c6 100644
--- a/gcc/gimple.cc
+++ b/gcc/gimple.cc
@@ -2839,6 +2839,9 @@ gimple_signed_or_unsigned_type (bool unsignedp, tree type)
       || TYPE_UNSIGNED (type) == unsignedp)
     return type;
 
+  if (BITINT_TYPE_P (type))
+    return build_bitint_type (TYPE_PRECISION (type), unsignedp);
+
 #define TYPE_OK(node)                                                      \
   (TYPE_MODE (type) == TYPE_MODE (node)                                        
    \
    && TYPE_PRECISION (type) == TYPE_PRECISION (node))
@@ -2923,7 +2926,8 @@ gimple_get_alias_set (tree t)
     return 0;
 
   /* Allow aliasing between signed and unsigned variants of the same
-     type.  We treat the signed variant as canonical.  */
+     type.  We treat the signed variant as canonical.  BITINT_TYPEs
+     are handled by canonical type merging.  */
   if (TREE_CODE (t) == INTEGER_TYPE && TYPE_UNSIGNED (t))
     {
       tree t1 = gimple_signed_type (t);
diff --git a/gcc/testsuite/gcc.dg/lto/bitint-lto-1_0.c 
b/gcc/testsuite/gcc.dg/lto/bitint-lto-1_0.c
new file mode 100644
index 00000000000..c73c79f3ad6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/bitint-lto-1_0.c
@@ -0,0 +1,22 @@
+/* PR/127922 */
+/* { dg-lto-do run } */
+/* { dg-require-effective-target bitint } */
+
+typedef _BitInt(17) S;
+typedef unsigned _BitInt(17) U;
+
+__attribute__((noipa)) S
+f(S *p, U *q)
+{
+  *p = 1;
+  *q = 2;
+  return *p;
+}
+
+int main()
+{
+  S x = 0;
+  S result = f(&x, (U *)&x);
+  if (result != 2)
+    __builtin_abort ();
+}
diff --git a/gcc/tree.cc b/gcc/tree.cc
index 63edf1959ce..e43a2b78c61 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -14211,10 +14211,16 @@ type_with_interoperable_signedness (const_tree type)
      signed char and unsigned char.  Similarly fortran FE builds
      C_SIZE_T as signed type, while C defines it unsigned.  */
 
-  return tree_code_for_canonical_type_merging (TREE_CODE (type))
-          == INTEGER_TYPE
-         && (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node)
-            || TYPE_PRECISION (type) == TYPE_PRECISION (size_type_node));
+  if (tree_code_for_canonical_type_merging (TREE_CODE (type)) == INTEGER_TYPE)
+    return (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node)
+           || TYPE_PRECISION (type) == TYPE_PRECISION (size_type_node));
+
+  /* The C standard allows aliasing between signed and unsigned variants
+     of the same type.  For INTEGER_TYPEs gimple_get_alias_set handles
+     this and this works because the integer type cache is pre-loaded
+     during streaming.  We do not do this for bitint_type_cache, so handle
+     the aliasing via assigning the same canonical type.  */
+  return TREE_CODE (type) == BITINT_TYPE;
 }
 
 /* Return true iff T1 and T2 are structurally identical for what
-- 
2.51.0

Reply via email to