Message ID | 20141215183952.GQ1667@tucnak.redhat.com |
---|---|
State | New |
Headers | show |
On December 15, 2014 7:39:52 PM CET, Jakub Jelinek <jakub@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 <jakub@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
> 2014-12-15 Jakub Jelinek <jakub@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. OK, thanks.
--- 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); +}