[gcc r12-10055] fold-const: Fix up multiple_of_p [PR112733]

Jakub Jelinek jakub@gcc.gnu.org
Sat Dec 16 00:38:18 GMT 2023


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

commit r12-10055-g4bf040fcd23aaa7d8c4873d1170776ab117bc213
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Wed Nov 29 12:26:50 2023 +0100

    fold-const: Fix up multiple_of_p [PR112733]
    
    We ICE on the following testcase when wi::multiple_of_p is called on
    widest_int 1 and -128 with UNSIGNED.  I still need to work on the
    actual wide-int.cc issue, the latest patch attached to the PR regressed
    bitint-{38,39}.c, so will need to debug that, but there is a clear bug
    on the fold-const.cc side as well - widest_int is a signed representation
    by definition, using UNSIGNED with it certainly doesn't match what was
    intended, because -128 as the second operand effectively means unsigned
    131072 bit 0xfffff............ffff80 integer, not the signed char -128
    that appeared in the source.
    
    In the INTEGER_CST case a few lines above this we already use
        case INTEGER_CST:
          if (TREE_CODE (bottom) != INTEGER_CST || integer_zerop (bottom))
            return false;
          return wi::multiple_of_p (wi::to_widest (top), wi::to_widest (bottom),
                                    SIGNED);
    so I think using SIGNED with widest_int is best there (compared to the
    other choices in the PR).
    
    2023-11-29  Jakub Jelinek  <jakub@redhat.com>
    
            PR middle-end/112733
            * fold-const.cc (multiple_of_p): Pass SIGNED rather than
            UNSIGNED for wi::multiple_of_p on widest_int arguments.
    
            * gcc.dg/pr112733.c: New test.
    
    (cherry picked from commit 5c95bf945c632925efba86dd5dceccdb9da8884c)

Diff:
---
 gcc/fold-const.cc               |  2 +-
 gcc/testsuite/gcc.dg/pr112733.c | 16 ++++++++++++++++
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index d7923974c85..cd410e50d77 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -14273,7 +14273,7 @@ multiple_of_p (tree type, const_tree top, const_tree bottom, bool nowrap)
 	      && TREE_CODE (op2) == INTEGER_CST
 	      && integer_pow2p (bottom)
 	      && wi::multiple_of_p (wi::to_widest (op2),
-				    wi::to_widest (bottom), UNSIGNED))
+				    wi::to_widest (bottom), SIGNED))
 	    return 1;
 
 	  op1 = gimple_assign_rhs1 (stmt);
diff --git a/gcc/testsuite/gcc.dg/pr112733.c b/gcc/testsuite/gcc.dg/pr112733.c
new file mode 100644
index 00000000000..d6f99f76077
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr112733.c
@@ -0,0 +1,16 @@
+/* PR middle-end/112733 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+signed char a, c;
+short b;
+
+void
+foo (void)
+{
+  signed char *e = &a;
+  c = foo != 0;
+  *e &= c;
+  for (; b; --b)
+    *e &= -128;
+}


More information about the Gcc-cvs mailing list