[ifcombine] fix mask variable test to match use [PR118344]

Message ID orr05bi32p.fsf@lxoliva.fsfla.org
State New
Headers
Series [ifcombine] fix mask variable test to match use [PR118344] |

Commit Message

Alexandre Oliva Jan. 10, 2025, 6:40 a.m. UTC
  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.

Regstrapped on x86_64-linux-gnu.  Ok to install?


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                    |    2 +-
 gcc/testsuite/gcc.dg/field-merge-19.c |   41 +++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/field-merge-19.c
  

Comments

Richard Biener Jan. 10, 2025, 7:50 a.m. UTC | #1
On Fri, 10 Jan 2025, Alexandre Oliva wrote:

> 
> 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.
> 
> Regstrapped on x86_64-linux-gnu.  Ok to install?

OK.

Richard.

> 
> 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                    |    2 +-
>  gcc/testsuite/gcc.dg/field-merge-19.c |   41 +++++++++++++++++++++++++++++++++
>  2 files changed, 42 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.dg/field-merge-19.c
> 
> diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
> index 0ad92de3a218f..20b5024d861db 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 0000000000000..5622baa52b0a3
> --- /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;
> +  }
> +}
> 
>
  

Patch

diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index 0ad92de3a218f..20b5024d861db 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 0000000000000..5622baa52b0a3
--- /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;
+  }
+}