(rdiv @0 (negate @1))
(rdiv (negate @0) @1))
+/* convert semantics of round(x) function to floor(x+0.5). */
+/* (x-floor(x)) < (ceil(x)-x) ? floor(x) : ceil(x) --> floor(x+0.5). */
+/* (x-floor(x)) >= (ceil(x)-x) ? ceil(x) : floor(x) --> floor(x+0.5). */
+/* (ceil(x)-x) > (x-floor(x)) ? floor(x) : ceil(x) --> floor(x+0.5). */
+/* (ceil(x)-x) <= (x-floor(x)) ? ceil(x) : floor(x) --> floor(x+0.5). */
+(for op (lt lt lt lt ge ge ge ge)
+ bt (BUILT_IN_FLOORF BUILT_IN_FLOOR BUILT_IN_FLOORL IFN_FLOOR
+ BUILT_IN_CEILF BUILT_IN_CEIL BUILT_IN_CEILL IFN_CEIL)
+ bf (BUILT_IN_CEILF BUILT_IN_CEIL BUILT_IN_CEILL IFN_CEIL
+ BUILT_IN_FLOORF BUILT_IN_FLOOR BUILT_IN_FLOORL IFN_FLOOR)
+ floor (BUILT_IN_FLOORF BUILT_IN_FLOOR BUILT_IN_FLOORL IFN_FLOOR
+ BUILT_IN_FLOORF BUILT_IN_FLOOR BUILT_IN_FLOORL IFN_FLOOR)
+ ceil (BUILT_IN_CEILF BUILT_IN_CEIL BUILT_IN_CEILL IFN_CEIL
+ BUILT_IN_CEILF BUILT_IN_CEIL BUILT_IN_CEILL IFN_CEIL)
+ (simplify
+ (cond (op:c (minus:s SSA_NAME@0 (floor SSA_NAME@0))
+ (minus:s (ceil SSA_NAME@0) SSA_NAME@0))
+ (bt SSA_NAME@0) (bf SSA_NAME@0))
+ (if (!HONOR_SIGNED_ZEROS (type) && !HONOR_SIGN_DEPENDENT_ROUNDING (type))
+ (floor (plus @0 { build_real (type, dconsthalf); })))))
+
(if (flag_unsafe_math_optimizations)
/* Simplify (C / x op 0.0) to x op 0.0 for C != 0, C != Inf/Nan.
Since C / x may underflow to zero, do this only for unsafe math. */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-Ofast" } */
+
+extern void link_error (void);
+
+#define TEST_ROUND(TYPE, FFLOOR, FCEIL) \
+ void round_##FFLOOR##_1 (TYPE x) \
+ { \
+ TYPE t1 = 0; \
+ TYPE t2 = __builtin_##FFLOOR (x + 0.5); \
+ if ((x - __builtin_##FFLOOR (x)) < (__builtin_##FCEIL (x) - x)) \
+ t1 = __builtin_##FFLOOR (x); \
+ else \
+ t1 = __builtin_##FCEIL (x); \
+ if (t1 != t2) \
+ link_error (); \
+ } \
+ void round_##FFLOOR##_2 (TYPE x) \
+ { \
+ TYPE t1 = 0; \
+ TYPE t2 = __builtin_##FFLOOR (x + 0.5); \
+ if ((__builtin_##FCEIL (x) - x) > (x - __builtin_##FFLOOR (x))) \
+ t1 = __builtin_##FFLOOR (x); \
+ else \
+ t1 = __builtin_##FCEIL (x); \
+ if (t1 != t2) \
+ link_error (); \
+ } \
+ void round_##FFLOOR##_3 (TYPE x) \
+ { \
+ TYPE t1 = 0; \
+ TYPE t2 = __builtin_##FFLOOR (x + 0.5); \
+ if ((__builtin_##FCEIL (x) - x) <= (x - __builtin_##FFLOOR (x))) \
+ t1 = __builtin_##FCEIL (x); \
+ else \
+ t1 = __builtin_##FFLOOR (x); \
+ if (t1 != t2) \
+ link_error (); \
+ } \
+ void round_##FFLOOR##_4 (TYPE x) \
+ { \
+ TYPE t1 = 0; \
+ TYPE t2 = __builtin_##FFLOOR (x + 0.5); \
+ if ((x - __builtin_##FFLOOR (x)) >= (__builtin_##FCEIL (x) - x)) \
+ t1 = __builtin_##FCEIL (x); \
+ else \
+ t1 = __builtin_##FFLOOR (x); \
+ if (t1 != t2) \
+ link_error (); \
+ }
+
+TEST_ROUND (float, floorf, ceilf)
+TEST_ROUND (double, floor, ceil)
+TEST_ROUND (long double, floorl, ceill)
+
+/* { dg-final { scan-assembler-not "link_error" } } */