https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66986
Bug ID: 66986 Summary: poor performance of __builtin_isinf on x64 Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: neleai at seznam dot cz Target Milestone: --- Created attachment 36046 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36046&action=edit benchmark. Hi, On x64 floating builtins are considerably slower than equivalent integer code. For easier tracking I split this in per-function basis. Currently libc uses separate inlines to get better performance than buildins so fixing these would be appreciated. As for isinf main problem is how to measure it. Depending on use case parts of it will be optimized away. It tests 12 cases which combination of surrounding expression 1: if (isinf2 (x)) *d+=42; 2: if (isinf2 (x)) abort(); 3: *d += isinf2 (x); where in cases 1 and 3 gcc tries to generate branchless code which does more harm than good, case 2 is common usage to represent if (isinf(x) foo() else bar() Then its tried by placing this expression in function and selectively inlining we measure effect of constructing needed integer constants. Attached benchmark clearly shows that its better to use following inline instead. #define EXTRACT_WORDS64(i, d) \ do { \ int64_t i_; \ asm ("movq %1, %0" : "=rm" (i_) : "x" ((double) (d))); \ (i) = i_; \ } while (0) int I2 isinf2 (double dx) { unsigned long x; EXTRACT_WORDS64(dx, x); if (2 * x == 0xffe0000000000000) return 0; else return (int) (x >> 32); }