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? 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