@@ -2246,7 +2246,18 @@ fold_convert_const_int_from_real (enum tree_code code, tree type, const_tree arg
if (! overflow)
val = real_to_integer (&r, &overflow, TYPE_PRECISION (type));
- t = force_fit_type (type, val, -1, overflow | TREE_OVERFLOW (arg1));
+ /* According to IEEE standard, for conversions from floating point to
+ integer. When a NaN or infinite operand cannot be represented in the
+ destination format and this cannot otherwise be indicated, the invalid
+ operation exception shall be signaled. When a numeric operand would
+ convert to an integer outside the range of the destination format, the
+ invalid operation exception shall be signaled if this situation cannot
+ otherwise be indicated. */
+ if (!flag_trapping_math || !overflow)
+ t = force_fit_type (type, val, -1, overflow | TREE_OVERFLOW (arg1));
+ else
+ t = NULL_TREE;
+
return t;
}
@@ -2256,14 +2256,25 @@ simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
switch (code)
{
case FIX:
+ /* According to IEEE standard, for conversions from floating point to
+ integer. When a NaN or infinite operand cannot be represented in
+ the destination format and this cannot otherwise be indicated, the
+ invalid operation exception shall be signaled. When a numeric
+ operand would convert to an integer outside the range of the
+ destination format, the invalid operation exception shall be
+ signaled if this situation cannot otherwise be indicated. */
if (REAL_VALUE_ISNAN (*x))
- return const0_rtx;
+ return flag_trapping_math ? NULL_RTX : const0_rtx;
+
+ if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
+ return NULL_RTX;
/* Test against the signed upper bound. */
wmax = wi::max_value (width, SIGNED);
real_from_integer (&t, VOIDmode, wmax, SIGNED);
if (real_less (&t, x))
- return immed_wide_int_const (wmax, mode);
+ return (flag_trapping_math
+ ? NULL_RTX : immed_wide_int_const (wmax, mode));
/* Test against the signed lower bound. */
wmin = wi::min_value (width, SIGNED);
@@ -2276,13 +2287,17 @@ simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
case UNSIGNED_FIX:
if (REAL_VALUE_ISNAN (*x) || REAL_VALUE_NEGATIVE (*x))
- return const0_rtx;
+ return flag_trapping_math ? NULL_RTX : const0_rtx;
+
+ if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
+ return NULL_RTX;
/* Test against the unsigned upper bound. */
wmax = wi::max_value (width, UNSIGNED);
real_from_integer (&t, VOIDmode, wmax, UNSIGNED);
if (real_less (&t, x))
- return immed_wide_int_const (wmax, mode);
+ return (flag_trapping_math
+ ? NULL_RTX : immed_wide_int_const (wmax, mode));
return immed_wide_int_const (real_to_integer (x, &fail, width),
mode);
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-Wconversion" } */
+/* { dg-options "-Wconversion -fno-trapping-math" } */
typedef char T;
@@ -2,6 +2,7 @@
C99 6.3.1.4(1a) New.
Test integer saturation. */
+/* { dg-options "-fno-trapping-math" } */
#ifndef __STDC_WANT_DEC_FP__
#define __STDC_WANT_DEC_FP__ 1
#endif
@@ -1,6 +1,6 @@
// PR sanitizer/63956
// { dg-do compile }
-// { dg-options "-std=c++14 -fsanitize=undefined,float-divide-by-zero,float-cast-overflow" }
+// { dg-options "-std=c++14 -fsanitize=undefined,float-divide-by-zero" }
#define SA(X) static_assert((X),#X)
#define INT_MIN (-__INT_MAX__ - 1)
@@ -162,8 +162,13 @@ fn11 (double d)
return i * 2;
}
+void
+__attribute__((optimize("no-trapping-math")))
+foo ()
+{
constexpr int r1 = fn11 (3.4);
constexpr int r2 = fn11 (__builtin_inf ()); // { dg-message "in .constexpr. expansion of " }
+}
constexpr int
fn12 (int i)
@@ -3,7 +3,7 @@
gcc/testsuite/gcc.dg/Wconversion-real-integer.c */
/* { dg-do compile }
-/* { dg-options "-Wconversion -ftrack-macro-expansion=0" } */
+/* { dg-options "-Wconversion -ftrack-macro-expansion=0 -fno-trapping-math" } */
/* { dg-require-effective-target int32plus } */
#include <limits.h>
@@ -1,5 +1,7 @@
/* PR optimization/9325 */
+/* { dg-additional-options "-fno-trapping-math" } */
+
#include <limits.h>
extern void abort (void);
@@ -6,7 +6,7 @@
/* { dg-do compile } */
/* { dg-skip-if "doubles are floats,ints are 16bits" { "avr-*-*" } } */
-/* { dg-options " -std=c99 -pedantic -Wconversion " } */
+/* { dg-options " -std=c99 -pedantic -Wconversion -fno-trapping-math" } */
/* { dg-require-effective-target int32plus } */
/* { dg-require-effective-target double64plus } */
@@ -3,7 +3,7 @@
/* { dg-do compile } */
/* { dg-skip-if "doubles are floats,ints are 16bits" { "avr-*-*" } } */
-/* { dg-options "-std=c99 -Wconversion" } */
+/* { dg-options "-std=c99 -Wconversion -fno-trapping-math" } */
/* { dg-require-effective-target int32plus } */
/* { dg-require-effective-target double64plus } */
#include <limits.h>
@@ -2,7 +2,7 @@
constant expressions. */
/* Origin: Joseph Myers <joseph@codesourcery.com> */
/* { dg-do compile } */
-/* { dg-options "-std=iso9899:1990 -pedantic-errors -O2" } */
+/* { dg-options "-std=iso9899:1990 -pedantic-errors -O2 -fno-trapping-math" } */
#include <float.h>
#include <limits.h>
@@ -1,5 +1,6 @@
#include <limits.h>
+/* { dg-options " -fno-trapping-math" } */
void foo (int j)
{
int i1 = (int)(double)1.0 + INT_MAX; /* { dg-warning "integer overflow" } */
new file mode 100644
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftrapping-math -fdump-tree-optimized -fdump-rtl-final" } */
+/* { dg-final { scan-tree-dump-times {(?n)= \(int\)} 3 "optimized" } } */
+/* { dg-final { scan-rtl-dump-times {(?n)\(fix:SI} 3 "final" } } */
+
+int
+foo_ofr ()
+{
+ union {float a;
+ int b;}c;
+ c.b = 0x4f000000;
+ return (int)c.a;
+}
+
+int
+foo_inf ()
+{
+ union {float a;
+ int b;}c;
+ c.b = 0xff800000;
+ return (int)c.a;
+}
+
+int
+foo_nan ()
+{
+ union {float a;
+ int b;}c;
+ c.b = 0xff800001;
+ return (int)c.a;
+}