https://gcc.gnu.org/g:d4d75a83007e884bfcd632ea3b3269704496f048

commit r15-3408-gd4d75a83007e884bfcd632ea3b3269704496f048
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Tue Sep 3 10:20:44 2024 +0200

    lower-bitint: Fix up __builtin_{add,sub}_overflow{,_p} bitint lowering 
[PR116501]
    
    The following testcase is miscompiled.  The problem is in the last_ovf step.
    The second operand has signed _BitInt(513) type but has the MSB clear,
    so range_to_prec returns 512 for it (i.e. it fits into unsigned
    _BitInt(512)).  Because of that the last step actually doesn't need to get
    the most significant bit from the second operand, but the code was deciding
    what to use purely from TYPE_UNSIGNED (type1) - if unsigned, use 0,
    otherwise sign-extend the last processed bit; but that in this case was set.
    We don't want to treat the positive operand as if it was negative regardless
    of the bit below that precision, and precN >= 0 indicates that the operand
    is in the [0, inf) range.
    
    2024-09-03  Jakub Jelinek  <ja...@redhat.com>
    
            PR tree-optimization/116501
            * gimple-lower-bitint.cc (bitint_large_huge::lower_addsub_overflow):
            In the last_ovf case, use build_zero_cst operand not just when
            TYPE_UNSIGNED (typeN), but also when precN >= 0.
    
            * gcc.dg/torture/bitint-73.c: New test.

Diff:
---
 gcc/gimple-lower-bitint.cc               |  4 ++--
 gcc/testsuite/gcc.dg/torture/bitint-73.c | 20 ++++++++++++++++++++
 2 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc
index b10593035c36..58deaf253e93 100644
--- a/gcc/gimple-lower-bitint.cc
+++ b/gcc/gimple-lower-bitint.cc
@@ -4192,7 +4192,7 @@ bitint_large_huge::lower_addsub_overflow (tree obj, 
gimple *stmt)
       else
        {
          m_data_cnt = data_cnt;
-         if (TYPE_UNSIGNED (type0))
+         if (TYPE_UNSIGNED (type0) || prec0 >= 0)
            rhs1 = build_zero_cst (m_limb_type);
          else
            {
@@ -4210,7 +4210,7 @@ bitint_large_huge::lower_addsub_overflow (tree obj, 
gimple *stmt)
                  rhs1 = add_cast (m_limb_type, gimple_assign_lhs (g));
                }
            }
-         if (TYPE_UNSIGNED (type1))
+         if (TYPE_UNSIGNED (type1) || prec1 >= 0)
            rhs2 = build_zero_cst (m_limb_type);
          else
            {
diff --git a/gcc/testsuite/gcc.dg/torture/bitint-73.c 
b/gcc/testsuite/gcc.dg/torture/bitint-73.c
new file mode 100644
index 000000000000..1e15f3912574
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/bitint-73.c
@@ -0,0 +1,20 @@
+/* PR tree-optimization/116501 */
+/* { dg-do run { target bitint575 } } */
+/* { dg-options "-std=c23" } */
+/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
+/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */
+
+_BitInt (4) a;
+
+int
+foo (_BitInt(513) b)
+{
+  return __builtin_sub_overflow_p (a, b, (_BitInt (511)) 0);
+}
+
+int
+main ()
+{
+  if (!foo 
(0xffffffffffffffff0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff0000000000000000wb))
+    __builtin_abort ();
+}

Reply via email to