Hello, With -mno-ieee-fp, or when that flag is implied by other flags such as -ffast-math, i386 backend will use ordered rather than unordered comparisons (fcom* instead of fucom*, or their SSE counterparts).
Expansion of several rounding builtins currently uses unordered comparisons always, unconditionally. That looks historical, or an oversight rather than deliberate, and the following patch makes expansion use ix86_fp_compare_mode like in other places. Bootstrapped and regtested on x86_64-linux. 2013-10-11 Alexander Monakov <amona...@ispras.ru> * config/i386/i386.c (ix86_expand_sse_compare_and_jump): Use mode provided by ix86_fp_compare_mode instead of CCFPUmode. testsuite/: * gcc.target/i386/builtin-ucmp.c: New test. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 21fc531..69650ff 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -38263,6 +38263,7 @@ static rtx ix86_expand_sse_compare_and_jump (enum rtx_code code, rtx op0, rtx op1, bool swap_operands) { + enum machine_mode fpcmp_mode = ix86_fp_compare_mode (code); rtx label, tmp; if (swap_operands) @@ -38273,9 +38274,9 @@ ix86_expand_sse_compare_and_jump (enum rtx_code code, rtx op0, rtx op1, } label = gen_label_rtx (); - tmp = gen_rtx_REG (CCFPUmode, FLAGS_REG); + tmp = gen_rtx_REG (fpcmp_mode, FLAGS_REG); emit_insn (gen_rtx_SET (VOIDmode, tmp, - gen_rtx_COMPARE (CCFPUmode, op0, op1))); + gen_rtx_COMPARE (fpcmp_mode, op0, op1))); tmp = gen_rtx_fmt_ee (code, VOIDmode, tmp, const0_rtx); tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, gen_rtx_LABEL_REF (VOIDmode, label), pc_rtx); diff --git a/gcc/testsuite/gcc.target/i386/builtin-ucmp.c b/gcc/testsuite/gcc.target/i386/builtin-ucmp.c new file mode 100644 index 0000000..709804c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/builtin-ucmp.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ffast-math -mfpmath=sse -msse2" } */ + +double foo(double a) +{ + return __builtin_round(a); +} + +/* { dg-final { scan-assembler-not "ucom" } } */