http://gcc.gnu.org/bugzilla/show_bug.cgi?id=61119
--- Comment #3 from Marc Glisse <glisse at gcc dot gnu.org> --- But arg0 = builtin_save_expr (arg0); would prevent from folding REALPART_EXPR. Looking at the fold_unary_loc transforms on REALPART_EXPR, I think it is fine to restrict the special fast-math treatment in fold_builtin_cexp to the case where arg0 is a COMPLEX_EXPR. Then we can extract the arguments directly with TREE_OPERAND and the existing save_expr are enough. @@ -7853,7 +7853,7 @@ fold_builtin_cexp (location_t loc, tree /* In case we can easily decompose real and imaginary parts split cexp to exp (r) * cexpi (i). */ if (flag_unsafe_math_optimizations - && realp) + && TREE_CODE (arg0) == COMPLEX_EXPR) { tree rfn, rcall, icall; @@ -7861,9 +7861,8 @@ fold_builtin_cexp (location_t loc, tree if (!rfn) return NULL_TREE; - imagp = fold_unary_loc (loc, IMAGPART_EXPR, rtype, arg0); - if (!imagp) - return NULL_TREE; + realp = TREE_OPERAND (arg0, 0); + imagp = TREE_OPERAND (arg0, 1); icall = build_call_expr_loc (loc, ifn, 1, imagp); icall = builtin_save_expr (icall);