https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86511
Bug ID: 86511 Summary: Unordered comparisons are expanded with branchless code Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: ubizjak at gmail dot com Target Milestone: --- Following testcase: --cut here-- #include <fenv.h> extern void abort (void); extern void exit (int); volatile double x = __builtin_nan (""); volatile int i; int main (void) { i = !__builtin_isless (x, 1.0); if (fetestexcept (FE_INVALID)) abort (); } --cut here-- compiles for alphaev68-linux-gnu (-O2 -mieee) to brachless code: cvtsts $f12,$f11 cmptun/su $f10,$f11,$f12 ftoit $f12,$2 >> cmptle/su $f11,$f10,$f12 cmpult $31,$2,$2 ftoit $f12,$1 cmovne $1,1,$2 bis $31,$2,$1 ldq $2,i($29) !literal where cmptle generates unwanted exception and the testcase aborts. gcc-7.3.0 generates: cvtsts $f12,$f11 trapb cmptun/su $f10,$f11,$f12 trapb fbne $f12,$L2 cmptle/su $f11,$f10,$f12 trapb fbeq $f12,$L5 $L2: ldq $2,i($29) !literal which avoids cmptle for unordered arguments. Both compilers generate following _.optimized tree dump: x.0_1 ={v} x; _2 = x.0_1 u>= 1.0e+0; _3 = (int) _2; i ={v} _3; gcc-9 expands to branchless code: ... (insn 14 13 15 2 (set (reg:SF 87) (mem/u/c:SF (lo_sum:DI (reg:DI 86) (symbol_ref/u:DI ("*$LC1") [flags 0x2])) [0 S4 A32])) "inf-compare-7.c":16 211 {*movsf} (nil)) (insn 15 14 16 2 (set (reg:DF 85) (float_extend:DF (reg:SF 87))) "inf-compare-7.c":16 144 {*extendsfdf2_ieee} (expr_list:REG_EQUAL (const_double:DF 1.0e+0 [0x0.8p+1]) (nil))) (insn 16 15 17 2 (set (reg:DF 90) (unordered:DF (reg:DF 70 [ x.0_1 ]) (reg:DF 85))) "inf-compare-7.c":16 176 {*cmpdf_internal} (nil)) (insn 17 16 18 2 (set (reg:DI 89) (ne:DI (subreg:DI (reg:DF 90) 0) (const_int 0 [0]))) "inf-compare-7.c":16 149 {*setne_internal} (nil)) (insn 18 17 19 2 (set (reg:SI 88) (subreg:SI (reg:DI 89) 0)) "inf-compare-7.c":16 214 {*movsi} (nil)) (insn 19 18 20 2 (set (reg:DI 92) (high:DI (symbol_ref/u:DI ("*$LC1") [flags 0x2]))) "inf-compare-7.c":16 221 {*movdi} (nil)) (insn 20 19 21 2 (set (reg:SF 93) (mem/u/c:SF (lo_sum:DI (reg:DI 92) (symbol_ref/u:DI ("*$LC1") [flags 0x2])) [0 S4 A32])) "inf-compare-7.c":16 211 {*movsf} (nil)) (insn 21 20 22 2 (set (reg:DF 91) (float_extend:DF (reg:SF 93))) "inf-compare-7.c":16 144 {*extendsfdf2_ieee} (expr_list:REG_EQUAL (const_double:DF 1.0e+0 [0x0.8p+1]) (nil))) (insn 22 21 23 2 (set (reg:DF 94) (le:DF (reg:DF 91) (reg:DF 70 [ x.0_1 ]))) "inf-compare-7.c":16 176 {*cmpdf_internal} (nil)) (insn 23 22 24 2 (set (reg:SI 76) (if_then_else:SI (ne (subreg:DI (reg:DF 94) 0) (const_int 0 [0])) (const_int 1 [0x1]) (reg:SI 88))) "inf-compare-7.c":16 152 {*movsicc_internal} (nil)) ... where gcc-7 expands to: ... (insn 21 20 22 2 (set (reg:SF 97) (mem/u/c:SF (lo_sum:DI (reg:DI 96) (symbol_ref/u:DI ("*$LC1") [flags 0x2])) [2 S4 A32])) "inf-compare-7.c":16 230 {*movsf} (nil)) (insn 22 21 23 2 (set (reg:DF 95) (float_extend:DF (reg:SF 97))) "inf-compare-7.c":16 161 {*extendsfdf2_ieee} (expr_list:REG_EQUAL (const_double:DF 1.0e+0 [0x0.8p+1]) (nil))) (insn 23 22 24 2 (set (reg:DF 98) (unordered:DF (reg:DF 70 [ x.0_1 ]) (reg:DF 95))) "inf-compare-7.c":16 194 {*cmpdf_ieee} (nil)) (jump_insn 24 23 53 2 (set (pc) (if_then_else (ne:CC (reg:DF 98) (const_double:DF 0.0 [0x0.0p+0])) (label_ref 31) (pc))) "inf-compare-7.c":16 205 {*fbcc_normal} (int_list:REG_BR_PROB 100 (nil)) -> 31) ;; succ: 6 [1.0%] ;; 4 [99.0%] (FALLTHRU) ;; basic block 4, loop depth 0, count 0, freq 9900, maybe hot ;; prev block 2, next block 5, flags: (NEW, REACHABLE, RTL, MODIFIED) ;; pred: 2 [99.0%] (FALLTHRU) (note 53 24 25 4 [bb 4] NOTE_INSN_BASIC_BLOCK) (insn 25 53 26 4 (set (reg:DI 100) (high:DI (symbol_ref/u:DI ("*$LC1") [flags 0x2]))) "inf-compare-7.c":16 240 {*movdi} (nil)) (insn 26 25 27 4 (set (reg:SF 101) (mem/u/c:SF (lo_sum:DI (reg:DI 100) (symbol_ref/u:DI ("*$LC1") [flags 0x2])) [2 S4 A32])) "inf-compare-7.c":16 230 {*movsf} (nil)) (insn 27 26 28 4 (set (reg:DF 99) (float_extend:DF (reg:SF 101))) "inf-compare-7.c":16 161 {*extendsfdf2_ieee} (expr_list:REG_EQUAL (const_double:DF 1.0e+0 [0x0.8p+1]) (nil))) (insn 28 27 29 4 (set (reg:DF 102) (le:DF (reg:DF 99) (reg:DF 70 [ x.0_1 ]))) "inf-compare-7.c":16 194 {*cmpdf_ieee} (nil)) (jump_insn 29 28 54 4 (set (pc) (if_then_else (ne:CC (reg:DF 102) (const_double:DF 0.0 [0x0.0p+0])) (label_ref 31) (pc))) "inf-compare-7.c":16 205 {*fbcc_normal} (int_list:REG_BR_PROB 5000 (nil)) -> 31) ...