Hi! Most of this probably doesn't need explanation, just the expand_sdiv_pow2 change - shift_cost only tracks shift counts to MAX_BITS_PER_WORD (but, for consistency between e.g. i?86 and x86_64 -m32 we'd better use BITS_PER_WORD instead as in most other expmed.c places), when called with larger values it is out of bounds access. I believe for multiword accesses, even when we don't have costs for it, and masking will be typically cheaper (e.g. for double word you need two word ANDs, while for double word shift unless there is a specialized instruction for double word shifts one needs either a library routine or 3 shifts and IOR).
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2014-07-02 Jakub Jelinek <ja...@redhat.com> * gcov-io.c (gcov_read_words): Don't call memmove if excess is 0. * data-streamer-in.c (streamer_read_hwi): Shift UHWI 1 instead of HWI 1 and negate the unsigned value. * expmed.c (expand_sdiv_pow2): For modes wider than word always use AND instead of shift. * wide-int-print.cc (print_decs): Negate UHWI instead of HWI. c-family/ * c-ada-spec.c (dump_ada_nodes): Don't call qsort if comments->count <= 1, as comments->entries might be NULL. --- gcc/gcov-io.c.jj 2014-05-30 10:51:15.000000000 +0200 +++ gcc/gcov-io.c 2014-06-30 12:09:54.276063826 +0200 @@ -489,14 +489,15 @@ gcov_read_words (unsigned words) if (excess < words) { gcov_var.start += gcov_var.offset; -#if IN_LIBGCOV if (excess) { +#if IN_LIBGCOV memcpy (gcov_var.buffer, gcov_var.buffer + gcov_var.offset, 4); - } #else - memmove (gcov_var.buffer, gcov_var.buffer + gcov_var.offset, excess * 4); + memmove (gcov_var.buffer, gcov_var.buffer + gcov_var.offset, + excess * 4); #endif + } gcov_var.offset = 0; gcov_var.length = excess; #if IN_LIBGCOV --- gcc/data-streamer-in.c.jj 2014-01-03 11:40:29.000000000 +0100 +++ gcc/data-streamer-in.c 2014-06-30 11:59:52.000221301 +0200 @@ -174,7 +174,7 @@ streamer_read_hwi (struct lto_input_bloc if ((byte & 0x80) == 0) { if ((shift < HOST_BITS_PER_WIDE_INT) && (byte & 0x40)) - result |= - ((HOST_WIDE_INT)1 << shift); + result |= - (HOST_WIDE_INT_1U << shift); return result; } --- gcc/expmed.c.jj 2014-06-27 09:03:01.000000000 +0200 +++ gcc/expmed.c 2014-06-30 11:46:00.947593030 +0200 @@ -3795,8 +3795,9 @@ expand_sdiv_pow2 (enum machine_mode mode temp = gen_reg_rtx (mode); temp = emit_store_flag (temp, LT, op0, const0_rtx, mode, 0, -1); - if (shift_cost (optimize_insn_for_speed_p (), mode, ushift) - > COSTS_N_INSNS (1)) + if (GET_MODE_BITSIZE (mode) >= BITS_PER_WORD + || shift_cost (optimize_insn_for_speed_p (), mode, ushift) + > COSTS_N_INSNS (1)) temp = expand_binop (mode, and_optab, temp, gen_int_mode (d - 1, mode), NULL_RTX, 0, OPTAB_LIB_WIDEN); else --- gcc/c-family/c-ada-spec.c.jj 2014-05-11 22:20:59.000000000 +0200 +++ gcc/c-family/c-ada-spec.c 2014-06-30 12:05:06.931560475 +0200 @@ -636,8 +636,9 @@ dump_ada_nodes (pretty_printer *pp, cons comments = cpp_get_comments (parse_in); /* Sort the comments table by sloc. */ - qsort (comments->entries, comments->count, sizeof (cpp_comment), - compare_comment); + if (comments->count > 1) + qsort (comments->entries, comments->count, sizeof (cpp_comment), + compare_comment); /* Interleave comments and declarations in line number order. */ i = j = 0; --- gcc/wide-int-print.cc.jj 2014-05-11 22:21:04.000000000 +0200 +++ gcc/wide-int-print.cc 2014-06-30 12:02:11.349485371 +0200 @@ -62,7 +62,8 @@ print_decs (const wide_int_ref &wi, char || (wi.get_len () == 1)) { if (wi::neg_p (wi)) - sprintf (buf, "-" HOST_WIDE_INT_PRINT_UNSIGNED, -wi.to_shwi ()); + sprintf (buf, "-" HOST_WIDE_INT_PRINT_UNSIGNED, + -(unsigned HOST_WIDE_INT) wi.to_shwi ()); else sprintf (buf, HOST_WIDE_INT_PRINT_DEC, wi.to_shwi ()); } Jakub