Hi,

LTO quickly breaks on Ada code involving floating-point comparisons because 
the Ada compiler defaults to -fnon-call-exceptions -fno-trapping-math (on most 
platforms) and only -fnon-call-exceptions is restored on the LTO side, so you 
can end up with the wrong number of edges on FP comparisons during LTRANS.

Tested on x86_64-suse-linux, OK for the mainline?


2014-10-06  Eric Botcazou  <ebotca...@adacore.com>

        * lto-opts.c (lto_write_options): Handle -fmath-errno, -fsigned-zeros
        and -ftrapping-math.
        * lto-wrapper.c (merge_and_complain): Likewise.
        (run_gcc): Likewise.


2014-10-06  Eric Botcazou  <ebotca...@adacore.com>

        * gnat.dg/lto16.adb: New test.
        * gnat.dg/lto16_pkg.adb: New helper.


-- 
Eric Botcazou
Index: lto-opts.c
===================================================================
--- lto-opts.c	(revision 215843)
+++ lto-opts.c	(working copy)
@@ -115,6 +115,24 @@ lto_write_options (void)
       default:
 	gcc_unreachable ();
       }
+  /* The default -fmath-errno, -fsigned-zeros and -ftrapping-math change
+     depending on the language (they can be disabled by the Ada and Java
+     front-ends).  Pass thru conservative standard settings.  */
+  if (!global_options_set.x_flag_errno_math)
+    append_to_collect_gcc_options (&temporary_obstack, &first_p,
+				   global_options.x_flag_errno_math
+				   ? "-fmath-errno"
+				   : "-fno-math-errno");
+  if (!global_options_set.x_flag_signed_zeros)
+    append_to_collect_gcc_options (&temporary_obstack, &first_p,
+				   global_options.x_flag_signed_zeros
+				   ? "-fsigned-zeros"
+				   : "-fno-signed-zeros");
+  if (!global_options_set.x_flag_trapping_math)
+    append_to_collect_gcc_options (&temporary_obstack, &first_p,
+				   global_options.x_flag_trapping_math
+				   ? "-ftrapping-math"
+				   : "-fno-trapping-math");
   /* We need to merge -f[no-]strict-overflow, -f[no-]wrapv and -f[no-]trapv
      conservatively, so stream out their defaults.  */
   if (!global_options_set.x_flag_wrapv
Index: lto-wrapper.c
===================================================================
--- lto-wrapper.c	(revision 215843)
+++ lto-wrapper.c	(working copy)
@@ -261,6 +261,9 @@ merge_and_complain (struct cl_decoded_op
 	    (*decoded_options)[j] = *foption;
 	  break;
 
+	case OPT_fmath_errno:
+	case OPT_fsigned_zeros:
+	case OPT_ftrapping_math:
 	case OPT_fwrapv:
 	  /* For selected options we can merge conservatively.  */
 	  for (j = 0; j < *decoded_options_count; ++j)
@@ -268,7 +271,10 @@ merge_and_complain (struct cl_decoded_op
 	      break;
 	  if (j == *decoded_options_count)
 	    append_option (decoded_options, decoded_options_count, foption);
-	  /* -fwrapv > -fno-wrapv.  */
+	  /* -fmath-errno > -fno-math-errno,
+	     -fsigned-zeros > -fno-signed-zeros,
+	     -ftrapping-math -> -fno-trapping-math,
+	     -fwrapv > -fno-wrapv.  */
 	  else if (foption->value > (*decoded_options)[j].value)
 	    (*decoded_options)[j] = *foption;
 	  break;
@@ -502,6 +508,9 @@ run_gcc (unsigned argc, char *argv[])
 	case OPT_fpcc_struct_return:
 	case OPT_fshort_double:
 	case OPT_ffp_contract_:
+	case OPT_fmath_errno:
+	case OPT_fsigned_zeros:
+	case OPT_ftrapping_math:
 	case OPT_fwrapv:
 	case OPT_ftrapv:
 	case OPT_fstrict_overflow:
-- { dg-do link }
-- { dg-options "-O -flto" }
-- { dg-require-effective-target lto }

with Lto16_Pkg; use Lto16_Pkg;
with Text_IO; use Text_IO;

procedure Lto16 is
begin
  if F = 0.0 then
    Put_Line ("zero");
  else
    Put_Line ("non-zero");
  end if;
exception
  when others => Put_Line ("exception");
end;
with Ada.Calendar; use Ada.Calendar;

package body Lto16_Pkg is

  function F return Float is
    F1 : Float := Float (Seconds (Clock));
    F2 : Float := Float (Seconds (Clock));
    F  : Float;
  begin
    if F1 > F2 then
      F := (F2 - F1) / 2.0;
    else
      F := (F1 - F2) / 2.0;
    end if;
    return F;
  end;

end Lto16_Pkg;
package Lto16_Pkg is

  function F return Float;

end Lto16_Pkg;

Reply via email to