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,