aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2025-04-15 15:55:34 +0200
committerMartin Jambor <jamborm@gcc.gnu.org>2025-04-15 15:56:17 +0200
commitb4cf69503bcb32491dbd7ab63fe7f0f9fcdcca38 (patch)
treec5f95453c5ce314bf49d5f5810a6b84e78807ca6
parent074b2b0f91f948fe3488ada91ec6a8576c684dea (diff)
downloadgcc-b4cf69503bcb32491dbd7ab63fe7f0f9fcdcca38.zip
gcc-b4cf69503bcb32491dbd7ab63fe7f0f9fcdcca38.tar.gz
gcc-b4cf69503bcb32491dbd7ab63fe7f0f9fcdcca38.tar.bz2
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 <mjambor@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 <mjambor@suse.cz> PR ipa/119803 * gcc.dg/ipa/pr119803.c: New test. Co-authored-by: Jakub Jelinek <jakub@redhat.com>
-rw-r--r--gcc/ipa-cp.cc6
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pr119803.c16
2 files changed, 19 insertions, 3 deletions
diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
index 379fbc5..806c2bd 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 0000000..1a7bfd2
--- /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);
+}