On Wed, Jan 15, 2014 at 10:50 AM, Steve Ellcey <sell...@mips.com> wrote:
> The test c-c++-common/cilk-plus/AN/builtin_func_double2.c is failing on MIPS
> when compiled with C++ but not when compiled with C because GCC is generating
> an illegal assembly language instruction during the C++ compilation.  The
> reason this works in C but fails for C++ is because the
> __sec_reduce_any_nonzero call is creating a conditional assignment expression
> and in C the condition used in that expression is type integer but in C++
> it is type boolean.
>
> In c/c-array-notation.c we have:
>
>     case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO:
>     case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_NONZERO:
>     case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO:
>     case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_NONZERO:
>       new_var_type = integer_type_node;
>       break;
>
> new_var_type is used as the type of a variable used as the condition 'C' in
> "foo = C ? 1 : 0".
>
> But in C++ we use a boolean type instead of an integer type for the
> condition.  Thus, in cp/cp-array-notation.c we have:
>
>     case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO:
>     case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO:
>     case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_NONZERO:
>     case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_NONZERO:
>       new_var_type = boolean_type_node;
>       break;
>
> The reason this matters is that on MIPS a floating point conditional
> register ($fcc0) can hold a boolean type but not an integer type
> but this register cannot be used in a conditional move.  So when the
> C++ code is generated GCC will create an instruction that looks like:
>
>         movz $4,$6,$fcc0
>
> And this is illegal.  I would like to fix this by using integer_type_node
> for C++ like C is doing and I have attached a tested patch that does
> this.  It fixes the bug and caused no regressions on mips-mti-linux-gnu.
>
> One could argue that a better fix would be checking the legality of the
> conditional move in expr.c and not generating an illegal one, however the
> current GCC conditional move code checks for the type (mode) of the value
> being moved but has no check on the type or mode of the conditional being
> used to control the move so doing this would probably mean adding a new
> target predicate.  Since no other tests are failing with this problem I
> would rather tweak the cilk code instead.
>
> Tested on mips-mti-linux-gnu with no regressions.
>
> OK to checkin?

No, this really should be fixed in the target side.  In fact for MIPS
there is an instruction which does a conditional move based on the FP
CC register (movt/movf).  So you need to look into why the wrong
pattern is being selected instead.

Thanks,
Andrew Pinski

>
> Steve Ellcey
> sell...@mips.com
>
>
> 2014-01-15  Steve Ellcey  <sell...@mips.com>
>
>         PR target/59462
>         * cp-array-notation.c (expand_sec_reduce_builtin): Change conditional
>         type.
>
>
> diff --git a/gcc/cp/cp-array-notation.c b/gcc/cp/cp-array-notation.c
> index 65b8bcb..6cba0b4 100644
> --- a/gcc/cp/cp-array-notation.c
> +++ b/gcc/cp/cp-array-notation.c
> @@ -274,7 +274,7 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree 
> *new_var)
>      case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO:
>      case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_NONZERO:
>      case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_NONZERO:
> -      new_var_type = boolean_type_node;
> +      new_var_type = integer_type_node;
>        break;
>      case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND:
>      case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND:
>

Reply via email to