Index: gcc/gimple-low.c =================================================================== --- gcc/gimple-low.c (revision 271463) +++ gcc/gimple-low.c (working copy) @@ -234,6 +234,22 @@ lower_omp_directive (gimple_stmt_iterato gsi_next (gsi); } +/* Build __asm__ volatile ("" : "=g" (op) : "0" (op)). */ + +static gasm * +gimple_build_barrier (tree op) +{ + vec *inputs = NULL, *outputs = NULL; + vec_safe_push (inputs, + build_tree_list (build_tree_list + (NULL_TREE, build_string (2, "0")), op)); + vec_safe_push (outputs, + build_tree_list (build_tree_list + (NULL_TREE, build_string (3, "=g")), op)); + gasm *fixup = gimple_build_asm_vec ("", inputs, outputs, NULL, NULL); + gimple_asm_set_volatile (fixup, true); + return fixup; +} /* Lower statement GSI. DATA is passed through the recursion. We try to track the fallthruness of statements and get rid of unreachable return @@ -322,9 +338,25 @@ lower_stmt (gimple_stmt_iterator *gsi, s gsi_next (gsi); return; + case GIMPLE_ASSIGN: + if (flag_rounding_math + && !gimple_assign_single_p (stmt)) + { + for (unsigned i = 1; i < gimple_num_ops (stmt); ++i) + { + tree op = gimple_op (stmt, i); + if (!CONSTANT_CLASS_P (op) + && HONOR_SIGN_DEPENDENT_ROUNDING (op)) + { + gasm *fixup = gimple_build_barrier (op); + gsi_insert_before (gsi, fixup, GSI_SAME_STMT); + } + } + } + break; + case GIMPLE_NOP: case GIMPLE_ASM: - case GIMPLE_ASSIGN: case GIMPLE_PREDICT: case GIMPLE_LABEL: case GIMPLE_EH_MUST_NOT_THROW: