For floating point vector compares the target mode is an integer mode which accidently was used as register mode when forcing the compare operands into regs.
gcc/ChangeLog: 2016-02-17 Andreas Krebbel <kreb...@linux.vnet.ibm.com> * config/s390/s390.c (s390_expand_vcond): Use the compare operand mode. gcc/testsuite/ChangeLog: 2016-02-17 Andreas Krebbel <kreb...@linux.vnet.ibm.com> * gcc.target/s390/vector/vec-vcond-1.c: New test. --- gcc/config/s390/s390.c | 4 ++-- gcc/testsuite/gcc.target/s390/vector/vec-vcond-1.c | 23 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/s390/vector/vec-vcond-1.c diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index da05a04..cd53b15 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -6329,10 +6329,10 @@ s390_expand_vcond (rtx target, rtx then, rtx els, can be handled by the optimization above but not by the following code. Hence, force them into registers here. */ if (!REG_P (cmp_op1)) - cmp_op1 = force_reg (target_mode, cmp_op1); + cmp_op1 = force_reg (GET_MODE (cmp_op1), cmp_op1); if (!REG_P (cmp_op2)) - cmp_op2 = force_reg (target_mode, cmp_op2); + cmp_op2 = force_reg (GET_MODE (cmp_op2), cmp_op2); s390_expand_vec_compare (result_target, cond, cmp_op1, cmp_op2); diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-vcond-1.c b/gcc/testsuite/gcc.target/s390/vector/vec-vcond-1.c new file mode 100644 index 0000000..ec65c6f --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/vector/vec-vcond-1.c @@ -0,0 +1,23 @@ +/* A const vector operand is forced into a register in + s390_expand_vcond. + This testcase once failed because the target mode (v2di) was picked + for the reg instead of the mode of the other comparison + operand. */ + +/* { dg-do compile { target { s390*-*-* } } } */ +/* { dg-options "-O3 -mzarch -march=z13" } */ + +typedef __attribute__((vector_size(16))) long v2di; +typedef __attribute__((vector_size(16))) double v2df; + +v2di +foo (v2df a) +{ + return a == (v2df){ 0.0, 0.0 }; +} + +v2di +bar (v2df a) +{ + return (v2df){ 1.0, 1.0 } == (v2df){ 0.0, 0.0 }; +} -- 1.9.1