diff options
author | Jakub Jelinek <jakub@redhat.com> | 2014-02-20 21:39:46 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2014-02-20 21:39:46 +0100 |
commit | aa637f667f9c6b5f96af8c96c956f58041cdb2ba (patch) | |
tree | 9964bf6b2be6a97e7d32e3018422a760985a450d /gcc | |
parent | 004a7e45c695a377acabad42e139b64876558a44 (diff) | |
download | gcc-aa637f667f9c6b5f96af8c96c956f58041cdb2ba.zip gcc-aa637f667f9c6b5f96af8c96c956f58041cdb2ba.tar.gz gcc-aa637f667f9c6b5f96af8c96c956f58041cdb2ba.tar.bz2 |
re PR target/57896 (ICE in expand_expr_real_2)
PR target/57896
* config/i386/i386.c (expand_vec_perm_interleave2): Don't call
gen_reg_rtx if d->testing_p.
(expand_vec_perm_pshufb2, expand_vec_perm_broadcast_1): Return early
if d->testing_p and we will certainly return true.
(expand_vec_perm_even_odd_1): Likewise. Don't call gen_reg_rtx
if d->testing_p.
From-SVN: r207969
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 36 |
2 files changed, 42 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 10ab024..cbdecf8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2014-02-20 Jakub Jelinek <jakub@redhat.com> + + PR target/57896 + * config/i386/i386.c (expand_vec_perm_interleave2): Don't call + gen_reg_rtx if d->testing_p. + (expand_vec_perm_pshufb2, expand_vec_perm_broadcast_1): Return early + if d->testing_p and we will certainly return true. + (expand_vec_perm_even_odd_1): Likewise. Don't call gen_reg_rtx + if d->testing_p. + 2014-02-20 Uros Bizjak <ubizjak@gmail.com> * emit-rtl.c (gen_reg_rtx): Assert that diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index cd14e52..07658c3 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -43411,8 +43411,11 @@ expand_vec_perm_interleave2 (struct expand_vec_perm_d *d) else dfinal.perm[i] = e; } - dremap.target = gen_reg_rtx (dremap.vmode); - dfinal.op0 = gen_lowpart (dfinal.vmode, dremap.target); + if (!d->testing_p) + { + dremap.target = gen_reg_rtx (dremap.vmode); + dfinal.op0 = gen_lowpart (dfinal.vmode, dremap.target); + } dfinal.op1 = dfinal.op0; dfinal.one_operand_p = true; @@ -43845,6 +43848,9 @@ expand_vec_perm_pshufb2 (struct expand_vec_perm_d *d) return false; gcc_assert (!d->one_operand_p); + if (d->testing_p) + return true; + nelt = d->nelt; eltsz = GET_MODE_SIZE (GET_MODE_INNER (d->vmode)); @@ -44053,6 +44059,8 @@ expand_vec_perm_even_odd_1 (struct expand_vec_perm_d *d, unsigned odd) switch (d->vmode) { case V4DFmode: + if (d->testing_p) + break; t1 = gen_reg_rtx (V4DFmode); t2 = gen_reg_rtx (V4DFmode); @@ -44072,6 +44080,8 @@ expand_vec_perm_even_odd_1 (struct expand_vec_perm_d *d, unsigned odd) { int mask = odd ? 0xdd : 0x88; + if (d->testing_p) + break; t1 = gen_reg_rtx (V8SFmode); t2 = gen_reg_rtx (V8SFmode); t3 = gen_reg_rtx (V8SFmode); @@ -44113,6 +44123,8 @@ expand_vec_perm_even_odd_1 (struct expand_vec_perm_d *d, unsigned odd) return expand_vec_perm_pshufb2 (d); else { + if (d->testing_p) + break; /* We need 2*log2(N)-1 operations to achieve odd/even with interleave. */ t1 = gen_reg_rtx (V8HImode); @@ -44134,6 +44146,8 @@ expand_vec_perm_even_odd_1 (struct expand_vec_perm_d *d, unsigned odd) return expand_vec_perm_pshufb2 (d); else { + if (d->testing_p) + break; t1 = gen_reg_rtx (V16QImode); t2 = gen_reg_rtx (V16QImode); t3 = gen_reg_rtx (V16QImode); @@ -44160,7 +44174,10 @@ expand_vec_perm_even_odd_1 (struct expand_vec_perm_d *d, unsigned odd) { struct expand_vec_perm_d d_copy = *d; d_copy.vmode = V4DFmode; - d_copy.target = gen_reg_rtx (V4DFmode); + if (d->testing_p) + d_copy.target = gen_lowpart (V4DFmode, d->target); + else + d_copy.target = gen_reg_rtx (V4DFmode); d_copy.op0 = gen_lowpart (V4DFmode, d->op0); d_copy.op1 = gen_lowpart (V4DFmode, d->op1); if (expand_vec_perm_even_odd_1 (&d_copy, odd)) @@ -44173,6 +44190,9 @@ expand_vec_perm_even_odd_1 (struct expand_vec_perm_d *d, unsigned odd) return false; } + if (d->testing_p) + break; + t1 = gen_reg_rtx (V4DImode); t2 = gen_reg_rtx (V4DImode); @@ -44193,7 +44213,10 @@ expand_vec_perm_even_odd_1 (struct expand_vec_perm_d *d, unsigned odd) { struct expand_vec_perm_d d_copy = *d; d_copy.vmode = V8SFmode; - d_copy.target = gen_reg_rtx (V8SFmode); + if (d->testing_p) + d_copy.target = gen_lowpart (V8SFmode, d->target); + else + d_copy.target = gen_reg_rtx (V8SFmode); d_copy.op0 = gen_lowpart (V8SFmode, d->op0); d_copy.op1 = gen_lowpart (V8SFmode, d->op1); if (expand_vec_perm_even_odd_1 (&d_copy, odd)) @@ -44206,6 +44229,9 @@ expand_vec_perm_even_odd_1 (struct expand_vec_perm_d *d, unsigned odd) return false; } + if (d->testing_p) + break; + t1 = gen_reg_rtx (V8SImode); t2 = gen_reg_rtx (V8SImode); t3 = gen_reg_rtx (V4DImode); @@ -44298,6 +44324,8 @@ expand_vec_perm_broadcast_1 (struct expand_vec_perm_d *d) case V16QImode: /* These can be implemented via interleave. We save one insn by stopping once we have promoted to V4SImode and then use pshufd. */ + if (d->testing_p) + return true; do { rtx dest; |