+ /* If divisor is invariant, convert a/b to a*(1/b), allowing reciprocal
+ to be hoisted out of loop, saving expensive divide. */
+ if (pos == MOVE_POSSIBLE
+ && (rhs = TREE_OPERAND (stmt, 1)) != NULL
+ && TREE_CODE (rhs) == RDIV_EXPR
+ && flag_unsafe_math_optimizations
+ && outermost_invariant_loop_expr (TREE_OPERAND (rhs, 1),
+ loop_containing_stmt (stmt)) != NULL
+ && outermost_invariant_loop_expr (rhs,
+ loop_containing_stmt (stmt)) == NULL)
+ {
+ tree lhs, stmt1, stmt2, var, name;
+
+ lhs = TREE_OPERAND (stmt, 0);
+
+ /* stmt must be MODIFY_EXPR. */
+ var = create_tmp_var (TREE_TYPE (rhs), "reciptmp");
+ add_referenced_tmp_var (var);
+
+ stmt1 = build2 (MODIFY_EXPR, void_type_node, var,
+ build2 (RDIV_EXPR, TREE_TYPE (rhs),
+ build_real (TREE_TYPE (rhs), dconst1),
+ TREE_OPERAND (rhs, 1)));
+ name = make_ssa_name (var, stmt1);
+ TREE_OPERAND (stmt1, 0) = name;
+ stmt2 = build2 (MODIFY_EXPR, void_type_node, lhs,
+ build2 (MULT_EXPR, TREE_TYPE (rhs),
+ name, TREE_OPERAND (rhs, 0)));
+
+ /* Replace division stmt with reciprocal and multiply stmts.
+ The multiply stmt is not invariant, so update iterator
+ and avoid rescanning. */
+ bsi_replace (&bsi, stmt1, true);
+ bsi_insert_after (&bsi, stmt2, BSI_NEW_STMT);
+ SSA_NAME_DEF_STMT (lhs) = stmt2;
+
+ /* Continue processing with invariant reciprocal statment. */
+ stmt = stmt1;
+ }
+