It looks like expand_abs and clients use absv_optab even for
FP modes which IMHO is wrong.  The following restricts it
to MODE_INT (not sure what modes the v variants should be present,
but existing checks use MODE_INT and libgcc only provides SImode and
DImode fallbacks).

I've took the liberty to fix the smax expansion path to properly
use negv_optab if required.

Bootstrap and regtest running on x86_64-unknown-linux-gnu, ok?

While in general -ftrap support is in a sorry state we shouldn't
ICE with it ...

Thanks,
Richard.

2014-04-01  Richard Biener  <rguent...@suse.de>

        PR middle-end/60729
        * optabs.c (expand_abs_nojump): Honor flag_trapv only for
        MODE_INTs.  Properly use negv_optab.
        (expand_abs): Likewise.

        * g++.dg/vect/pr60729.cc: New testcase.

Index: gcc/optabs.c
===================================================================
*** gcc/optabs.c        (revision 208988)
--- gcc/optabs.c        (working copy)
*************** expand_abs_nojump (enum machine_mode mod
*** 3384,3390 ****
  {
    rtx temp;
  
!   if (! flag_trapv)
      result_unsignedp = 1;
  
    /* First try to do it with a special abs instruction.  */
--- 3384,3391 ----
  {
    rtx temp;
  
!   if (GET_MODE_CLASS (mode) != MODE_INT
!       || ! flag_trapv)
      result_unsignedp = 1;
  
    /* First try to do it with a special abs instruction.  */
*************** expand_abs_nojump (enum machine_mode mod
*** 3407,3413 ****
      {
        rtx last = get_last_insn ();
  
!       temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0);
        if (temp != 0)
        temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
                             OPTAB_WIDEN);
--- 3408,3415 ----
      {
        rtx last = get_last_insn ();
  
!       temp = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
!                         op0, NULL_RTX, 0);
        if (temp != 0)
        temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
                             OPTAB_WIDEN);
*************** expand_abs (enum machine_mode mode, rtx
*** 3449,3455 ****
  {
    rtx temp, op1;
  
!   if (! flag_trapv)
      result_unsignedp = 1;
  
    temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
--- 3451,3458 ----
  {
    rtx temp, op1;
  
!   if (GET_MODE_CLASS (mode) != MODE_INT
!       || ! flag_trapv)
      result_unsignedp = 1;
  
    temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
Index: gcc/testsuite/g++.dg/vect/pr60729.cc
===================================================================
*** gcc/testsuite/g++.dg/vect/pr60729.cc        (revision 0)
--- gcc/testsuite/g++.dg/vect/pr60729.cc        (working copy)
***************
*** 0 ****
--- 1,10 ----
+ // { dg-do compile }
+ // { dg-additional-options "-ftrapv" }
+ 
+ void doSomething(int dim, double *Y, double *A) 
+ {
+   for (int k=0; k<dim; k++) 
+     Y[k] += __builtin_fabs (A[k]);
+ }
+ 
+ // { dg-final { cleanup-tree-dump "vect" } }

Reply via email to