https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80584
Bug ID: 80584 Summary: Combine some float tests using bit ops Product: gcc Version: 8.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: enhancement Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: glisse at gcc dot gnu.org Target Milestone: --- Target: x86_64-*-* Some (ieee) float tests amount to bit operations, and some of the usual optimizations on bit operations may thus apply. d == 0 tests if all non-sign bits are 0, so (d1 == 0) & (d2 == 0) is equivalent to (d1 | d2) == 0 !isfinite tests if the exponent is all ones, so isfinite(d1) | isfinite(d2) is equivalent to isfinite(d1 & d2) (I may have gotten one of those wrong, but something similar should work) on platforms like x86 (SSE) that provide bit operations for floats, this could be an interesting optimization. I don't think d1&d2 can produce sNaN unless d1 or d2 is already sNaN, but d1|d2 can, so care might be needed there. Doing it in gimple is problematic, after querying the target to see if it provides IOR for double, we would have to cast to some integer type before doing the bit operation then back, and trust that float bitops will be generated, which works better since Jakub worked on it but still not perfectly. Doing the transformation too early may also hinder other optimizations by obfuscating the condition. After expansion, the representation becomes quite large (setting the flags, reading the flags, if_then_else, etc) and there is no hope for combine to notice some special pattern. I expect the most convenient place for this transformation would be during expansion, when we get as input 3 simple statements and can directly write the output using float bitops (if available).