Do not convert floats to ints in multiple step if trapping math is
enabled.  This might hide some inexact signals.

Also use correct sign (the sign of the target integer type) for the
intermediate steps.  This only affects undefined behaviour (casting
floats to unsigned datatype where the float is negative).

gcc/ChangeLog:

        * tree-vect-stmts.cc (vectorizable_conversion): multi-step
          float to int conversion only with trapping math and correct
          sign.

Signed-off-by: Juergen Christ <jchr...@linux.ibm.com>

Bootstrapped and tested on x84 and s390.  Ok for trunk?

---
 gcc/tree-vect-stmts.cc | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index fdcda0d2abae..2ddd13383193 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -5448,7 +5448,8 @@ vectorizable_conversion (vec_info *vinfo,
            break;
 
          cvt_type
-           = build_nonstandard_integer_type (GET_MODE_BITSIZE (rhs_mode), 0);
+           = build_nonstandard_integer_type (GET_MODE_BITSIZE (rhs_mode),
+                                             TYPE_UNSIGNED (lhs_type));
          cvt_type = get_same_sized_vectype (cvt_type, vectype_in);
          if (cvt_type == NULL_TREE)
            goto unsupported;
@@ -5505,10 +5506,11 @@ vectorizable_conversion (vec_info *vinfo,
       if (GET_MODE_SIZE (lhs_mode) >= GET_MODE_SIZE (rhs_mode))
        goto unsupported;
 
-      if (code == FIX_TRUNC_EXPR)
+      if (code == FIX_TRUNC_EXPR && !flag_trapping_math)
        {
          cvt_type
-           = build_nonstandard_integer_type (GET_MODE_BITSIZE (rhs_mode), 0);
+           = build_nonstandard_integer_type (GET_MODE_BITSIZE (rhs_mode),
+                                             TYPE_UNSIGNED (lhs_type));
          cvt_type = get_same_sized_vectype (cvt_type, vectype_in);
          if (cvt_type == NULL_TREE)
            goto unsupported;
-- 
2.43.5

Reply via email to