As demonstrated in the PR, middle-end changes the trappines of the
compare by expanding non-trapping compare to a combination of
setcc/cmove branchless code, e.g. UNLT is split to UNORDERED setcc and
LT cmove.

The above conversion is invalid w.r.t traps, since UNLT doesn't trap
on NaNs, while LT does.

The solution is to avoid the above expansion for compares that would
change their trappines and emit jumps around

2018-07-13  Uros Bizjak  <ubiz...@gmail.com>

    PR target/86511
    * expmed.c (emit_store_flag): Do not emit setcc followed by a
    conditional move when trapping comparison was split to a
    non-trapping one (and vice versa).

Patch was bootstrapped and regression tested on x86_64-linux-gnu
{,-m32}, regression tests on alphaev68-linux-gnu are still running.

OK for mainline and branch?

Uros.
diff --git a/gcc/expmed.c b/gcc/expmed.c
index b01e1946898a..f114eb45e01f 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -6038,6 +6038,11 @@ emit_store_flag (rtx target, enum rtx_code code, rtx 
op0, rtx op1,
       if (!HAVE_conditional_move)
        return 0;
 
+      /* Do not turn a trapping comparison into a non-trapping one.  */
+      if ((code != EQ && code != NE && code != UNEQ && code != LTGT)
+         && flag_trapping_math)
+       return 0;
+
       /* Try using a setcc instruction for ORDERED/UNORDERED, followed by a
         conditional move.  */
       tem = emit_store_flag_1 (subtarget, first_code, op0, op1, mode, 0,

Reply via email to