https://gcc.gnu.org/g:98ead44962ac7673b7a835c1872ad166195b69bd
commit 98ead44962ac7673b7a835c1872ad166195b69bd
Author: Alexandre Oliva <ol...@adacore.com>
Date:   Thu Jan 9 10:23:50 2025 -0300

    [ifcombine] fix mask variable test to match use [PR118344]
    
    There was a cut&pasto in the rr_and_mask's adjustment to match the
    combined type: the test on whether there was a mask already was
    testing the wrong variable, and then it might crash or otherwise fail
    accessing an undefined mask.  This only hit with checking enabled,
    and rarely at that.
    
    
    for  gcc/ChangeLog
    
            PR tree-optimization/118344
            * gimple-fold.cc (fold_truth_andor_for_ifcombine): Fix typo in
            rr_and_mask's type adjustment test.
    
    for  gcc/testsuite/ChangeLog
    
            PR tree-optimization/118344
            * gcc.dg/field-merge-19.c: New.

Diff:
---
 gcc/gimple-fold.cc                    |  2 +-
 gcc/testsuite/gcc.dg/field-merge-19.c | 41 +++++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index 0ad92de3a218..20b5024d861d 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -8644,7 +8644,7 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree 
truth_type,
                          xlr_bitpos);
       else
        lr_mask = wi::shifted_mask (xlr_bitpos, lr_bitsize, false, rnprec);
-      if (rl_and_mask.get_precision ())
+      if (rr_and_mask.get_precision ())
        rr_mask = wi::lshift (wide_int::from (rr_and_mask, rnprec, UNSIGNED),
                              xrr_bitpos);
       else
diff --git a/gcc/testsuite/gcc.dg/field-merge-19.c 
b/gcc/testsuite/gcc.dg/field-merge-19.c
new file mode 100644
index 000000000000..5622baa52b0a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/field-merge-19.c
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fchecking" } */
+
+/* PR tree-optimization/118344 */
+
+/* This used to ICE attempting to extend a mask variable after testing the
+   wrong mask variable.  */
+
+int d, e, g, h, i, c, j;
+static short k;
+char o;
+static int *p;
+static long *a;
+int b[0];
+int q(int s, int t, int *u, int *v) {
+  for (int f = 0; f < s; f++)
+    if ((t & v[f]) != u[f])
+      return 0;
+  return 1;
+}
+int w(int s, int t) {
+  int l[] = {t, t, t, t}, m[] = {e, e, 3, 1};
+  int n = q(s, d, l, m);
+  return n;
+}
+int x(unsigned s) {
+  unsigned r;
+  if (s >= -1)
+    return 1;
+  r = 10000000;
+  while (s > 1 / r)
+    r /= 2;
+  return g ? 2 : 0;
+}
+void y() {
+  for (;;) {
+    b[w(8, *p)] = h;
+    for (; a + k; j = o)
+      i &= c = x(6) < 0;
+  }
+}

Reply via email to