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

commit r15-9486-gb4cf69503bcb32491dbd7ab63fe7f0f9fcdcca38
Author: Martin Jambor <mjam...@suse.cz>
Date:   Tue Apr 15 15:55:34 2025 +0200

    ipa-bit-cp: Fix adjusting value according to mask (PR119803)
    
    In my fix for PR 119318 I put mask calculation in
    ipcp_bits_lattice::meet_with_1 above a final fix to value so that all
    the bits in the value which are meaningless according to mask have
    value zero, which has tripped a validator in PR 119803.  This patch
    fixes that by moving the adjustment down.
    
    Even thought the fix for PR 119318 did a similar thing in
    ipcp_bits_lattice::meet_with, the same is not necessary because that
    code path then feeds the new value and mask to
    ipcp_bits_lattice::set_to_constant which does the final adjustment
    correctly.
    
    In both places, however, Jakup proposed a better way of calculating
    cap_mask and so I have changed it accordingly.
    
    gcc/ChangeLog:
    
    2025-04-15  Martin Jambor  <mjam...@suse.cz>
    
            PR ipa/119803
            * ipa-cp.cc (ipcp_bits_lattice::meet_with_1): Move m_value adjustmed
            according to m_mask below the adjustment of the latter according to
            cap_mask.  Optimize the  calculation of cap_mask a bit.
            (ipcp_bits_lattice::meet_with): Optimize the calculation of 
cap_mask a
            bit.
    
    gcc/testsuite/ChangeLog:
    
    2025-04-15  Martin Jambor  <mjam...@suse.cz>
    
            PR ipa/119803
            * gcc.dg/ipa/pr119803.c: New test.
    
    Co-authored-by: Jakub Jelinek <ja...@redhat.com>

Diff:
---
 gcc/ipa-cp.cc                       |  6 +++---
 gcc/testsuite/gcc.dg/ipa/pr119803.c | 16 ++++++++++++++++
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
index 379fbc5dd637..806c2bdc97f2 100644
--- a/gcc/ipa-cp.cc
+++ b/gcc/ipa-cp.cc
@@ -933,13 +933,13 @@ ipcp_bits_lattice::meet_with_1 (widest_int value, 
widest_int mask,
   m_mask = (m_mask | mask) | (m_value ^ value);
   if (drop_all_ones)
     m_mask |= m_value;
-  m_value &= ~m_mask;
 
-  widest_int cap_mask = wi::bit_not (wi::sub (wi::lshift (1, precision), 1));
+  widest_int cap_mask = wi::shifted_mask <widest_int> (0, precision, true);
   m_mask |= cap_mask;
   if (wi::sext (m_mask, precision) == -1)
     return set_to_bottom ();
 
+  m_value &= ~m_mask;
   return m_mask != old_mask;
 }
 
@@ -1015,7 +1015,7 @@ ipcp_bits_lattice::meet_with (ipcp_bits_lattice& other, 
unsigned precision,
          adjusted_mask |= adjusted_value;
          adjusted_value &= ~adjusted_mask;
        }
-      widest_int cap_mask = wi::bit_not (wi::sub (wi::lshift (1, precision), 
1));
+      widest_int cap_mask = wi::shifted_mask <widest_int> (0, precision, true);
       adjusted_mask |= cap_mask;
       if (wi::sext (adjusted_mask, precision) == -1)
        return set_to_bottom ();
diff --git a/gcc/testsuite/gcc.dg/ipa/pr119803.c 
b/gcc/testsuite/gcc.dg/ipa/pr119803.c
new file mode 100644
index 000000000000..1a7bfd25018a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr119803.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+extern void f(int p);
+int a, b;
+char c;
+static int d(int e) { return !e || a == 1 ? 0 : a / e; }
+static void h(short e) {
+  int g = d(e);
+  f(g);
+}
+void i() {
+  c = 128;
+  h(c);
+  b = d(65536);
+}

Reply via email to