]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[ifcombine] fix mask variable test to match use [PR118344]
authorAlexandre Oliva <oliva@adacore.com>
Fri, 10 Jan 2025 12:32:43 +0000 (09:32 -0300)
committerAlexandre Oliva <oliva@gnu.org>
Fri, 10 Jan 2025 12:40:39 +0000 (09:40 -0300)
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.

gcc/gimple-fold.cc
gcc/testsuite/gcc.dg/field-merge-19.c [new file with mode: 0644]

index 0ad92de3a218f5481f81ba2ad123a25d54723be9..20b5024d861db19769d8c546796bb5340772665f 100644 (file)
@@ -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 (file)
index 0000000..5622baa
--- /dev/null
@@ -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;
+  }
+}