On December 15, 2014 7:39:52 PM CET, Jakub Jelinek <ja...@redhat.com> wrote: >Hi! > >This patch fixes ICE when cmp_mode is some vector mode, creating >comparison of a vector with scalar const0_rtx is a bad idea. > >Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK Thanks, Richard. >2014-12-15 Jakub Jelinek <ja...@redhat.com> > > PR rtl-optimization/64316 > * simplify-rtx.c (simplify_relational_operation_1): For > (eq/ne (and x y) x) and (eq/ne (and x y) y) optimizations use > CONST0_RTX instead of const0_rtx. > > * gcc.dg/pr64316.c: New test. > >--- gcc/simplify-rtx.c.jj 2014-12-12 13:39:50.000000000 +0100 >+++ gcc/simplify-rtx.c 2014-12-15 16:40:33.371447749 +0100 >@@ -4561,7 +4561,8 @@ simplify_relational_operation_1 (enum rt >rtx not_y = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 1), >cmp_mode); > rtx lhs = simplify_gen_binary (AND, cmp_mode, not_y, XEXP (op0, 0)); > >- return simplify_gen_relational (code, mode, cmp_mode, lhs, >const0_rtx); >+ return simplify_gen_relational (code, mode, cmp_mode, lhs, >+ CONST0_RTX (cmp_mode)); > } > > /* Likewise for (eq/ne (and x y) y). */ >@@ -4573,7 +4574,8 @@ simplify_relational_operation_1 (enum rt >rtx not_x = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 0), >cmp_mode); > rtx lhs = simplify_gen_binary (AND, cmp_mode, not_x, XEXP (op0, 1)); > >- return simplify_gen_relational (code, mode, cmp_mode, lhs, >const0_rtx); >+ return simplify_gen_relational (code, mode, cmp_mode, lhs, >+ CONST0_RTX (cmp_mode)); > } > >/* (eq/ne (bswap x) C1) simplifies to (eq/ne x C2) with C2 swapped. */ >--- gcc/testsuite/gcc.dg/pr64316.c.jj 2014-12-15 16:46:47.428982539 >+0100 >+++ gcc/testsuite/gcc.dg/pr64316.c 2014-12-15 16:46:29.000000000 +0100 >@@ -0,0 +1,42 @@ >+/* PR rtl-optimization/64316 */ >+/* { dg-do compile } */ >+/* { dg-options "-O3" } */ >+/* { dg-additional-options "-mavx2" { target { i?86-*-* x86_64-*-* } } >} */ >+ >+struct S >+{ >+ unsigned int s; >+ unsigned long w[]; >+}; >+ >+struct S **s; >+ >+int >+foo (struct S *x, struct S *y, struct S *z) >+{ >+ unsigned int i; >+ unsigned long *a, *b, *c; >+ int r = 0; >+ for (a = x->w, b = y->w, c = z->w, i = 0; i < x->s; i++, a++) >+ { >+ unsigned long d = *b++ & *c++; >+ if (*a != d) >+ { >+ r = 1; >+ *a = d; >+ } >+ } >+ return r; >+} >+ >+void >+bar (int x) >+{ >+ int p = x - 1; >+ do >+ { >+ foo (s[x], s[x], s[p]); >+ p--; >+ } >+ while (p > 0); >+} > > Jakub