diff mbox series

sccvn: Handle bitfields in push_partial_def [PR93582]

Message ID 20200222074132.GW2155@tucnak
State New
Headers show
Series sccvn: Handle bitfields in push_partial_def [PR93582] | expand

Commit Message

Jakub Jelinek Feb. 22, 2020, 7:41 a.m. UTC
Hi!

The following patch adds support for bitfields to push_partial_def.
Previously pd.offset and pd.size were counted in bytes and maxsizei
in bits, now everything is counted in bits.

Not really sure how much of the further code can be outlined and moved, e.g. 
the full def and partial def code doesn't have pretty much anything in
common (the partial defs case basically have some load bit range and a set
of store bit ranges that at least partially overlap and we need to handle
all the different cases, like negative pd.offset or non-negative, little vs. 
bit endian, size so small that we need to preserve original bits on both
sides of the byte, size that fits or is too large.
Perhaps the storing of some value into a middle of existing buffer (i.e.
what push_partial_def now does in the loop) could, but the candidate for
sharing would be most likely store-merging rather than the other spots in
sccvn, and I think it is better not to touch store-merging at this stage.

Yes, I've thought about trying to do everything in place, but the code is
quite hard to understand and get right already now and if we tried to do the
optimize on the fly, it would need more special cases and would for gcov
coverage need more testcases to cover it.  Most of the time the sizes will
be small.  Furthermore, for bitfields native_encode_expr stores actually
number of bytes in the mode and not say actual bitsize rounded up to bytes,
so it wouldn't be just a matter of saving/restoring bytes at the start and
end, but we might need even 7 further bytes e.g. for __int128 bitfields.
Perhaps we could have just a fast path for the case where everything is byte
aligned and (for integral types the mode bitsize is equal to the size too)?

Bootstrapped/regtested on {x86_64,i686,powerpc64{,le}}-linux, on
powerpc64-linux with -m32/-m64 testing, on {x86_64,i686}-linux
bootstrap/regtests together I've also gathered statistics, where the
new code (where something in the partial defs handling wasn't byte
aligned/sized and still found a constant) triggered 5266 times,
attached is sort | uniq -c | sort -n list of those, i.e. first column
is number of times it hit in the same file/function/wordsize (across
the 2 bootstraps/regtests), second is BITS_PER_WORD, third is filename
and last is current_function_name ().

Ok for trunk?

2020-02-22  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/93582
	* tree-ssa-sccvn.c (vn_walk_cb_data::push_partial_def): Consider
	pd.offset and pd.size to be counted in bits rather than bytes, add
	support for maxsizei that is not a multiple of BITS_PER_UNIT and
	handle bitfield stores and loads.
	(vn_reference_lookup_3): Don't call ranges_known_overlap_p with
	uncomparable quantities - bytes vs. bits.  Allow push_partial_def
	on offsets/sizes that aren't multiple of BITS_PER_UNIT and adjust
	pd.offset/pd.size to be counted in bits rather than bytes.
	Formatting fix.  Rename shadowed len variable to buflen.

	* gcc.dg/tree-ssa/pr93582-4.c: New test.
	* gcc.dg/tree-ssa/pr93582-5.c: New test.
	* gcc.dg/tree-ssa/pr93582-6.c: New test.
	* gcc.dg/tree-ssa/pr93582-7.c: New test.
	* gcc.dg/tree-ssa/pr93582-8.c: New test.


	Jakub
1 32 /home/jakub/src/gcc/gcc/testsuite/gcc.dg/tree-ssa/pr93582-4.c foo
      1 32 /home/jakub/src/gcc/gcc/testsuite/gcc.dg/tree-ssa/pr93582-5.c foo
      1 32 /home/jakub/src/gcc/gcc/testsuite/gcc.dg/tree-ssa/pr93582-6.c foo
      1 32 /home/jakub/src/gcc/gcc/testsuite/gcc.dg/tree-ssa/pr93582-7.c foo
      1 32 /home/jakub/src/gcc/gcc/testsuite/gcc.dg/ubsan/pr78248.c main
      1 32 /home/jakub/src/gcc/gcc/testsuite/gcc.target/i386/pr66922.c sse2_test
      1 32 /tmp/cc4MIAj2.o main
      1 32 /tmp/ccJDoQfU.o main
      1 32 /tmp/ccmiLJwF.o __ct_base 
      1 32 /tmp/pr58984.exe.6JBchO.ltrans0.o main
      1 32 /tmp/pr71002.exe.Kq0z1W.ltrans0.o __ct_base 
      1 32 /tmp/pr88904.exe.kQNPa3.ltrans0.o main
      1 64 cd1c03i.adb cd1c03i
      1 64 cd2a32a.adb cd2a32a
      1 64 /home/jakub/src/gcc/gcc/testsuite/gcc.dg/tree-ssa/pr93582-4.c foo
      1 64 /home/jakub/src/gcc/gcc/testsuite/gcc.dg/tree-ssa/pr93582-5.c foo
      1 64 /home/jakub/src/gcc/gcc/testsuite/gcc.dg/tree-ssa/pr93582-6.c foo
      1 64 /home/jakub/src/gcc/gcc/testsuite/gcc.dg/tree-ssa/pr93582-7.c foo
      1 64 /home/jakub/src/gcc/gcc/testsuite/gcc.dg/ubsan/pr78248.c main
      1 64 /home/jakub/src/gcc/gcc/testsuite/gcc.target/i386/pr66922.c sse2_test
      1 64 /home/jakub/src/gcc/gcc/testsuite/gnat.dg/inline2.adb inline2_pkg.invalid_real
      1 64 /tmp/ccayIuEe.o main
      1 64 /tmp/ccS70F7g.o main
      1 64 /tmp/ccT7Fqnu.o __ct_base 
      1 64 /tmp/pr58984.exe.Qibnjc.ltrans0.o main
      1 64 /tmp/pr71002.exe.O3rGbI.ltrans0.o __ct_base 
      1 64 /tmp/pr78170.exe.x487vH.ltrans0.o main
      1 64 /tmp/pr88904.exe.RxM5pN.ltrans0.o main
      2 32 ../../gcc/asan.c asan_clear_shadow
      2 32 ../../gcc/asan.c asan_emit_stack_protection
      2 32 ../../gcc/bb-reorder.c better_edge_p
      2 32 ../../gcc/cfgcleanup.c outgoing_edges_match
      2 32 ../../gcc/cfgloop.c loop_iterator::loop_iterator
      2 32 ../../gcc/cfgloopmanip.c create_empty_loop_on_edge
      2 32 ../../gcc/cfgloopmanip.c create_preheaders
      2 32 ../../gcc/cfgrtl.c purge_dead_edges
      2 32 ../../gcc/cgraph.c cgraph_edge::redirect_call_stmt_to_callee
      2 32 ../../gcc/coroutine-passes.cc execute_early_expand_coro_ifns
      2 32 ../../gcc/df-scan.c df_insn_rescan
      2 32 ../../gcc/dojump.c jumpifnot
      2 32 ../../gcc/dojump.c jumpifnot_1
      2 32 ../../gcc/dominance.c get_dominated_by
      2 32 ../../gcc/dominance.c get_dominated_to_depth
      2 32 ../../gcc/expr.c emit_block_move_hints
      2 32 ../../gcc/function-tests.c selftest::test_fndecl_float_intchar
      2 32 ../../gcc/genautomata.c form_ainsn_with_same_reservs.isra
      2 32 ../../gcc/genmatch.c lower
      2 32 ../../gcc/genrecog.c add_decision.constprop
      2 32 ../../gcc/genrecog.c merge_pattern_info::merge_pattern_info
      2 32 ../../gcc/genrecog.c merge_patterns
      2 32 ../../gcc/genrecog.c transition::transition
      2 32 ../../gcc/gimple-ssa-store-merging.c {anonymous}::imm_store_chain_info::output_merged_store
      2 32 ../../gcc/gimple-ssa-store-merging.c {anonymous}::merged_store_group::merged_store_group
      2 32 ../../gcc/gimple-ssa-strength-reduction.c {anonymous}::pass_strength_reduction::execute
      2 32 ../../gcc/hsa-gen.c hsa_op_code_list::hsa_op_code_list
      2 32 ../../gcc/ifcvt.c cond_exec_process_if_block
      2 32 ../../gcc/ifcvt.c dead_or_predicable
      2 32 ../../gcc/internal-fn.c expand_neg_overflow
      2 32 ../../gcc/internal-fn.c profile_probability::very_unlikely
      2 32 ../../gcc/ipa-devirt.c possible_polymorphic_call_targets
      2 32 ../../gcc/loop-invariant.c loop_iterator::loop_iterator
      2 32 ../../gcc/lra-assigns.c lra_split_hard_reg_for
      2 32 ../../gcc/lra-constraints.c lra_constraints
      2 32 ../../gcc/modulo-sched.c loop_iterator::loop_iterator
      2 32 ../../gcc/profile-count.c profile_count::adjust_for_ipa_scaling
      2 32 ../../gcc/profile-count.c profile_count::to_cgraph_frequency
      2 32 ../../gcc/profile-count.c profile_count::to_frequency
      2 32 ../../gcc/profile-count.c profile_count::to_sreal_scale
      2 32 ../../gcc/recog.c {anonymous}::pass_peephole2::execute
      2 32 ../../gcc/sel-sched-ir.c loop_iterator::loop_iterator
      2 32 ../../gcc/tree-call-cdce.c {anonymous}::pass_call_cdce::execute
      2 32 ../../gcc/tree.c build_vector_a_then_b
      2 32 ../../gcc/tree.c build_vector_from_ctor
      2 32 ../../gcc/tree.c drop_tree_overflow
      2 32 ../../gcc/tree-cfg.c loop_iterator::loop_iterator
      2 32 ../../gcc/tree.c selftest::build_vector
      2 32 ../../gcc/tree-if-conv.c tree_if_conversion
      2 32 ../../gcc/tree-ssa-forwprop.c tree_vector_builder::tree_vector_builder
      2 32 ../../gcc/tree-ssa-loop-ivcanon.c unloop_loops
      2 32 ../../gcc/tree-ssa-loop-split.c loop_iterator::loop_iterator
      2 32 ../../gcc/tree-ssa-phiopt.c profile_probability::even
      2 32 ../../gcc/tree-ssa-reassoc.c optimize_range_tests_to_bit_test
      2 32 ../../gcc/tree-ssa-reassoc.c reassociate_bb
      2 32 ../../gcc/tree-ssa-structalias.c find_func_aliases
      2 32 ../../gcc/tree-ssa-structalias.c find_func_clobbers
      2 32 ../../gcc/tree-stdarg.c reachable_at_most_once
      2 32 ../../gcc/tree-switch-conversion.c tree_switch_conversion::bit_test_cluster::hoist_edge_and_branch_if_true
      2 32 ../../gcc/tree-switch-conversion.c tree_switch_conversion::switch_conversion::gen_inbound_check
      2 32 ../../gcc/tree-switch-conversion.c tree_switch_conversion::switch_decision_tree::do_jump_if_equal
      2 32 ../../gcc/tree-switch-conversion.c tree_switch_conversion::switch_decision_tree::emit_cmp_and_jump_insns
      2 32 ../../gcc/tree-vect-loop.c have_whole_vector_shift
      2 32 ../../gcc/tree-vect-loop.c vectorizable_live_operation
      2 32 ../../gcc/tree-vect-loop-manip.c slpeel_add_loop_guard
      2 32 ../../gcc/tree-vect-slp.c vect_get_constant_vectors.constprop
      2 32 ../../gcc/tree-vect-slp.c vect_transform_slp_perm_load
      2 32 ../../gcc/tree-vect-stmts.c vectorizable_call
      2 32 ../../gcc/value-prof.c gimple_ic
      2 32 ../../gcc/var-tracking.c emit_note_insn_var_location
      2 32 ../../gcc/var-tracking.c vt_expand_loc
      2 32 ../../gcc/vec.c selftest::vec_c_tests
      2 32 ../../gcc/vtable-verify.c vtbl_map_node_registration_insert
      2 32 ../../../../libquadmath/math/nanq.c nanq
      2 32 ../../../libquadmath/math/nanq.c nanq
      2 64 ../../gcc/asan.c asan_clear_shadow
      2 64 ../../gcc/asan.c asan_emit_stack_protection
      2 64 ../../gcc/bitmap.c selftest::bitmap_c_tests
      2 64 ../../gcc/bitmap.c selftest::test_clear_bit_in_middle
      2 64 ../../gcc/c/c-parser.c c_parser_omp_variable_list
      2 64 ../../gcc/cfgcleanup.c outgoing_edges_match
      2 64 ../../gcc/cfgloop.c loop_iterator::loop_iterator
      2 64 ../../gcc/cfgloopmanip.c create_empty_loop_on_edge
      2 64 ../../gcc/cfgloopmanip.c create_preheaders
      2 64 ../../gcc/cfgrtl.c purge_dead_edges
      2 64 ../../gcc/cgraph.c cgraph_edge::redirect_call_stmt_to_callee
      2 64 ../../gcc/coroutine-passes.cc execute_early_expand_coro_ifns
      2 64 ../../gcc/df-scan.c df_insn_rescan
      2 64 ../../gcc/dojump.c jumpifnot
      2 64 ../../gcc/dojump.c jumpifnot_1
      2 64 ../../gcc/dominance.c get_dominated_by
      2 64 ../../gcc/dominance.c get_dominated_to_depth
      2 64 ../../gcc/expr.c emit_block_move_hints
      2 64 ../../gcc/function-tests.c selftest::test_fndecl_float_intchar
      2 64 ../../gcc/genautomata.c form_ainsn_with_same_reservs.isra
      2 64 ../../gcc/genmatch.c lower
      2 64 ../../gcc/genrecog.c add_decision.constprop
      2 64 ../../gcc/genrecog.c find_subroutines.isra
      2 64 ../../gcc/genrecog.c merge_pattern_info::merge_pattern_info
      2 64 ../../gcc/genrecog.c merge_patterns
      2 64 ../../gcc/genrecog.c transition::transition
      2 64 ../../gcc/gimple-ssa-store-merging.c {anonymous}::imm_store_chain_info::output_merged_store
      2 64 ../../gcc/gimple-ssa-store-merging.c {anonymous}::merged_store_group::merged_store_group
      2 64 ../../gcc/gimple-ssa-strength-reduction.c {anonymous}::pass_strength_reduction::execute
      2 64 ../../gcc/graphite-isl-ast-to-gimple.c translate_isl_ast_to_gimple::gsi_insert_earliest
      2 64 ../../gcc/graphite-scop-detection.c dot_sese
      2 64 ../../gcc/hsa-gen.c hsa_op_code_list::hsa_op_code_list
      2 64 ../../gcc/ifcvt.c cond_exec_process_if_block
      2 64 ../../gcc/ifcvt.c dead_or_predicable
      2 64 ../../gcc/internal-fn.c expand_neg_overflow
      2 64 ../../gcc/internal-fn.c profile_probability::very_unlikely
      2 64 ../../gcc/ipa-devirt.c possible_polymorphic_call_targets
      2 64 ../../gcc/ipa-profile.c ipa_propagate_frequency
      2 64 ../../gcc/loop-invariant.c loop_iterator::loop_iterator
      2 64 ../../gcc/lra-assigns.c lra_split_hard_reg_for
      2 64 ../../gcc/lra-constraints.c lra_constraints
      2 64 ../../gcc/modulo-sched.c loop_iterator::loop_iterator
      2 64 ../../gcc/recog.c {anonymous}::pass_peephole2::execute
      2 64 ../../gcc/sel-sched-ir.c loop_iterator::loop_iterator
      2 64 ../../gcc/tree-call-cdce.c {anonymous}::pass_call_cdce::execute
      2 64 ../../gcc/tree.c build_vector_a_then_b
      2 64 ../../gcc/tree.c build_vector_from_ctor
      2 64 ../../gcc/tree.c drop_tree_overflow
      2 64 ../../gcc/tree-cfg.c loop_iterator::loop_iterator
      2 64 ../../gcc/tree.c selftest::build_vector
      2 64 ../../gcc/tree-if-conv.c tree_if_conversion
      2 64 ../../gcc/tree-parloops.c loop_iterator::loop_iterator
      2 64 ../../gcc/tree-ssa-forwprop.c tree_vector_builder::tree_vector_builder
      2 64 ../../gcc/tree-ssa-loop-ivcanon.c unloop_loops
      2 64 ../../gcc/tree-ssa-loop-split.c loop_iterator::loop_iterator
      2 64 ../../gcc/tree-ssa-phiopt.c profile_probability::even
      2 64 ../../gcc/tree-ssa-reassoc.c optimize_range_tests_to_bit_test
      2 64 ../../gcc/tree-ssa-reassoc.c reassociate_bb
      2 64 ../../gcc/tree-ssa-structalias.c find_func_aliases
      2 64 ../../gcc/tree-ssa-structalias.c find_func_clobbers
      2 64 ../../gcc/tree-stdarg.c reachable_at_most_once
      2 64 ../../gcc/tree-switch-conversion.c tree_switch_conversion::bit_test_cluster::hoist_edge_and_branch_if_true
      2 64 ../../gcc/tree-switch-conversion.c tree_switch_conversion::switch_conversion::gen_inbound_check
      2 64 ../../gcc/tree-switch-conversion.c tree_switch_conversion::switch_decision_tree::do_jump_if_equal
      2 64 ../../gcc/tree-switch-conversion.c tree_switch_conversion::switch_decision_tree::emit_cmp_and_jump_insns
      2 64 ../../gcc/tree-vect-loop.c have_whole_vector_shift
      2 64 ../../gcc/tree-vect-loop.c vectorizable_live_operation
      2 64 ../../gcc/tree-vect-loop-manip.c slpeel_add_loop_guard
      2 64 ../../gcc/tree-vect-slp.c vect_get_constant_vectors.constprop
      2 64 ../../gcc/tree-vect-slp.c vect_transform_slp_perm_load
      2 64 ../../gcc/tree-vect-stmts.c vectorizable_call
      2 64 ../../gcc/value-prof.c gimple_ic
      2 64 ../../gcc/var-tracking.c emit_note_insn_var_location
      2 64 ../../gcc/var-tracking.c vt_expand_loc
      2 64 ../../gcc/vec.c selftest::vec_c_tests
      2 64 ../../gcc/vtable-verify.c vtbl_map_node_registration_insert
      2 64 ../../../libquadmath/math/nanq.c nanq
      2 64 /tmp/pr88739.exe.kvWJh4.ltrans0.o main
      3 64 /home/jakub/src/gcc/gcc/testsuite/gcc.c-torture/execute/pr88904.c main
      4 32 ../../gcc/asan.c profile_count::apply_probability
      4 32 ../../gcc/asan.c profile_probability::apply_scale
      4 32 ../../gcc/bb-reorder.c profile_count::apply_probability
      4 32 ../../gcc/bb-reorder.c profile_probability::apply_scale
      4 32 ../../gcc/bitmap.c selftest::bitmap_c_tests
      4 32 ../../gcc/cfgbuild.c find_many_sub_basic_blocks
      4 32 ../../gcc/cfgbuild.c profile_count::apply_probability
      4 32 ../../gcc/cfgcleanup.c profile_count::apply_probability
      4 32 ../../gcc/cfg.c profile_count::apply_probability
      4 32 ../../gcc/cfg.c profile_probability::apply_scale
      4 32 ../../gcc/cfg.c profile_probability::operator/=
      4 32 ../../gcc/cfgexpand.c profile_count::apply_probability
      4 32 ../../gcc/cfghooks.c profile_count::apply_probability
      4 32 ../../gcc/cfgloopanal.c profile_count::apply_probability
      4 32 ../../gcc/cfgloopanal.c profile_probability::apply_scale
      4 32 ../../gcc/cfgloop.c profile_count::apply_probability
      4 32 ../../gcc/cfgloopmanip.c force_single_succ_latches
      4 32 ../../gcc/cfgloopmanip.c profile_count::apply_probability
      4 32 ../../gcc/cfgloopmanip.c profile_probability::apply_scale
      4 32 ../../gcc/cfgrtl.c profile_count::apply_probability
      4 32 ../../gcc/cfgrtl.c profile_probability::apply_scale
      4 32 ../../gcc/cgraph.c profile_probability::apply_scale
      4 32 ../../gcc/cgraphunit.c cgraph_node::expand_thunk
      4 32 ../../gcc/cgraphunit.c profile_probability::apply_scale
      4 32 ../../gcc/config/i386/i386.c profile_count::apply_probability
      4 32 ../../gcc/config/i386/i386.c profile_probability::apply_scale
      4 32 ../../gcc/dojump.c profile_probability::apply_scale
      4 32 ../../gcc/dojump.c profile_probability::operator/
      4 32 ../../gcc/expr.c profile_probability::apply_scale
      4 32 ../../gcc/final.c profile_count::apply_probability
      4 32 ../../gcc/genautomata.c create_automata
      4 32 ../../gcc/genrecog.c cse_tests.isra
      4 32 ../../gcc/genrecog.c int_set::int_set
      4 32 ../../gcc/genrecog.c match_pattern
      4 32 ../../gcc/genrecog.c populate_pattern_use
      4 32 ../../gcc/gimple-loop-interchange.cc {anonymous}::pass_linterchange::execute
      4 32 ../../gcc/gimple-loop-jam.c {anonymous}::pass_loop_jam::execute
      4 32 ../../gcc/gimple-loop-versioning.cc profile_probability::apply_scale
      4 32 ../../gcc/gimple-ssa-isolate-paths.c profile_count::apply_probability
      4 32 ../../gcc/gimple-ssa-split-paths.c {anonymous}::pass_split_paths::execute
      4 32 ../../gcc/haifa-sched.c profile_count::apply_probability
      4 32 ../../gcc/haifa-sched.c profile_probability::apply_scale
      4 32 ../../gcc/hsa-gen.c profile_count::apply_probability
      4 32 ../../gcc/hsa-gen.c profile_probability::operator/
      4 32 ../../gcc/ifcvt.c profile_probability::apply
      4 32 ../../gcc/internal-fn.c profile_probability::apply_scale
      4 32 ../../gcc/ipa-fnsummary.c analyze_function_body
      4 32 ../../gcc/ipa-profile.c profile_count::apply_probability
      4 32 ../../gcc/ipa-pure-const.c analyze_function
      4 32 ../../gcc/ipa-split.c profile_count::apply_probability
      4 32 ../../gcc/ira-color.c profile_count::apply_probability
      4 32 ../../gcc/ira-emit.c profile_count::apply_probability
      4 32 ../../gcc/loop-init.c fix_loop_structure
      4 32 ../../gcc/loop-init.c loop_optimizer_finalize
      4 32 ../../gcc/loop-unroll.c decide_unrolling
      4 32 ../../gcc/loop-unroll.c profile_probability::apply_scale
      4 32 ../../gcc/modulo-sched.c profile_count::apply_probability
      4 32 ../../gcc/modulo-sched.c profile_probability::apply_scale
      4 32 ../../gcc/omp-expand.c profile_probability::apply_scale
      4 32 ../../gcc/omp-simd-clone.c profile_count::apply_probability
      4 32 ../../gcc/omp-simd-clone.c profile_probability::apply_scale
      4 32 ../../gcc/postreload-gcse.c profile_count::apply_probability
      4 32 ../../gcc/predict.c {anonymous}::pass_profile::execute
      4 32 ../../gcc/predict.c guess_outgoing_edge_probabilities
      4 32 ../../gcc/predict.c invert_br_probabilities
      4 32 ../../gcc/predict.c predict_loops
      4 32 ../../gcc/predict.c profile_count::apply_probability
      4 32 ../../gcc/predict.c profile_probability::apply_scale
      4 32 ../../gcc/predict.c profile_probability::operator/
      4 32 ../../gcc/predict.c profile_probability::operator/=
      4 32 ../../gcc/predict.c unlikely_executed_edge_p
      4 32 ../../gcc/profile.c branch_prob
      4 32 ../../gcc/profile-count.c profile_count::combine_with_ipa_count
      4 32 ../../gcc/profile-count.c profile_count::compatible_p
      4 32 ../../gcc/profile-count.c profile_count::operator+
      4 32 ../../gcc/profile-count.c profile_count::probability_in
      4 32 ../../gcc/profile-count.c profile_probability::apply_scale
      4 32 ../../gcc/profile.c profile_count::apply_probability
      4 32 ../../gcc/profile.c profile_probability::apply_scale
      4 32 ../../gcc/reg-stack.c profile_count::apply_probability
      4 32 ../../gcc/sel-sched-ir.c sel_finish_pipelining
      4 32 ../../gcc/shrink-wrap.c profile_count::apply_probability
      4 32 ../../gcc/stmt.c profile_probability::apply_scale
      4 32 ../../gcc/stmt.c profile_probability::operator/
      4 32 ../../gcc/stmt.c profile_probability::operator/=
      4 32 ../../gcc/tracer.c profile_count::apply_probability
      4 32 ../../gcc/trans-mem.c profile_count::apply_probability
      4 32 ../../gcc/trans-mem.c profile_probability::apply_scale
      4 32 ../../gcc/tree-call-cdce.c profile_count::apply_probability
      4 32 ../../gcc/tree-call-cdce.c profile_probability::apply_scale
      4 32 ../../gcc/tree-cfg.c profile_count::apply_probability
      4 32 ../../gcc/tree-complex.c profile_count::apply_probability
      4 32 ../../gcc/tree-complex.c profile_probability::apply_scale
      4 32 ../../gcc/tree-if-conv.c {anonymous}::pass_if_conversion::execute
      4 32 ../../gcc/tree-inline.c profile_count::apply_probability
      4 32 ../../gcc/tree-loop-distribution.c loop_distribution::execute
      4 32 ../../gcc/tree-loop-distribution.c profile_probability::apply_scale
      4 32 ../../gcc/tree-parloops.c parallelize_loops
      4 32 ../../gcc/tree-parloops.c profile_probability::apply_scale
      4 32 ../../gcc/tree-predcom.c tree_predictive_commoning
      4 32 ../../gcc/tree-profile.c gimple_gen_time_profiler
      4 32 ../../gcc/tree-profile.c profile_probability::apply_scale
      4 32 ../../gcc/tree-scalar-evolution.c scev_initialize
      4 32 ../../gcc/tree-scalar-evolution.c scev_reset
      4 32 ../../gcc/tree-ssa-coalesce.c profile_count::apply_probability
      4 32 ../../gcc/tree-ssa-dce.c perform_tree_ssa_dce
      4 32 ../../gcc/tree-ssa-live.c remove_unused_locals
      4 32 ../../gcc/tree-ssa-loop.c {anonymous}::pass_oacc_kernels::gate
      4 32 ../../gcc/tree-ssa-loop.c {anonymous}::pass_scev_cprop::execute
      4 32 ../../gcc/tree-ssa-loop-ch.c {anonymous}::ch_base::_ZN12_GLOBAL__N_17ch_base12copy_headersEP8function.part.0
      4 32 ../../gcc/tree-ssa-loop-im.c profile_count::apply_probability
      4 32 ../../gcc/tree-ssa-loop-im.c profile_probability::apply_scale
      4 32 ../../gcc/tree-ssa-loop-ivcanon.c canonicalize_induction_variables
      4 32 ../../gcc/tree-ssa-loop-ivopts.c tree_ssa_iv_optimize
      4 32 ../../gcc/tree-ssa-loop-manip.c profile_count::apply_probability
      4 32 ../../gcc/tree-ssa-loop-manip.c profile_probability::apply_scale
      4 32 ../../gcc/tree-ssa-loop-manip.c profile_probability::operator/
      4 32 ../../gcc/tree-ssa-loop-manip.c rewrite_into_loop_closed_ssa_1
      4 32 ../../gcc/tree-ssa-loop-niter.c estimate_numbers_of_iterations
      4 32 ../../gcc/tree-ssa-loop-niter.c free_numbers_of_iterations_estimates
      4 32 ../../gcc/tree-ssa-loop-prefetch.c _Z24tree_ssa_prefetch_arraysv.part.0
      4 32 ../../gcc/tree-ssa-loop-split.c profile_probability::apply_scale
      4 32 ../../gcc/tree-ssa-loop-unswitch.c profile_count::apply_probability
      4 32 ../../gcc/tree-ssa-loop-unswitch.c tree_unswitch_single_loop
      4 32 ../../gcc/tree-ssa-phiopt.c profile_probability::apply_scale
      4 32 ../../gcc/tree-ssa-reassoc.c {anonymous}::pass_reassoc::execute
      4 32 ../../gcc/tree-ssa-reassoc.c profile_count::apply_probability
      4 32 ../../gcc/tree-ssa-reassoc.c profile_probability::apply_scale
      4 32 ../../gcc/tree-ssa-sccvn.c do_rpo_vn
      4 32 ../../gcc/tree-ssa-threadupdate.c profile_count::apply_probability
      4 32 ../../gcc/tree-ssa-threadupdate.c profile_probability::operator/
      4 32 ../../gcc/tree-ssa-threadupdate.c profile_probability::operator/=
      4 32 ../../gcc/tree-ssa-threadupdate.c thread_through_all_blocks
      4 32 ../../gcc/tree-switch-conversion.c profile_count::apply_probability
      4 32 ../../gcc/tree-switch-conversion.c profile_probability::apply_scale
      4 32 ../../gcc/tree-switch-conversion.c profile_probability::operator/
      4 32 ../../gcc/tree-tailcall.c profile_count::apply_probability
      4 32 ../../gcc/tree-vect-loop.c profile_count::apply_probability
      4 32 ../../gcc/tree-vect-loop.c profile_probability::apply_scale
      4 32 ../../gcc/tree-vect-loop.c profile_probability::operator/
      4 32 ../../gcc/tree-vect-loop.c vect_transform_cycle_phi
      4 32 ../../gcc/tree-vect-loop.c vect_transform_loop
      4 32 ../../gcc/tree-vect-loop-manip.c profile_count::apply_probability
      4 32 ../../gcc/tree-vect-loop-manip.c profile_probability::apply_scale
      4 32 ../../gcc/tree-vectorizer.c vectorize_loops
      4 32 ../../gcc/tree-vect-slp.c vect_schedule_slp_instance
      4 32 ../../gcc/tree-vrp.c {anonymous}::pass_vrp::execute
      4 32 ../../gcc/ubsan.c profile_count::apply_probability
      4 32 ../../gcc/ubsan.c profile_probability::apply_scale
      4 32 ../../gcc/value-prof.c profile_count::apply_probability
      4 32 /home/jakub/src/gcc/gcc/testsuite/gcc.c-torture/execute/pr88904.c main
      4 32 /home/jakub/src/gcc/gcc/testsuite/gcc.dg/torture/pr28045.c main
      4 64 ../../gcc/asan.c profile_count::apply_probability
      4 64 ../../gcc/asan.c profile_probability::apply_scale
      4 64 ../../gcc/bb-reorder.c profile_count::apply_probability
      4 64 ../../gcc/bb-reorder.c profile_probability::apply_scale
      4 64 ../../gcc/cfgbuild.c find_many_sub_basic_blocks
      4 64 ../../gcc/cfgbuild.c profile_count::apply_probability
      4 64 ../../gcc/cfgcleanup.c profile_count::apply_probability
      4 64 ../../gcc/cfg.c profile_count::apply_probability
      4 64 ../../gcc/cfg.c profile_probability::apply_scale
      4 64 ../../gcc/cfg.c profile_probability::operator/=
      4 64 ../../gcc/cfgexpand.c profile_count::apply_probability
      4 64 ../../gcc/cfghooks.c profile_count::apply_probability
      4 64 ../../gcc/cfgloopanal.c profile_count::apply_probability
      4 64 ../../gcc/cfgloopanal.c profile_probability::apply_scale
      4 64 ../../gcc/cfgloop.c profile_count::apply_probability
      4 64 ../../gcc/cfgloopmanip.c force_single_succ_latches
      4 64 ../../gcc/cfgloopmanip.c profile_count::apply_probability
      4 64 ../../gcc/cfgloopmanip.c profile_probability::apply_scale
      4 64 ../../gcc/cfgrtl.c profile_count::apply_probability
      4 64 ../../gcc/cfgrtl.c profile_probability::apply_scale
      4 64 ../../gcc/cgraph.c profile_probability::apply_scale
      4 64 ../../gcc/cgraphunit.c cgraph_node::expand_thunk
      4 64 ../../gcc/cgraphunit.c profile_probability::apply_scale
      4 64 ../../gcc/config/i386/i386.c profile_count::apply_probability
      4 64 ../../gcc/config/i386/i386.c profile_probability::apply_scale
      4 64 ../../gcc/dojump.c profile_probability::apply_scale
      4 64 ../../gcc/dojump.c profile_probability::operator/
      4 64 ../../gcc/expr.c profile_probability::apply_scale
      4 64 ../../gcc/final.c profile_count::apply_probability
      4 64 ../../gcc/genautomata.c create_automata
      4 64 ../../gcc/genrecog.c cse_tests.isra
      4 64 ../../gcc/genrecog.c int_set::int_set
      4 64 ../../gcc/genrecog.c merge_into_decision
      4 64 ../../gcc/genrecog.c populate_pattern_use
      4 64 ../../gcc/gimple-loop-interchange.cc {anonymous}::pass_linterchange::execute
      4 64 ../../gcc/gimple-loop-jam.c tree_loop_unroll_and_jam
      4 64 ../../gcc/gimple-loop-versioning.cc profile_probability::apply_scale
      4 64 ../../gcc/gimple-ssa-isolate-paths.c profile_count::apply_probability
      4 64 ../../gcc/gimple-ssa-split-paths.c {anonymous}::pass_split_paths::execute
      4 64 ../../gcc/graphite-isl-ast-to-gimple.c graphite_regenerate_ast_isl
      4 64 ../../gcc/haifa-sched.c profile_count::apply_probability
      4 64 ../../gcc/haifa-sched.c profile_probability::apply_scale
      4 64 ../../gcc/hsa-gen.c profile_count::apply_probability
      4 64 ../../gcc/hsa-gen.c profile_probability::operator/
      4 64 ../../gcc/ifcvt.c profile_probability::apply
      4 64 ../../gcc/internal-fn.c profile_probability::apply_scale
      4 64 ../../gcc/ipa-fnsummary.c analyze_function_body
      4 64 ../../gcc/ipa-profile.c profile_count::apply_probability
      4 64 ../../gcc/ipa-pure-const.c analyze_function
      4 64 ../../gcc/ipa-split.c profile_count::apply_probability
      4 64 ../../gcc/ira-color.c profile_count::apply_probability
      4 64 ../../gcc/ira-emit.c profile_count::apply_probability
      4 64 ../../gcc/loop-init.c fix_loop_structure
      4 64 ../../gcc/loop-init.c loop_optimizer_finalize
      4 64 ../../gcc/loop-unroll.c decide_unrolling
      4 64 ../../gcc/loop-unroll.c profile_probability::apply_scale
      4 64 ../../gcc/modulo-sched.c profile_count::apply_probability
      4 64 ../../gcc/modulo-sched.c profile_probability::apply_scale
      4 64 ../../gcc/omp-expand.c profile_probability::apply_scale
      4 64 ../../gcc/omp-simd-clone.c profile_count::apply_probability
      4 64 ../../gcc/omp-simd-clone.c profile_probability::apply_scale
      4 64 ../../gcc/postreload-gcse.c profile_count::apply_probability
      4 64 ../../gcc/predict.c {anonymous}::pass_profile::execute
      4 64 ../../gcc/predict.c guess_outgoing_edge_probabilities
      4 64 ../../gcc/predict.c invert_br_probabilities
      4 64 ../../gcc/predict.c predict_loops
      4 64 ../../gcc/predict.c probably_never_executed
      4 64 ../../gcc/predict.c profile_count::apply_probability
      4 64 ../../gcc/predict.c profile_probability::apply_scale
      4 64 ../../gcc/predict.c profile_probability::operator/
      4 64 ../../gcc/predict.c profile_probability::operator/=
      4 64 ../../gcc/predict.c unlikely_executed_edge_p
      4 64 ../../gcc/profile.c branch_prob
      4 64 ../../gcc/profile-count.c profile_count::adjust_for_ipa_scaling
      4 64 ../../gcc/profile-count.c profile_count::to_cgraph_frequency
      4 64 ../../gcc/profile-count.c profile_count::to_frequency
      4 64 ../../gcc/profile-count.c profile_count::to_sreal_scale
      4 64 ../../gcc/profile-count.c profile_probability::apply_scale
      4 64 ../../gcc/profile.c profile_count::apply_probability
      4 64 ../../gcc/profile.c profile_probability::apply_scale
      4 64 ../../gcc/reg-stack.c profile_count::apply_probability
      4 64 ../../gcc/sel-sched-ir.c sel_finish_pipelining
      4 64 ../../gcc/shrink-wrap.c profile_count::apply_probability
      4 64 ../../gcc/stmt.c profile_probability::apply_scale
      4 64 ../../gcc/stmt.c profile_probability::operator/
      4 64 ../../gcc/stmt.c profile_probability::operator/=
      4 64 ../../gcc/tracer.c profile_count::apply_probability
      4 64 ../../gcc/trans-mem.c profile_count::apply_probability
      4 64 ../../gcc/trans-mem.c profile_probability::apply_scale
      4 64 ../../gcc/tree-call-cdce.c profile_count::apply_probability
      4 64 ../../gcc/tree-call-cdce.c profile_probability::apply_scale
      4 64 ../../gcc/tree-cfg.c profile_count::apply_probability
      4 64 ../../gcc/tree-complex.c profile_count::apply_probability
      4 64 ../../gcc/tree-complex.c profile_probability::apply_scale
      4 64 ../../gcc/tree-if-conv.c {anonymous}::pass_if_conversion::execute
      4 64 ../../gcc/tree-inline.c profile_count::apply_probability
      4 64 ../../gcc/tree-loop-distribution.c loop_distribution::execute
      4 64 ../../gcc/tree-loop-distribution.c profile_probability::apply_scale
      4 64 ../../gcc/tree-parloops.c profile_probability::apply_scale
      4 64 ../../gcc/tree-predcom.c tree_predictive_commoning
      4 64 ../../gcc/tree-profile.c gimple_gen_time_profiler
      4 64 ../../gcc/tree-profile.c profile_probability::apply_scale
      4 64 ../../gcc/tree-scalar-evolution.c scev_initialize
      4 64 ../../gcc/tree-scalar-evolution.c scev_reset
      4 64 ../../gcc/tree-ssa-coalesce.c profile_count::apply_probability
      4 64 ../../gcc/tree-ssa-dce.c perform_tree_ssa_dce
      4 64 ../../gcc/tree-ssa-live.c remove_unused_locals
      4 64 ../../gcc/tree-ssa-loop.c {anonymous}::pass_oacc_kernels::gate
      4 64 ../../gcc/tree-ssa-loop.c {anonymous}::pass_scev_cprop::execute
      4 64 ../../gcc/tree-ssa-loop-ch.c {anonymous}::ch_base::_ZN12_GLOBAL__N_17ch_base12copy_headersEP8function.part.0
      4 64 ../../gcc/tree-ssa-loop-im.c profile_count::apply_probability
      4 64 ../../gcc/tree-ssa-loop-im.c profile_probability::apply_scale
      4 64 ../../gcc/tree-ssa-loop-ivcanon.c canonicalize_induction_variables
      4 64 ../../gcc/tree-ssa-loop-ivopts.c tree_ssa_iv_optimize
      4 64 ../../gcc/tree-ssa-loop-manip.c profile_count::apply_probability
      4 64 ../../gcc/tree-ssa-loop-manip.c profile_probability::apply_scale
      4 64 ../../gcc/tree-ssa-loop-manip.c profile_probability::operator/
      4 64 ../../gcc/tree-ssa-loop-manip.c rewrite_into_loop_closed_ssa_1
      4 64 ../../gcc/tree-ssa-loop-niter.c estimate_numbers_of_iterations
      4 64 ../../gcc/tree-ssa-loop-niter.c free_numbers_of_iterations_estimates
      4 64 ../../gcc/tree-ssa-loop-prefetch.c _Z24tree_ssa_prefetch_arraysv.part.0
      4 64 ../../gcc/tree-ssa-loop-split.c profile_probability::apply_scale
      4 64 ../../gcc/tree-ssa-loop-unswitch.c profile_count::apply_probability
      4 64 ../../gcc/tree-ssa-loop-unswitch.c tree_unswitch_single_loop
      4 64 ../../gcc/tree-ssa-phiopt.c profile_probability::apply_scale
      4 64 ../../gcc/tree-ssa-reassoc.c {anonymous}::pass_reassoc::execute
      4 64 ../../gcc/tree-ssa-reassoc.c profile_count::apply_probability
      4 64 ../../gcc/tree-ssa-reassoc.c profile_probability::apply_scale
      4 64 ../../gcc/tree-ssa-sccvn.c do_rpo_vn
      4 64 ../../gcc/tree-ssa-threadupdate.c profile_count::apply_probability
      4 64 ../../gcc/tree-ssa-threadupdate.c profile_probability::operator/
      4 64 ../../gcc/tree-ssa-threadupdate.c profile_probability::operator/=
      4 64 ../../gcc/tree-ssa-threadupdate.c thread_through_all_blocks
      4 64 ../../gcc/tree-switch-conversion.c profile_count::apply_probability
      4 64 ../../gcc/tree-switch-conversion.c profile_probability::apply_scale
      4 64 ../../gcc/tree-switch-conversion.c profile_probability::operator/
      4 64 ../../gcc/tree-tailcall.c profile_count::apply_probability
      4 64 ../../gcc/tree-vect-loop.c profile_count::apply_probability
      4 64 ../../gcc/tree-vect-loop.c profile_probability::apply_scale
      4 64 ../../gcc/tree-vect-loop.c profile_probability::operator/
      4 64 ../../gcc/tree-vect-loop.c vect_transform_cycle_phi
      4 64 ../../gcc/tree-vect-loop.c vect_transform_loop
      4 64 ../../gcc/tree-vect-loop-manip.c profile_count::apply_probability
      4 64 ../../gcc/tree-vect-loop-manip.c profile_probability::apply_scale
      4 64 ../../gcc/tree-vectorizer.c vectorize_loops
      4 64 ../../gcc/tree-vect-slp.c vect_schedule_slp_instance
      4 64 ../../gcc/tree-vrp.c execute_vrp
      4 64 ../../gcc/ubsan.c profile_count::apply_probability
      4 64 ../../gcc/ubsan.c profile_probability::apply_scale
      4 64 ../../gcc/value-prof.c profile_count::apply_probability
      4 64 /home/jakub/src/gcc/gcc/testsuite/gcc.c-torture/execute/pr58984.c main
      4 64 /home/jakub/src/gcc/gcc/testsuite/gcc.dg/torture/pr28045.c main
      5 32 /home/jakub/src/gcc/gcc/testsuite/gcc.c-torture/execute/pr58984.c main
      5 64 /home/jakub/src/gcc/gcc/testsuite/g++.dg/torture/pr71002.C foo::foo
      6 32 ../../gcc/dojump.c do_jump_by_parts_greater_rtx
      6 32 ../../gcc/dojump.c profile_probability::split
      6 32 ../../gcc/gimple-ssa-backprop.c {anonymous}::backprop::process_var
      6 32 ../../gcc/haifa-sched.c sched_create_recovery_edges
      6 32 ../../gcc/ipa-param-manipulation.c ipa_param_body_adjustments::common_initialization
      6 32 ../../gcc/tree-if-conv.c combine_blocks
      6 32 ../../gcc/tree-ssa-ifcombine.c update_profile_after_ifcombine
      6 32 ../../gcc/tree-switch-conversion.c tree_switch_conversion::bit_test_cluster::emit
      6 32 ../../gcc/tree-vect-loop.c optimize_mask_stores
      6 32 ../../gcc/tree-vect-loop.c vectorizable_induction
      6 32 ../../gcc/tree-vect-slp.c vect_bb_slp_scalar_cost.isra
      6 32 ../../gcc/ubsan.c ubsan_expand_null_ifn
      6 32 /home/jakub/src/gcc/gcc/testsuite/gcc.c-torture/compile/20191015-1.c f
      6 32 /home/jakub/src/gcc/gcc/testsuite/gcc.c-torture/compile/20191015-2.c f
      6 32 /home/jakub/src/gcc/gcc/testsuite/gcc.c-torture/compile/20200105-1.c g
      6 32 /home/jakub/src/gcc/gcc/testsuite/gcc.c-torture/compile/20200105-2.c g
      6 32 /home/jakub/src/gcc/gcc/testsuite/gcc.c-torture/compile/20200105-3.c g
      6 32 /home/jakub/src/gcc/gcc/testsuite/gcc.c-torture/execute/20190901-1.c tests_infinity_d
      6 32 /home/jakub/src/gcc/gcc/testsuite/gcc.c-torture/execute/960608-1.c main
      6 32 /home/jakub/src/gcc/gcc/testsuite/gcc.dg/torture/pr37868.c main
      6 32 /home/jakub/src/gcc/gcc/testsuite/g++.dg/torture/pr71002.C foo::foo
      6 64 ../../gcc/dojump.c do_jump_by_parts_greater_rtx
      6 64 ../../gcc/dojump.c profile_probability::split
      6 64 ../../gcc/gimple-ssa-backprop.c {anonymous}::backprop::process_var
      6 64 ../../gcc/haifa-sched.c sched_create_recovery_edges
      6 64 ../../gcc/ipa-param-manipulation.c ipa_param_body_adjustments::common_initialization
      6 64 ../../gcc/tree-if-conv.c combine_blocks
      6 64 ../../gcc/tree-ssa-ifcombine.c update_profile_after_ifcombine
      6 64 ../../gcc/tree-switch-conversion.c tree_switch_conversion::bit_test_cluster::emit
      6 64 ../../gcc/tree-vect-loop.c optimize_mask_stores
      6 64 ../../gcc/tree-vect-loop.c vectorizable_induction
      6 64 ../../gcc/tree-vect-slp.c vect_bb_slp_scalar_cost.isra
      6 64 ../../gcc/ubsan.c ubsan_expand_null_ifn
      6 64 /home/jakub/src/gcc/gcc/testsuite/gcc.c-torture/compile/20191015-1.c f
      6 64 /home/jakub/src/gcc/gcc/testsuite/gcc.c-torture/compile/20191015-2.c f
      6 64 /home/jakub/src/gcc/gcc/testsuite/gcc.c-torture/compile/20200105-1.c g
      6 64 /home/jakub/src/gcc/gcc/testsuite/gcc.c-torture/compile/20200105-2.c g
      6 64 /home/jakub/src/gcc/gcc/testsuite/gcc.c-torture/compile/20200105-3.c g
      6 64 /home/jakub/src/gcc/gcc/testsuite/gcc.c-torture/execute/20190901-1.c tests_infinity_d
      6 64 /home/jakub/src/gcc/gcc/testsuite/gcc.c-torture/execute/960608-1.c main
      6 64 /home/jakub/src/gcc/gcc/testsuite/gcc.dg/torture/pr37868.c main
      8 32 ../../gcc/asan.c profile_probability::operator-
      8 32 ../../gcc/asan.c profile_probability::very_likely
      8 32 ../../gcc/bb-reorder.c profile_probability::operator+
      8 32 ../../gcc/bb-reorder.c profile_probability::operator-
      8 32 ../../gcc/cfgbuild.c profile_probability::operator-
      8 32 ../../gcc/cfg.c check_bb_profile
      8 32 ../../gcc/cfgcleanup.c profile_probability::operator-
      8 32 ../../gcc/cfg.c profile_probability::operator+=
      8 32 ../../gcc/cfg.c profile_probability::operator-
      8 32 ../../gcc/cfg.c profile_probability::operator-=
      8 32 ../../gcc/cfgexpand.c expand_gimple_basic_block
      8 32 ../../gcc/cfgexpand.c profile_probability::operator+=
      8 32 ../../gcc/cfghooks.c profile_probability::operator+=
      8 32 ../../gcc/cfghooks.c profile_record_check_consistency
      8 32 ../../gcc/cfgloopanal.c single_likely_exit
      8 32 ../../gcc/cfgloopmanip.c duplicate_loop_to_header_edge
      8 32 ../../gcc/cfgloopmanip.c profile_probability::operator*
      8 32 ../../gcc/cfgloopmanip.c profile_probability::operator-
      8 32 ../../gcc/cfgrtl.c cfg_layout_finalize
      8 32 ../../gcc/cfgrtl.c profile_probability::operator-
      8 32 ../../gcc/cfgrtl.c profile_probability::operator-=
      8 32 ../../gcc/config/i386/i386.c profile_probability::operator-
      8 32 ../../gcc/config/i386/i386.c profile_probability::very_likely
      8 32 ../../gcc/dojump.c do_jump
      8 32 ../../gcc/dojump.c profile_probability::operator*
      8 32 ../../gcc/dojump.c profile_probability::operator-
      8 32 ../../gcc/genrecog.c print_state.isra
      8 32 ../../gcc/gimple-loop-versioning.cc profile_probability::operator-
      8 32 ../../gcc/haifa-sched.c profile_probability::operator-
      8 32 ../../gcc/hsa-gen.c profile_probability::operator+
      8 32 ../../gcc/hsa-gen.c profile_probability::operator+=
      8 32 ../../gcc/hsa-gen.c profile_probability::operator-
      8 32 ../../gcc/ifcvt.c profile_probability::operator-
      8 32 ../../gcc/internal-fn.c expand_addsub_overflow
      8 32 ../../gcc/internal-fn.c profile_probability::operator-
      8 32 ../../gcc/internal-fn.c profile_probability::very_likely
      8 32 ../../gcc/ipa-utils.c profile_probability::operator*
      8 32 ../../gcc/ipa-utils.c profile_probability::operator+
      8 32 ../../gcc/loop-doloop.c profile_probability::operator-
      8 32 ../../gcc/loop-unroll.c profile_probability::operator-
      8 32 ../../gcc/modulo-sched.c profile_probability::operator-
      8 32 ../../gcc/omp-expand.c expand_omp_for_static_chunk
      8 32 ../../gcc/omp-expand.c extract_omp_for_update_vars
      8 32 ../../gcc/omp-expand.c profile_probability::operator-
      8 32 ../../gcc/omp-simd-clone.c profile_probability::operator-
      8 32 ../../gcc/predict.c profile_probability::operator+=
      8 32 ../../gcc/predict.c profile_probability::operator-
      8 32 ../../gcc/predict.c profile_probability::operator-=
      8 32 ../../gcc/profile-count.c profile_probability::operator*
      8 32 ../../gcc/profile-count.c profile_probability::operator+
      8 32 ../../gcc/recog.c profile_probability::operator-
      8 32 ../../gcc/stmt.c profile_probability::operator+=
      8 32 ../../gcc/stmt.c profile_probability::operator-=
      8 32 ../../gcc/trans-mem.c profile_probability::operator-
      8 32 ../../gcc/tree-call-cdce.c profile_probability::operator-
      8 32 ../../gcc/tree-cfgcleanup.c profile_probability::operator+=
      8 32 ../../gcc/tree-cfg.c profile_probability::operator-=
      8 32 ../../gcc/tree-loop-distribution.c profile_probability::operator-
      8 32 ../../gcc/tree-parloops.c profile_probability::operator-
      8 32 ../../gcc/tree-profile.c profile_probability::operator-
      8 32 ../../gcc/tree-ssa-ifcombine.c profile_probability::operator*
      8 32 ../../gcc/tree-ssa-ifcombine.c profile_probability::operator+
      8 32 ../../gcc/tree-ssa-ifcombine.c profile_probability::operator-
      8 32 ../../gcc/tree-ssa-loop-im.c {anonymous}::pass_lim::execute
      8 32 ../../gcc/tree-ssa-loop-im.c profile_probability::operator-
      8 32 ../../gcc/tree-ssa-loop-manip.c profile_probability::operator-
      8 32 ../../gcc/tree-ssa-loop-split.c profile_probability::operator-
      8 32 ../../gcc/tree-ssa-loop-unswitch.c profile_probability::operator-
      8 32 ../../gcc/tree-ssa-reassoc.c profile_probability::operator-=
      8 32 ../../gcc/tree-ssa-threadupdate.c profile_probability::operator*=
      8 32 ../../gcc/tree-ssa-threadupdate.c profile_probability::operator-
      8 32 ../../gcc/tree-switch-conversion.c profile_probability::operator+
      8 32 ../../gcc/tree-switch-conversion.c profile_probability::operator+=
      8 32 ../../gcc/tree-switch-conversion.c profile_probability::operator-
      8 32 ../../gcc/tree-switch-conversion.c profile_probability::operator-=
      8 32 ../../gcc/tree-switch-conversion.c tree_switch_conversion::jump_table_cluster::emit
      8 32 ../../gcc/tree-switch-conversion.c tree_switch_conversion::switch_decision_tree::balance_case_nodes
      8 32 ../../gcc/tree-vect-loop.c profile_probability::operator-
      8 32 ../../gcc/tree-vect-loop-manip.c profile_probability::operator*
      8 32 ../../gcc/tree-vect-loop-manip.c profile_probability::operator+
      8 32 ../../gcc/tree-vect-loop-manip.c profile_probability::operator-
      8 32 ../../gcc/tree-vect-slp.c vect_slp_bb
      8 32 ../../gcc/tree-vect-stmts.c vectorizable_store
      8 32 ../../gcc/ubsan.c profile_probability::operator-
      8 32 ../../gcc/ubsan.c profile_probability::very_likely
      8 32 ../../gcc/value-prof.c profile_probability::operator-
      8 32 /home/jakub/src/gcc/gcc/testsuite/gcc.c-torture/execute/bf64-1.c main
      8 64 ../../gcc/asan.c profile_probability::operator-
      8 64 ../../gcc/asan.c profile_probability::very_likely
      8 64 ../../gcc/bb-reorder.c profile_probability::operator+
      8 64 ../../gcc/bb-reorder.c profile_probability::operator-
      8 64 ../../gcc/cfgbuild.c profile_probability::operator-
      8 64 ../../gcc/cfg.c check_bb_profile
      8 64 ../../gcc/cfgcleanup.c profile_probability::operator-
      8 64 ../../gcc/cfg.c profile_probability::operator+=
      8 64 ../../gcc/cfg.c profile_probability::operator-
      8 64 ../../gcc/cfg.c profile_probability::operator-=
      8 64 ../../gcc/cfgexpand.c expand_gimple_basic_block
      8 64 ../../gcc/cfgexpand.c profile_probability::operator+=
      8 64 ../../gcc/cfghooks.c profile_probability::operator+=
      8 64 ../../gcc/cfghooks.c profile_record_check_consistency
      8 64 ../../gcc/cfgloopanal.c single_likely_exit
      8 64 ../../gcc/cfgloopmanip.c duplicate_loop_to_header_edge
      8 64 ../../gcc/cfgloopmanip.c profile_probability::operator*
      8 64 ../../gcc/cfgloopmanip.c profile_probability::operator-
      8 64 ../../gcc/cfgrtl.c cfg_layout_finalize
      8 64 ../../gcc/cfgrtl.c profile_probability::operator-
      8 64 ../../gcc/cfgrtl.c profile_probability::operator-=
      8 64 ../../gcc/config/i386/i386.c profile_probability::operator-
      8 64 ../../gcc/config/i386/i386.c profile_probability::very_likely
      8 64 ../../gcc/dojump.c do_jump
      8 64 ../../gcc/dojump.c profile_probability::operator*
      8 64 ../../gcc/dojump.c profile_probability::operator-
      8 64 ../../gcc/genrecog.c print_state.isra
      8 64 ../../gcc/gimple-loop-versioning.cc profile_probability::operator-
      8 64 ../../gcc/graphite.c graphite_transform_loops
      8 64 ../../gcc/haifa-sched.c profile_probability::operator-
      8 64 ../../gcc/hsa-gen.c profile_probability::operator+
      8 64 ../../gcc/hsa-gen.c profile_probability::operator+=
      8 64 ../../gcc/hsa-gen.c profile_probability::operator-
      8 64 ../../gcc/ifcvt.c profile_probability::operator-
      8 64 ../../gcc/internal-fn.c expand_addsub_overflow
      8 64 ../../gcc/internal-fn.c profile_probability::operator-
      8 64 ../../gcc/internal-fn.c profile_probability::very_likely
      8 64 ../../gcc/ipa-utils.c profile_probability::operator*
      8 64 ../../gcc/ipa-utils.c profile_probability::operator+
      8 64 ../../gcc/loop-doloop.c profile_probability::operator-
      8 64 ../../gcc/loop-unroll.c profile_probability::operator-
      8 64 ../../gcc/modulo-sched.c profile_probability::operator-
      8 64 ../../gcc/omp-expand.c expand_omp_for_static_chunk
      8 64 ../../gcc/omp-expand.c extract_omp_for_update_vars
      8 64 ../../gcc/omp-expand.c profile_probability::operator-
      8 64 ../../gcc/omp-simd-clone.c profile_probability::operator-
      8 64 ../../gcc/predict.c profile_probability::operator+=
      8 64 ../../gcc/predict.c profile_probability::operator-
      8 64 ../../gcc/predict.c profile_probability::operator-=
      8 64 ../../gcc/profile-count.c profile_count::combine_with_ipa_count
      8 64 ../../gcc/profile-count.c profile_count::compatible_p
      8 64 ../../gcc/profile-count.c profile_count::operator+
      8 64 ../../gcc/profile-count.c profile_count::probability_in
      8 64 ../../gcc/profile-count.c profile_probability::operator*
      8 64 ../../gcc/profile-count.c profile_probability::operator+
      8 64 ../../gcc/recog.c profile_probability::operator-
      8 64 ../../gcc/stmt.c profile_probability::operator+=
      8 64 ../../gcc/stmt.c profile_probability::operator-=
      8 64 ../../gcc/trans-mem.c profile_probability::operator-
      8 64 ../../gcc/tree-call-cdce.c profile_probability::operator-
      8 64 ../../gcc/tree-cfgcleanup.c profile_probability::operator+=
      8 64 ../../gcc/tree-cfg.c profile_probability::operator-=
      8 64 ../../gcc/tree-loop-distribution.c profile_probability::operator-
      8 64 ../../gcc/tree-parloops.c profile_probability::operator-
      8 64 ../../gcc/tree-profile.c profile_probability::operator-
      8 64 ../../gcc/tree-ssa-ifcombine.c profile_probability::operator*
      8 64 ../../gcc/tree-ssa-ifcombine.c profile_probability::operator+
      8 64 ../../gcc/tree-ssa-ifcombine.c profile_probability::operator-
      8 64 ../../gcc/tree-ssa-loop-im.c {anonymous}::pass_lim::execute
      8 64 ../../gcc/tree-ssa-loop-im.c profile_probability::operator-
      8 64 ../../gcc/tree-ssa-loop-manip.c profile_probability::operator-
      8 64 ../../gcc/tree-ssa-loop-split.c profile_probability::operator-
      8 64 ../../gcc/tree-ssa-loop-unswitch.c profile_probability::operator-
      8 64 ../../gcc/tree-ssa-reassoc.c profile_probability::operator-=
      8 64 ../../gcc/tree-ssa-threadupdate.c profile_probability::operator*=
      8 64 ../../gcc/tree-ssa-threadupdate.c profile_probability::operator-
      8 64 ../../gcc/tree-switch-conversion.c profile_probability::operator+
      8 64 ../../gcc/tree-switch-conversion.c profile_probability::operator+=
      8 64 ../../gcc/tree-switch-conversion.c profile_probability::operator-
      8 64 ../../gcc/tree-switch-conversion.c profile_probability::operator-=
      8 64 ../../gcc/tree-switch-conversion.c tree_switch_conversion::jump_table_cluster::emit
      8 64 ../../gcc/tree-switch-conversion.c tree_switch_conversion::switch_decision_tree::balance_case_nodes
      8 64 ../../gcc/tree-vect-loop.c profile_probability::operator-
      8 64 ../../gcc/tree-vect-loop-manip.c profile_probability::operator*
      8 64 ../../gcc/tree-vect-loop-manip.c profile_probability::operator+
      8 64 ../../gcc/tree-vect-loop-manip.c profile_probability::operator-
      8 64 ../../gcc/tree-vect-slp.c vect_slp_bb
      8 64 ../../gcc/tree-vect-stmts.c vectorizable_store
      8 64 ../../gcc/ubsan.c profile_probability::operator-
      8 64 ../../gcc/ubsan.c profile_probability::very_likely
      8 64 ../../gcc/value-prof.c profile_probability::operator-
      8 64 /home/jakub/src/gcc/gcc/testsuite/gcc.c-torture/execute/bf64-1.c main
     10 32 ../../gcc/genrecog.c populate_pattern_routine
     10 32 ../../gcc/stmt.c emit_case_dispatch_table
     10 32 ../../gcc/tree-ssa-loop-manip.c tree_transform_and_unroll_loop
     10 32 ../../gcc/tree-ssa-loop-unswitch.c tree_ssa_unswitch_loops
     10 32 /home/jakub/src/gcc/gcc/testsuite/gcc.c-torture/execute/921204-1.c main
     10 64 ../../gcc/cfgloop.c disambiguate_loops_with_multiple_latches
     10 64 ../../gcc/genrecog.c populate_pattern_routine
     10 64 ../../gcc/stmt.c emit_case_dispatch_table
     10 64 ../../gcc/tree-ssa-loop-manip.c tree_transform_and_unroll_loop
     10 64 ../../gcc/tree-ssa-loop-unswitch.c tree_ssa_unswitch_loops
     10 64 /home/jakub/src/gcc/gcc/testsuite/gcc.c-torture/execute/921204-1.c main
     11 64 /home/jakub/src/gcc/gcc/testsuite/gcc.c-torture/execute/pr70602.c main
     12 32 ../../gcc/asan.c create_cond_insert_point
     12 32 ../../gcc/cfg.c update_bb_profile_for_threading
     12 32 ../../gcc/omp-expand.c expand_omp_simd
     12 32 ../../gcc/tree-profile.c gimple_gen_ic_func_profiler
     12 32 /home/jakub/src/gcc/gcc/testsuite/gcc.c-torture/execute/bf-sign-1.c main
     12 64 ../../gcc/asan.c create_cond_insert_point
     12 64 ../../gcc/omp-expand.c expand_omp_simd
     12 64 ../../gcc/tree-profile.c gimple_gen_ic_func_profiler
     12 64 ../../gcc/tree-vect-loop-manip.c vect_do_peeling
     12 64 /home/jakub/src/gcc/gcc/testsuite/gcc.c-torture/execute/bf-sign-1.c main
     14 32 ../../gcc/cfgloopmanip.c scale_loop_profile
     14 32 ../../gcc/omp-expand.c expand_omp_for_init_counts.constprop
     14 32 ../../gcc/tree-loop-distribution.c loop_distribution::distribute_loop
     14 64 ../../gcc/cfg.c update_bb_profile_for_threading
     14 64 ../../gcc/cfgloopmanip.c scale_loop_profile
     14 64 ../../gcc/omp-expand.c expand_omp_for_init_counts.constprop
     14 64 ../../gcc/predict.c handle_missing_profiles
     14 64 ../../gcc/tree-loop-distribution.c loop_distribution::distribute_loop
     16 32 ../../gcc/ifcvt.c if_convert
     16 32 ../../gcc/profile-count.c profile_probability::combine_with_count
     16 32 ../../gcc/tree-parloops.c gen_parallel_loop
     16 32 ../../gcc/tree-ssa-threadupdate.c update_profile
     16 32 ../../gcc/ubsan.c ubsan_expand_ptr_ifn
     16 64 ../../gcc/ifcvt.c if_convert
     16 64 ../../gcc/tree-ssa-threadupdate.c update_profile
     16 64 ../../gcc/ubsan.c ubsan_expand_ptr_ifn
     18 32 ../../gcc/dojump.c do_jump_1
     18 64 ../../gcc/bb-reorder.c {anonymous}::pass_reorder_blocks::execute
     18 64 ../../gcc/dojump.c do_jump_1
     20 32 ../../gcc/hsa-gen.c {anonymous}::pass_gen_hsail::execute
     20 32 ../../gcc/omp-expand.c expand_omp_for_static_nochunk
     20 32 ../../gcc/predict.c combine_predictions_for_bb
     20 32 ../../gcc/predict.c force_edge_cold
     20 32 ../../gcc/tree-call-cdce.c shrink_wrap_one_built_in_call_with_conds
     20 64 ../../gcc/hsa-gen.c {anonymous}::pass_gen_hsail::execute
     20 64 ../../gcc/omp-expand.c expand_omp_for_static_nochunk
     20 64 ../../gcc/predict.c combine_predictions_for_bb
     20 64 ../../gcc/predict.c force_edge_cold
     20 64 ../../gcc/tree-call-cdce.c shrink_wrap_one_built_in_call_with_conds
     20 64 ../../gcc/tree-parloops.c gen_parallel_loop
     22 32 ../../gcc/dojump.c do_compare_rtx_and_jump
     22 32 ../../gcc/loop-doloop.c doloop_optimize_loops
     22 32 ../../gcc/tree-vect-loop-manip.c vect_loop_versioning
     22 64 ../../gcc/dojump.c do_compare_rtx_and_jump
     22 64 ../../gcc/loop-doloop.c doloop_optimize_loops
     22 64 ../../gcc/tree-vect-loop-manip.c vect_loop_versioning
     24 32 ../../gcc/modulo-sched.c sms_schedule
     24 32 ../../gcc/trans-mem.c expand_transaction
     24 64 ../../gcc/modulo-sched.c sms_schedule
     24 64 ../../gcc/profile-count.c profile_probability::combine_with_count
     24 64 ../../gcc/trans-mem.c expand_transaction
     26 32 ../../gcc/loop-unroll.c unroll_loops
     26 32 ../../gcc/omp-simd-clone.c expand_simd_clones
     26 32 ../../gcc/tree-ssa-loop-im.c store_motion_loop
     26 64 ../../gcc/loop-unroll.c unroll_loops
     26 64 ../../gcc/omp-simd-clone.c expand_simd_clones
     26 64 ../../gcc/tree-ssa-loop-im.c store_motion_loop
     30 32 ../../gcc/bb-reorder.c sanitize_hot_paths
     30 32 ../../gcc/value-prof.c gimple_value_profile_transformations
     30 64 ../../gcc/bb-reorder.c sanitize_hot_paths
     30 64 ../../gcc/value-prof.c gimple_value_profile_transformations
     32 32 ../../gcc/omp-expand.c expand_omp_for_generic
     32 32 ../../gcc/tree-complex.c {anonymous}::pass_lower_complex::execute
     32 32 ../../gcc/tree-vect-loop-manip.c vect_do_peeling
     32 64 ../../gcc/omp-expand.c expand_omp_for_generic
     32 64 ../../gcc/tree-complex.c {anonymous}::pass_lower_complex::execute
     34 32 ../../gcc/internal-fn.c expand_mul_overflow
     34 32 ../../gcc/omp-expand.c expand_oacc_for
     34 64 ../../gcc/internal-fn.c expand_mul_overflow
     34 64 ../../gcc/omp-expand.c expand_oacc_for
     34 64 ../../gcc/predict.c set_even_probabilities
     36 32 ../../gcc/profile.c compute_branch_probabilities
     36 64 ../../gcc/profile.c compute_branch_probabilities
     38 32 ../../gcc/predict.c set_even_probabilities
     38 32 ../../gcc/tree-ssa-loop-split.c {anonymous}::pass_loop_split::execute
     38 64 ../../gcc/tree-ssa-loop-split.c tree_ssa_split_loops
     46 32 ../../gcc/gimple-loop-versioning.cc {anonymous}::pass_loop_versioning::_ZN12_GLOBAL__N_120pass_loop_versioning7executeEP8function.part.0
     48 64 ../../gcc/gimple-loop-versioning.cc {anonymous}::pass_loop_versioning::_ZN12_GLOBAL__N_120pass_loop_versioning7executeEP8function.part.0
     66 32 ../../gcc/predict.c determine_unlikely_bbs
     66 64 ../../gcc/predict.c determine_unlikely_bbs

Comments

Richard Biener Feb. 24, 2020, 11:43 a.m. UTC | #1
On Sat, 22 Feb 2020, Jakub Jelinek wrote:

> Hi!
> 
> The following patch adds support for bitfields to push_partial_def.
> Previously pd.offset and pd.size were counted in bytes and maxsizei
> in bits, now everything is counted in bits.
> 
> Not really sure how much of the further code can be outlined and moved, e.g. 
> the full def and partial def code doesn't have pretty much anything in
> common (the partial defs case basically have some load bit range and a set
> of store bit ranges that at least partially overlap and we need to handle
> all the different cases, like negative pd.offset or non-negative, little vs. 
> bit endian, size so small that we need to preserve original bits on both
> sides of the byte, size that fits or is too large.
> Perhaps the storing of some value into a middle of existing buffer (i.e.
> what push_partial_def now does in the loop) could, but the candidate for
> sharing would be most likely store-merging rather than the other spots in
> sccvn, and I think it is better not to touch store-merging at this stage.
> 
> Yes, I've thought about trying to do everything in place, but the code is
> quite hard to understand and get right already now and if we tried to do the
> optimize on the fly, it would need more special cases and would for gcov
> coverage need more testcases to cover it.  Most of the time the sizes will
> be small.  Furthermore, for bitfields native_encode_expr stores actually
> number of bytes in the mode and not say actual bitsize rounded up to bytes,
> so it wouldn't be just a matter of saving/restoring bytes at the start and
> end, but we might need even 7 further bytes e.g. for __int128 bitfields.
> Perhaps we could have just a fast path for the case where everything is byte
> aligned and (for integral types the mode bitsize is equal to the size too)?
> 
> Bootstrapped/regtested on {x86_64,i686,powerpc64{,le}}-linux, on
> powerpc64-linux with -m32/-m64 testing, on {x86_64,i686}-linux
> bootstrap/regtests together I've also gathered statistics, where the
> new code (where something in the partial defs handling wasn't byte
> aligned/sized and still found a constant) triggered 5266 times,
> attached is sort | uniq -c | sort -n list of those, i.e. first column
> is number of times it hit in the same file/function/wordsize (across
> the 2 bootstraps/regtests), second is BITS_PER_WORD, third is filename
> and last is current_function_name ().
> 
> Ok for trunk?

OK.

Thanks,
Richard.

> 2020-02-22  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR tree-optimization/93582
> 	* tree-ssa-sccvn.c (vn_walk_cb_data::push_partial_def): Consider
> 	pd.offset and pd.size to be counted in bits rather than bytes, add
> 	support for maxsizei that is not a multiple of BITS_PER_UNIT and
> 	handle bitfield stores and loads.
> 	(vn_reference_lookup_3): Don't call ranges_known_overlap_p with
> 	uncomparable quantities - bytes vs. bits.  Allow push_partial_def
> 	on offsets/sizes that aren't multiple of BITS_PER_UNIT and adjust
> 	pd.offset/pd.size to be counted in bits rather than bytes.
> 	Formatting fix.  Rename shadowed len variable to buflen.
> 
> 	* gcc.dg/tree-ssa/pr93582-4.c: New test.
> 	* gcc.dg/tree-ssa/pr93582-5.c: New test.
> 	* gcc.dg/tree-ssa/pr93582-6.c: New test.
> 	* gcc.dg/tree-ssa/pr93582-7.c: New test.
> 	* gcc.dg/tree-ssa/pr93582-8.c: New test.
> 
> --- gcc/tree-ssa-sccvn.c.jj	2020-02-18 08:52:26.156952846 +0100
> +++ gcc/tree-ssa-sccvn.c	2020-02-18 15:44:53.446837342 +0100
> @@ -1774,7 +1774,11 @@ vn_walk_cb_data::push_partial_def (const
>    const HOST_WIDE_INT bufsize = 64;
>    /* We're using a fixed buffer for encoding so fail early if the object
>       we want to interpret is bigger.  */
> -  if (maxsizei > bufsize * BITS_PER_UNIT)
> +  if (maxsizei > bufsize * BITS_PER_UNIT
> +      || CHAR_BIT != 8
> +      || BITS_PER_UNIT != 8
> +      /* Not prepared to handle PDP endian.  */
> +      || BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
>      return (void *)-1;
>  
>    bool pd_constant_p = (TREE_CODE (pd.rhs) == CONSTRUCTOR
> @@ -1854,41 +1858,39 @@ vn_walk_cb_data::push_partial_def (const
>    /* Now we have merged newr into the range tree.  When we have covered
>       [offseti, sizei] then the tree will contain exactly one node which has
>       the desired properties and it will be 'r'.  */
> -  if (!known_subrange_p (0, maxsizei / BITS_PER_UNIT, r->offset, r->size))
> +  if (!known_subrange_p (0, maxsizei, r->offset, r->size))
>      /* Continue looking for partial defs.  */
>      return NULL;
>  
>    /* Now simply native encode all partial defs in reverse order.  */
>    unsigned ndefs = partial_defs.length ();
>    /* We support up to 512-bit values (for V8DFmode).  */
> -  unsigned char buffer[bufsize];
> +  unsigned char buffer[bufsize + 1];
> +  unsigned char this_buffer[bufsize + 1];
>    int len;
>  
> +  memset (buffer, 0, bufsize + 1);
> +  unsigned needed_len = ROUND_UP (maxsizei, BITS_PER_UNIT) / BITS_PER_UNIT;
>    while (!partial_defs.is_empty ())
>      {
>        pd_data pd = partial_defs.pop ();
> -      gcc_checking_assert (pd.offset < bufsize);
> +      unsigned int amnt;
>        if (TREE_CODE (pd.rhs) == CONSTRUCTOR)
> -	/* Empty CONSTRUCTOR.  */
> -	memset (buffer + MAX (0, pd.offset),
> -		0, MIN (bufsize - MAX (0, pd.offset),
> -			pd.size + MIN (0, pd.offset)));
> +	{
> +	  /* Empty CONSTRUCTOR.  */
> +	  if (pd.size >= needed_len * BITS_PER_UNIT)
> +	    len = needed_len;
> +	  else
> +	    len = ROUND_UP (pd.size, BITS_PER_UNIT) / BITS_PER_UNIT;
> +	  memset (this_buffer, 0, len);
> +	}
>        else
>  	{
> -	  unsigned pad = 0;
> -	  if (BYTES_BIG_ENDIAN
> -	      && is_a <scalar_mode> (TYPE_MODE (TREE_TYPE (pd.rhs))))
> -	    {
> -	      /* On big-endian the padding is at the 'front' so just skip
> -		 the initial bytes.  */
> -	      fixed_size_mode mode
> -		= as_a <fixed_size_mode> (TYPE_MODE (TREE_TYPE (pd.rhs)));
> -	      pad = GET_MODE_SIZE (mode) - pd.size;
> -	    }
> -	  len = native_encode_expr (pd.rhs, buffer + MAX (0, pd.offset),
> -				    bufsize - MAX (0, pd.offset),
> -				    MAX (0, -pd.offset) + pad);
> -	  if (len <= 0 || len < (pd.size - MAX (0, -pd.offset)))
> +	  len = native_encode_expr (pd.rhs, this_buffer, bufsize,
> +				    MAX (0, -pd.offset) / BITS_PER_UNIT);
> +	  if (len <= 0
> +	      || len < (ROUND_UP (pd.size, BITS_PER_UNIT) / BITS_PER_UNIT
> +			- MAX (0, -pd.offset) / BITS_PER_UNIT))
>  	    {
>  	      if (dump_file && (dump_flags & TDF_DETAILS))
>  		fprintf (dump_file, "Failed to encode %u "
> @@ -1896,6 +1898,125 @@ vn_walk_cb_data::push_partial_def (const
>  	      return (void *)-1;
>  	    }
>  	}
> +
> +      unsigned char *p = buffer;
> +      HOST_WIDE_INT size = pd.size;
> +      if (pd.offset < 0)
> +	size -= ROUND_DOWN (-pd.offset, BITS_PER_UNIT);
> +      this_buffer[len] = 0;
> +      if (BYTES_BIG_ENDIAN)
> +	{
> +	  /* LSB of this_buffer[len - 1] byte should be at
> +	     pd.offset + pd.size - 1 bits in buffer.  */
> +	  amnt = ((unsigned HOST_WIDE_INT) pd.offset
> +		  + pd.size) % BITS_PER_UNIT;
> +	  if (amnt)
> +	    shift_bytes_in_array_right (this_buffer, len + 1, amnt);
> +	  unsigned char *q = this_buffer;
> +	  unsigned int off = 0;
> +	  if (pd.offset >= 0)
> +	    {
> +	      unsigned int msk;
> +	      off = pd.offset / BITS_PER_UNIT;
> +	      gcc_assert (off < needed_len);
> +	      p = buffer + off;
> +	      if (size <= amnt)
> +		{
> +		  msk = ((1 << size) - 1) << (BITS_PER_UNIT - amnt);
> +		  *p = (*p & ~msk) | (this_buffer[len] & msk);
> +		  size = 0;
> +		}
> +	      else
> +		{
> +		  if (TREE_CODE (pd.rhs) != CONSTRUCTOR)
> +		    q = (this_buffer + len
> +			 - (ROUND_UP (size - amnt, BITS_PER_UNIT)
> +			    / BITS_PER_UNIT));
> +		  if (pd.offset % BITS_PER_UNIT)
> +		    {
> +		      msk = -1U << (BITS_PER_UNIT
> +				    - (pd.offset % BITS_PER_UNIT));
> +		      *p = (*p & msk) | (*q & ~msk);
> +		      p++;
> +		      q++;
> +		      off++;
> +		      size -= BITS_PER_UNIT - (pd.offset % BITS_PER_UNIT);
> +		      gcc_assert (size >= 0);
> +		    }
> +		}
> +	    }
> +	  else if (TREE_CODE (pd.rhs) != CONSTRUCTOR)
> +	    {
> +	      q = (this_buffer + len
> +		   - (ROUND_UP (size - amnt, BITS_PER_UNIT)
> +		      / BITS_PER_UNIT));
> +	      if (pd.offset % BITS_PER_UNIT)
> +		{
> +		  q++;
> +		  size -= BITS_PER_UNIT - ((unsigned HOST_WIDE_INT) pd.offset
> +					   % BITS_PER_UNIT);
> +		  gcc_assert (size >= 0);
> +		}
> +	    }
> +	  if ((unsigned HOST_WIDE_INT) size / BITS_PER_UNIT + off
> +	      > needed_len)
> +	    size = (needed_len - off) * BITS_PER_UNIT;
> +	  memcpy (p, q, size / BITS_PER_UNIT);
> +	  if (size % BITS_PER_UNIT)
> +	    {
> +	      unsigned int msk
> +		= -1U << (BITS_PER_UNIT - (size % BITS_PER_UNIT));
> +	      p += size / BITS_PER_UNIT;
> +	      q += size / BITS_PER_UNIT;
> +	      *p = (*q & msk) | (*p & ~msk);
> +	    }
> +	}
> +      else
> +	{
> +	  size = MIN (size, (HOST_WIDE_INT) needed_len * BITS_PER_UNIT);
> +	  if (pd.offset >= 0)
> +	    {
> +	      /* LSB of this_buffer[0] byte should be at pd.offset bits
> +		 in buffer.  */
> +	      unsigned int msk;
> +	      amnt = pd.offset % BITS_PER_UNIT;
> +	      if (amnt)
> +		shift_bytes_in_array_left (this_buffer, len + 1, amnt);
> +	      unsigned int off = pd.offset / BITS_PER_UNIT;
> +	      gcc_assert (off < needed_len);
> +	      p = buffer + off;
> +	      if (amnt + size < BITS_PER_UNIT)
> +		{
> +		  /* Low amnt bits come from *p, then size bits
> +		     from this_buffer[0] and the remaining again from
> +		     *p.  */
> +		  msk = ((1 << size) - 1) << amnt;
> +		  *p = (*p & ~msk) | (this_buffer[0] & msk);
> +		  size = 0;
> +		}
> +	      else if (amnt)
> +		{
> +		  msk = -1U << amnt;
> +		  *p = (*p & ~msk) | (this_buffer[0] & msk);
> +		  p++;
> +		  size -= (BITS_PER_UNIT - amnt);
> +		}
> +	    }
> +	  else
> +	    {
> +	      amnt = (unsigned HOST_WIDE_INT) pd.offset % BITS_PER_UNIT;
> +	      if (amnt)
> +		shift_bytes_in_array_left (this_buffer, len + 1, amnt);
> +	    }
> +	  memcpy (p, this_buffer + (amnt != 0), size / BITS_PER_UNIT);
> +	  p += size / BITS_PER_UNIT;
> +	  if (size % BITS_PER_UNIT)
> +	    {
> +	      unsigned int msk = -1U << (size % BITS_PER_UNIT);
> +	      *p = (this_buffer[(amnt != 0) + size / BITS_PER_UNIT]
> +		    & ~msk) | (*p & msk);
> +	    }
> +	}
>      }
>  
>    tree type = vr->type;
> @@ -1903,7 +2024,26 @@ vn_walk_cb_data::push_partial_def (const
>       access size.  */
>    if (INTEGRAL_TYPE_P (vr->type) && maxsizei != TYPE_PRECISION (vr->type))
>      type = build_nonstandard_integer_type (maxsizei, TYPE_UNSIGNED (type));
> -  tree val = native_interpret_expr (type, buffer, maxsizei / BITS_PER_UNIT);
> +  tree val;
> +  if (BYTES_BIG_ENDIAN)
> +    {
> +      unsigned sz = needed_len;
> +      if (maxsizei % BITS_PER_UNIT)
> +	shift_bytes_in_array_right (buffer, needed_len,
> +				    BITS_PER_UNIT
> +				    - (maxsizei % BITS_PER_UNIT));
> +      if (INTEGRAL_TYPE_P (type))
> +	sz = GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (type));
> +      if (sz > needed_len)
> +	{
> +	  memcpy (this_buffer + (sz - needed_len), buffer, needed_len);
> +	  val = native_interpret_expr (type, this_buffer, sz);
> +	}
> +      else
> +	val = native_interpret_expr (type, buffer, needed_len);
> +    }
> +  else
> +    val = native_interpret_expr (type, buffer, bufsize);
>    /* If we chop off bits because the types precision doesn't match the memory
>       access size this is ok when optimizing reads but not when called from
>       the DSE code during elimination.  */
> @@ -2478,8 +2618,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree
>  	  tree val;
>  	  if (integer_zerop (gimple_call_arg (def_stmt, 1)))
>  	    val = build_zero_cst (vr->type);
> -	  else if (INTEGRAL_TYPE_P (vr->type)
> -		   && known_eq (ref->size, 8))
> +	  else if (INTEGRAL_TYPE_P (vr->type) && known_eq (ref->size, 8))
>  	    {
>  	      gimple_match_op res_op (gimple_match_cond::UNCOND, NOP_EXPR,
>  				      vr->type, gimple_call_arg (def_stmt, 1));
> @@ -2491,11 +2630,11 @@ vn_reference_lookup_3 (ao_ref *ref, tree
>  	    }
>  	  else
>  	    {
> -	      unsigned len = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (vr->type));
> -	      unsigned char *buf = XALLOCAVEC (unsigned char, len);
> +	      unsigned buflen = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (vr->type));
> +	      unsigned char *buf = XALLOCAVEC (unsigned char, buflen);
>  	      memset (buf, TREE_INT_CST_LOW (gimple_call_arg (def_stmt, 1)),
> -		      len);
> -	      val = native_interpret_expr (vr->type, buf, len);
> +		      buflen);
> +	      val = native_interpret_expr (vr->type, buf, buflen);
>  	      if (!val)
>  		return (void *)-1;
>  	    }
> @@ -2506,15 +2645,17 @@ vn_reference_lookup_3 (ao_ref *ref, tree
>  	       && integer_zerop (gimple_call_arg (def_stmt, 1))
>  	       && tree_fits_poly_int64_p (len)
>  	       && tree_to_poly_int64 (len).is_constant (&leni)
> +	       && leni <= INTTYPE_MAXIMUM (HOST_WIDE_INT) / BITS_PER_UNIT
>  	       && offset.is_constant (&offseti)
>  	       && offset2.is_constant (&offset2i)
>  	       && maxsize.is_constant (&maxsizei)
> -	       && ranges_known_overlap_p (offseti, maxsizei, offset2i, leni))
> +	       && ranges_known_overlap_p (offseti, maxsizei, offset2i,
> +					  leni << LOG2_BITS_PER_UNIT))
>  	{
>  	  pd_data pd;
>  	  pd.rhs = build_constructor (NULL_TREE, NULL);
> -	  pd.offset = (offset2i - offseti) / BITS_PER_UNIT;
> -	  pd.size = leni;
> +	  pd.offset = offset2i - offseti;
> +	  pd.size = leni << LOG2_BITS_PER_UNIT;
>  	  return data->push_partial_def (pd, 0, maxsizei);
>  	}
>      }
> @@ -2558,13 +2699,9 @@ vn_reference_lookup_3 (ao_ref *ref, tree
>  	    }
>  	  else if (known_eq (ref->size, maxsize)
>  		   && maxsize.is_constant (&maxsizei)
> -		   && maxsizei % BITS_PER_UNIT == 0
>  		   && offset.is_constant (&offseti)
> -		   && offseti % BITS_PER_UNIT == 0
>  		   && offset2.is_constant (&offset2i)
> -		   && offset2i % BITS_PER_UNIT == 0
>  		   && size2.is_constant (&size2i)
> -		   && size2i % BITS_PER_UNIT == 0
>  		   && ranges_known_overlap_p (offseti, maxsizei,
>  					      offset2i, size2i))
>  	    {
> @@ -2573,8 +2710,8 @@ vn_reference_lookup_3 (ao_ref *ref, tree
>  		 by a later def.  */
>  	      pd_data pd;
>  	      pd.rhs = gimple_assign_rhs1 (def_stmt);
> -	      pd.offset = (offset2i - offseti) / BITS_PER_UNIT;
> -	      pd.size = size2i / BITS_PER_UNIT;
> +	      pd.offset = offset2i - offseti;
> +	      pd.size = size2i;
>  	      return data->push_partial_def (pd, get_alias_set (lhs), maxsizei);
>  	    }
>  	}
> @@ -2719,19 +2856,15 @@ vn_reference_lookup_3 (ao_ref *ref, tree
>  		}
>  	    }
>  	  else if (ranges_known_overlap_p (offseti, maxsizei, offset2i,
> -					   size2i)
> -		   && maxsizei % BITS_PER_UNIT == 0
> -		   && offseti % BITS_PER_UNIT == 0
> -		   && size2i % BITS_PER_UNIT == 0
> -		   && offset2i % BITS_PER_UNIT == 0)
> +					   size2i))
>  	    {
>  	      pd_data pd;
>  	      tree rhs = gimple_assign_rhs1 (def_stmt);
>  	      if (TREE_CODE (rhs) == SSA_NAME)
>  		rhs = SSA_VAL (rhs);
>  	      pd.rhs = rhs;
> -	      pd.offset = (offset2i - offseti) / BITS_PER_UNIT;
> -	      pd.size = size2i / BITS_PER_UNIT;
> +	      pd.offset = offset2i - offseti;
> +	      pd.size = size2i;
>  	      return data->push_partial_def (pd, get_alias_set (lhs), maxsizei);
>  	    }
>  	}
> @@ -2803,19 +2936,15 @@ vn_reference_lookup_3 (ao_ref *ref, tree
>  		return data->finish (get_alias_set (lhs), val);
>  	    }
>  	  else if (maxsize.is_constant (&maxsizei)
> -		   && maxsizei % BITS_PER_UNIT == 0
>  		   && offset.is_constant (&offseti)
> -		   && offseti % BITS_PER_UNIT == 0
>  		   && offset2.is_constant (&offset2i)
> -		   && offset2i % BITS_PER_UNIT == 0
>  		   && size2.is_constant (&size2i)
> -		   && size2i % BITS_PER_UNIT == 0
>  		   && ranges_known_overlap_p (offset, maxsize, offset2, size2))
>  	    {
>  	      pd_data pd;
>  	      pd.rhs = SSA_VAL (def_rhs);
> -	      pd.offset = (offset2i - offseti) / BITS_PER_UNIT;
> -	      pd.size = size2i / BITS_PER_UNIT;
> +	      pd.offset = offset2i - offseti;
> +	      pd.size = size2i;
>  	      return data->push_partial_def (pd, get_alias_set (lhs), maxsizei);
>  	    }
>  	}
> @@ -2945,14 +3074,14 @@ vn_reference_lookup_3 (ao_ref *ref, tree
>  	     coming from targets that like to gimplify init-ctors as
>  	     aggregate copies from constant data like aarch64 for
>  	     PR83518.  */
> -	  if (maxsize.is_constant (&maxsizei)
> -	      && known_eq (ref->size, maxsize))
> +	  if (maxsize.is_constant (&maxsizei) && known_eq (ref->size, maxsize))
>  	    {
>  	      pd_data pd;
>  	      pd.rhs = val;
>  	      pd.offset = 0;
> -	      pd.size = maxsizei / BITS_PER_UNIT;
> -	      return data->push_partial_def (pd, get_alias_set (lhs), maxsizei);
> +	      pd.size = maxsizei;
> +	      return data->push_partial_def (pd, get_alias_set (lhs),
> +					     maxsizei);
>  	    }
>  	}
>  
> --- gcc/testsuite/gcc.dg/tree-ssa/pr93582-4.c.jj	2020-02-18 10:39:51.709597019 +0100
> +++ gcc/testsuite/gcc.dg/tree-ssa/pr93582-4.c	2020-02-18 10:39:51.708597035 +0100
> @@ -0,0 +1,23 @@
> +/* PR tree-optimization/93582 */
> +/* { dg-do compile { target int32 } } */
> +/* { dg-options "-O2 -fdump-tree-fre1" } */
> +/* { dg-final { scan-tree-dump "return -1991560811;" "fre1" { target le } } } */
> +/* { dg-final { scan-tree-dump "return -733324916;" "fre1" { target be } } } */
> +
> +union U {
> +  struct S { int a : 1, b : 4, c : 27; } s;
> +  unsigned int i;
> +};
> +struct A { char a[24]; union U u; };
> +void bar (struct A *);
> +
> +int
> +foo (void)
> +{
> +  struct A a;
> +  bar (&a);
> +  a.u.s.a = -1;
> +  a.u.s.b = -6;
> +  a.u.s.c = -62236276;
> +  return a.u.i;
> +}
> --- gcc/testsuite/gcc.dg/tree-ssa/pr93582-5.c.jj	2020-02-18 10:39:51.709597019 +0100
> +++ gcc/testsuite/gcc.dg/tree-ssa/pr93582-5.c	2020-02-18 10:39:51.709597019 +0100
> @@ -0,0 +1,25 @@
> +/* PR tree-optimization/93582 */
> +/* { dg-do compile { target int32 } } */
> +/* { dg-options "-O2 -fdump-tree-fre1" } */
> +/* { dg-final { scan-tree-dump "return -1462729318;" "fre1" { target le } } } */
> +/* { dg-final { scan-tree-dump "return 1300568597;" "fre1" { target be } } } */
> +
> +union U {
> +  struct S { int a : 1, b : 7, c : 8, d : 11, e : 5; } s;
> +  unsigned int i;
> +};
> +struct A { char a[8]; union U u; };
> +void bar (struct A *);
> +
> +int
> +foo (void)
> +{
> +  struct A a;
> +  bar (&a);
> +  a.u.s.a = 0;
> +  a.u.s.b = -51;
> +  a.u.s.c = -123;
> +  a.u.s.d = 208;
> +  a.u.s.e = -11;
> +  return a.u.i;
> +}
> --- gcc/testsuite/gcc.dg/tree-ssa/pr93582-6.c.jj	2020-02-18 10:39:51.709597019 +0100
> +++ gcc/testsuite/gcc.dg/tree-ssa/pr93582-6.c	2020-02-18 10:39:51.709597019 +0100
> @@ -0,0 +1,24 @@
> +/* PR tree-optimization/93582 */
> +/* { dg-do compile { target int32 } } */
> +/* { dg-options "-O2 -fdump-tree-fre1" } */
> +/* { dg-final { scan-tree-dump "return 890118;" "fre1" { target le } } } */
> +/* { dg-final { scan-tree-dump "return 447899;" "fre1" { target be } } } */
> +
> +union U {
> +  struct S { int a : 16, b : 5, c : 10, d : 1; } s;
> +  struct T { int a : 8, b : 21, c : 3; } t;
> +};
> +struct A { char a[4]; union U u; };
> +void bar (struct A *);
> +
> +int
> +foo (void)
> +{
> +  struct A a;
> +  bar (&a);
> +  a.u.s.a = 1590;
> +  a.u.s.b = -11;
> +  a.u.s.c = 620;
> +  a.u.s.d = -1;
> +  return a.u.t.b;
> +}
> --- gcc/testsuite/gcc.dg/tree-ssa/pr93582-7.c.jj	2020-02-18 10:39:51.709597019 +0100
> +++ gcc/testsuite/gcc.dg/tree-ssa/pr93582-7.c	2020-02-18 10:39:51.709597019 +0100
> @@ -0,0 +1,24 @@
> +/* PR tree-optimization/93582 */
> +/* { dg-do compile { target int32 } } */
> +/* { dg-options "-O2 -fdump-tree-fre1" } */
> +/* { dg-final { scan-tree-dump "return -413012;" "fre1" { target le } } } */
> +/* { dg-final { scan-tree-dump "return -611112;" "fre1" { target be } } } */
> +
> +union U {
> +  struct S { int a : 12, b : 5, c : 10, d : 5; } s;
> +  struct T { int a : 7, b : 21, c : 4; } t;
> +};
> +struct A { char a[48]; union U u; };
> +void bar (struct A *);
> +
> +int
> +foo (void)
> +{
> +  struct A a;
> +  bar (&a);
> +  a.u.s.a = 1590;
> +  a.u.s.b = -11;
> +  a.u.s.c = -404;
> +  a.u.s.d = 7;
> +  return a.u.t.b;
> +}
> --- gcc/testsuite/gcc.dg/tree-ssa/pr93582-8.c.jj	2020-02-15 00:40:16.234371422 +0100
> +++ gcc/testsuite/gcc.dg/tree-ssa/pr93582-8.c	2020-02-18 16:06:31.002311978 +0100
> @@ -0,0 +1,14 @@
> +/* PR tree-optimization/93582 */
> +/* { dg-do compile { target int32 } } */
> +/* { dg-options "-O2 -fdump-tree-fre1" } */
> +/* { dg-final { scan-tree-dump "return 0;" "fre1" { target le } } } */
> +/* { dg-final { scan-tree-dump "return -8531;" "fre1" { target be } } } */
> +
> +short
> +foo (void)
> +{
> +  union U { char c[32]; short s[16]; int i[8]; } u;
> +  __builtin_memset (u.c + 1, '\0', 5);
> +  u.s[3] = 0xdead;
> +  return u.i[1];
> +}
> 
> 	Jakub
>
diff mbox series

Patch

--- gcc/tree-ssa-sccvn.c.jj	2020-02-18 08:52:26.156952846 +0100
+++ gcc/tree-ssa-sccvn.c	2020-02-18 15:44:53.446837342 +0100
@@ -1774,7 +1774,11 @@  vn_walk_cb_data::push_partial_def (const
   const HOST_WIDE_INT bufsize = 64;
   /* We're using a fixed buffer for encoding so fail early if the object
      we want to interpret is bigger.  */
-  if (maxsizei > bufsize * BITS_PER_UNIT)
+  if (maxsizei > bufsize * BITS_PER_UNIT
+      || CHAR_BIT != 8
+      || BITS_PER_UNIT != 8
+      /* Not prepared to handle PDP endian.  */
+      || BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
     return (void *)-1;
 
   bool pd_constant_p = (TREE_CODE (pd.rhs) == CONSTRUCTOR
@@ -1854,41 +1858,39 @@  vn_walk_cb_data::push_partial_def (const
   /* Now we have merged newr into the range tree.  When we have covered
      [offseti, sizei] then the tree will contain exactly one node which has
      the desired properties and it will be 'r'.  */
-  if (!known_subrange_p (0, maxsizei / BITS_PER_UNIT, r->offset, r->size))
+  if (!known_subrange_p (0, maxsizei, r->offset, r->size))
     /* Continue looking for partial defs.  */
     return NULL;
 
   /* Now simply native encode all partial defs in reverse order.  */
   unsigned ndefs = partial_defs.length ();
   /* We support up to 512-bit values (for V8DFmode).  */
-  unsigned char buffer[bufsize];
+  unsigned char buffer[bufsize + 1];
+  unsigned char this_buffer[bufsize + 1];
   int len;
 
+  memset (buffer, 0, bufsize + 1);
+  unsigned needed_len = ROUND_UP (maxsizei, BITS_PER_UNIT) / BITS_PER_UNIT;
   while (!partial_defs.is_empty ())
     {
       pd_data pd = partial_defs.pop ();
-      gcc_checking_assert (pd.offset < bufsize);
+      unsigned int amnt;
       if (TREE_CODE (pd.rhs) == CONSTRUCTOR)
-	/* Empty CONSTRUCTOR.  */
-	memset (buffer + MAX (0, pd.offset),
-		0, MIN (bufsize - MAX (0, pd.offset),
-			pd.size + MIN (0, pd.offset)));
+	{
+	  /* Empty CONSTRUCTOR.  */
+	  if (pd.size >= needed_len * BITS_PER_UNIT)
+	    len = needed_len;
+	  else
+	    len = ROUND_UP (pd.size, BITS_PER_UNIT) / BITS_PER_UNIT;
+	  memset (this_buffer, 0, len);
+	}
       else
 	{
-	  unsigned pad = 0;
-	  if (BYTES_BIG_ENDIAN
-	      && is_a <scalar_mode> (TYPE_MODE (TREE_TYPE (pd.rhs))))
-	    {
-	      /* On big-endian the padding is at the 'front' so just skip
-		 the initial bytes.  */
-	      fixed_size_mode mode
-		= as_a <fixed_size_mode> (TYPE_MODE (TREE_TYPE (pd.rhs)));
-	      pad = GET_MODE_SIZE (mode) - pd.size;
-	    }
-	  len = native_encode_expr (pd.rhs, buffer + MAX (0, pd.offset),
-				    bufsize - MAX (0, pd.offset),
-				    MAX (0, -pd.offset) + pad);
-	  if (len <= 0 || len < (pd.size - MAX (0, -pd.offset)))
+	  len = native_encode_expr (pd.rhs, this_buffer, bufsize,
+				    MAX (0, -pd.offset) / BITS_PER_UNIT);
+	  if (len <= 0
+	      || len < (ROUND_UP (pd.size, BITS_PER_UNIT) / BITS_PER_UNIT
+			- MAX (0, -pd.offset) / BITS_PER_UNIT))
 	    {
 	      if (dump_file && (dump_flags & TDF_DETAILS))
 		fprintf (dump_file, "Failed to encode %u "
@@ -1896,6 +1898,125 @@  vn_walk_cb_data::push_partial_def (const
 	      return (void *)-1;
 	    }
 	}
+
+      unsigned char *p = buffer;
+      HOST_WIDE_INT size = pd.size;
+      if (pd.offset < 0)
+	size -= ROUND_DOWN (-pd.offset, BITS_PER_UNIT);
+      this_buffer[len] = 0;
+      if (BYTES_BIG_ENDIAN)
+	{
+	  /* LSB of this_buffer[len - 1] byte should be at
+	     pd.offset + pd.size - 1 bits in buffer.  */
+	  amnt = ((unsigned HOST_WIDE_INT) pd.offset
+		  + pd.size) % BITS_PER_UNIT;
+	  if (amnt)
+	    shift_bytes_in_array_right (this_buffer, len + 1, amnt);
+	  unsigned char *q = this_buffer;
+	  unsigned int off = 0;
+	  if (pd.offset >= 0)
+	    {
+	      unsigned int msk;
+	      off = pd.offset / BITS_PER_UNIT;
+	      gcc_assert (off < needed_len);
+	      p = buffer + off;
+	      if (size <= amnt)
+		{
+		  msk = ((1 << size) - 1) << (BITS_PER_UNIT - amnt);
+		  *p = (*p & ~msk) | (this_buffer[len] & msk);
+		  size = 0;
+		}
+	      else
+		{
+		  if (TREE_CODE (pd.rhs) != CONSTRUCTOR)
+		    q = (this_buffer + len
+			 - (ROUND_UP (size - amnt, BITS_PER_UNIT)
+			    / BITS_PER_UNIT));
+		  if (pd.offset % BITS_PER_UNIT)
+		    {
+		      msk = -1U << (BITS_PER_UNIT
+				    - (pd.offset % BITS_PER_UNIT));
+		      *p = (*p & msk) | (*q & ~msk);
+		      p++;
+		      q++;
+		      off++;
+		      size -= BITS_PER_UNIT - (pd.offset % BITS_PER_UNIT);
+		      gcc_assert (size >= 0);
+		    }
+		}
+	    }
+	  else if (TREE_CODE (pd.rhs) != CONSTRUCTOR)
+	    {
+	      q = (this_buffer + len
+		   - (ROUND_UP (size - amnt, BITS_PER_UNIT)
+		      / BITS_PER_UNIT));
+	      if (pd.offset % BITS_PER_UNIT)
+		{
+		  q++;
+		  size -= BITS_PER_UNIT - ((unsigned HOST_WIDE_INT) pd.offset
+					   % BITS_PER_UNIT);
+		  gcc_assert (size >= 0);
+		}
+	    }
+	  if ((unsigned HOST_WIDE_INT) size / BITS_PER_UNIT + off
+	      > needed_len)
+	    size = (needed_len - off) * BITS_PER_UNIT;
+	  memcpy (p, q, size / BITS_PER_UNIT);
+	  if (size % BITS_PER_UNIT)
+	    {
+	      unsigned int msk
+		= -1U << (BITS_PER_UNIT - (size % BITS_PER_UNIT));
+	      p += size / BITS_PER_UNIT;
+	      q += size / BITS_PER_UNIT;
+	      *p = (*q & msk) | (*p & ~msk);
+	    }
+	}
+      else
+	{
+	  size = MIN (size, (HOST_WIDE_INT) needed_len * BITS_PER_UNIT);
+	  if (pd.offset >= 0)
+	    {
+	      /* LSB of this_buffer[0] byte should be at pd.offset bits
+		 in buffer.  */
+	      unsigned int msk;
+	      amnt = pd.offset % BITS_PER_UNIT;
+	      if (amnt)
+		shift_bytes_in_array_left (this_buffer, len + 1, amnt);
+	      unsigned int off = pd.offset / BITS_PER_UNIT;
+	      gcc_assert (off < needed_len);
+	      p = buffer + off;
+	      if (amnt + size < BITS_PER_UNIT)
+		{
+		  /* Low amnt bits come from *p, then size bits
+		     from this_buffer[0] and the remaining again from
+		     *p.  */
+		  msk = ((1 << size) - 1) << amnt;
+		  *p = (*p & ~msk) | (this_buffer[0] & msk);
+		  size = 0;
+		}
+	      else if (amnt)
+		{
+		  msk = -1U << amnt;
+		  *p = (*p & ~msk) | (this_buffer[0] & msk);
+		  p++;
+		  size -= (BITS_PER_UNIT - amnt);
+		}
+	    }
+	  else
+	    {
+	      amnt = (unsigned HOST_WIDE_INT) pd.offset % BITS_PER_UNIT;
+	      if (amnt)
+		shift_bytes_in_array_left (this_buffer, len + 1, amnt);
+	    }
+	  memcpy (p, this_buffer + (amnt != 0), size / BITS_PER_UNIT);
+	  p += size / BITS_PER_UNIT;
+	  if (size % BITS_PER_UNIT)
+	    {
+	      unsigned int msk = -1U << (size % BITS_PER_UNIT);
+	      *p = (this_buffer[(amnt != 0) + size / BITS_PER_UNIT]
+		    & ~msk) | (*p & msk);
+	    }
+	}
     }
 
   tree type = vr->type;
@@ -1903,7 +2024,26 @@  vn_walk_cb_data::push_partial_def (const
      access size.  */
   if (INTEGRAL_TYPE_P (vr->type) && maxsizei != TYPE_PRECISION (vr->type))
     type = build_nonstandard_integer_type (maxsizei, TYPE_UNSIGNED (type));
-  tree val = native_interpret_expr (type, buffer, maxsizei / BITS_PER_UNIT);
+  tree val;
+  if (BYTES_BIG_ENDIAN)
+    {
+      unsigned sz = needed_len;
+      if (maxsizei % BITS_PER_UNIT)
+	shift_bytes_in_array_right (buffer, needed_len,
+				    BITS_PER_UNIT
+				    - (maxsizei % BITS_PER_UNIT));
+      if (INTEGRAL_TYPE_P (type))
+	sz = GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (type));
+      if (sz > needed_len)
+	{
+	  memcpy (this_buffer + (sz - needed_len), buffer, needed_len);
+	  val = native_interpret_expr (type, this_buffer, sz);
+	}
+      else
+	val = native_interpret_expr (type, buffer, needed_len);
+    }
+  else
+    val = native_interpret_expr (type, buffer, bufsize);
   /* If we chop off bits because the types precision doesn't match the memory
      access size this is ok when optimizing reads but not when called from
      the DSE code during elimination.  */
@@ -2478,8 +2618,7 @@  vn_reference_lookup_3 (ao_ref *ref, tree
 	  tree val;
 	  if (integer_zerop (gimple_call_arg (def_stmt, 1)))
 	    val = build_zero_cst (vr->type);
-	  else if (INTEGRAL_TYPE_P (vr->type)
-		   && known_eq (ref->size, 8))
+	  else if (INTEGRAL_TYPE_P (vr->type) && known_eq (ref->size, 8))
 	    {
 	      gimple_match_op res_op (gimple_match_cond::UNCOND, NOP_EXPR,
 				      vr->type, gimple_call_arg (def_stmt, 1));
@@ -2491,11 +2630,11 @@  vn_reference_lookup_3 (ao_ref *ref, tree
 	    }
 	  else
 	    {
-	      unsigned len = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (vr->type));
-	      unsigned char *buf = XALLOCAVEC (unsigned char, len);
+	      unsigned buflen = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (vr->type));
+	      unsigned char *buf = XALLOCAVEC (unsigned char, buflen);
 	      memset (buf, TREE_INT_CST_LOW (gimple_call_arg (def_stmt, 1)),
-		      len);
-	      val = native_interpret_expr (vr->type, buf, len);
+		      buflen);
+	      val = native_interpret_expr (vr->type, buf, buflen);
 	      if (!val)
 		return (void *)-1;
 	    }
@@ -2506,15 +2645,17 @@  vn_reference_lookup_3 (ao_ref *ref, tree
 	       && integer_zerop (gimple_call_arg (def_stmt, 1))
 	       && tree_fits_poly_int64_p (len)
 	       && tree_to_poly_int64 (len).is_constant (&leni)
+	       && leni <= INTTYPE_MAXIMUM (HOST_WIDE_INT) / BITS_PER_UNIT
 	       && offset.is_constant (&offseti)
 	       && offset2.is_constant (&offset2i)
 	       && maxsize.is_constant (&maxsizei)
-	       && ranges_known_overlap_p (offseti, maxsizei, offset2i, leni))
+	       && ranges_known_overlap_p (offseti, maxsizei, offset2i,
+					  leni << LOG2_BITS_PER_UNIT))
 	{
 	  pd_data pd;
 	  pd.rhs = build_constructor (NULL_TREE, NULL);
-	  pd.offset = (offset2i - offseti) / BITS_PER_UNIT;
-	  pd.size = leni;
+	  pd.offset = offset2i - offseti;
+	  pd.size = leni << LOG2_BITS_PER_UNIT;
 	  return data->push_partial_def (pd, 0, maxsizei);
 	}
     }
@@ -2558,13 +2699,9 @@  vn_reference_lookup_3 (ao_ref *ref, tree
 	    }
 	  else if (known_eq (ref->size, maxsize)
 		   && maxsize.is_constant (&maxsizei)
-		   && maxsizei % BITS_PER_UNIT == 0
 		   && offset.is_constant (&offseti)
-		   && offseti % BITS_PER_UNIT == 0
 		   && offset2.is_constant (&offset2i)
-		   && offset2i % BITS_PER_UNIT == 0
 		   && size2.is_constant (&size2i)
-		   && size2i % BITS_PER_UNIT == 0
 		   && ranges_known_overlap_p (offseti, maxsizei,
 					      offset2i, size2i))
 	    {
@@ -2573,8 +2710,8 @@  vn_reference_lookup_3 (ao_ref *ref, tree
 		 by a later def.  */
 	      pd_data pd;
 	      pd.rhs = gimple_assign_rhs1 (def_stmt);
-	      pd.offset = (offset2i - offseti) / BITS_PER_UNIT;
-	      pd.size = size2i / BITS_PER_UNIT;
+	      pd.offset = offset2i - offseti;
+	      pd.size = size2i;
 	      return data->push_partial_def (pd, get_alias_set (lhs), maxsizei);
 	    }
 	}
@@ -2719,19 +2856,15 @@  vn_reference_lookup_3 (ao_ref *ref, tree
 		}
 	    }
 	  else if (ranges_known_overlap_p (offseti, maxsizei, offset2i,
-					   size2i)
-		   && maxsizei % BITS_PER_UNIT == 0
-		   && offseti % BITS_PER_UNIT == 0
-		   && size2i % BITS_PER_UNIT == 0
-		   && offset2i % BITS_PER_UNIT == 0)
+					   size2i))
 	    {
 	      pd_data pd;
 	      tree rhs = gimple_assign_rhs1 (def_stmt);
 	      if (TREE_CODE (rhs) == SSA_NAME)
 		rhs = SSA_VAL (rhs);
 	      pd.rhs = rhs;
-	      pd.offset = (offset2i - offseti) / BITS_PER_UNIT;
-	      pd.size = size2i / BITS_PER_UNIT;
+	      pd.offset = offset2i - offseti;
+	      pd.size = size2i;
 	      return data->push_partial_def (pd, get_alias_set (lhs), maxsizei);
 	    }
 	}
@@ -2803,19 +2936,15 @@  vn_reference_lookup_3 (ao_ref *ref, tree
 		return data->finish (get_alias_set (lhs), val);
 	    }
 	  else if (maxsize.is_constant (&maxsizei)
-		   && maxsizei % BITS_PER_UNIT == 0
 		   && offset.is_constant (&offseti)
-		   && offseti % BITS_PER_UNIT == 0
 		   && offset2.is_constant (&offset2i)
-		   && offset2i % BITS_PER_UNIT == 0
 		   && size2.is_constant (&size2i)
-		   && size2i % BITS_PER_UNIT == 0
 		   && ranges_known_overlap_p (offset, maxsize, offset2, size2))
 	    {
 	      pd_data pd;
 	      pd.rhs = SSA_VAL (def_rhs);
-	      pd.offset = (offset2i - offseti) / BITS_PER_UNIT;
-	      pd.size = size2i / BITS_PER_UNIT;
+	      pd.offset = offset2i - offseti;
+	      pd.size = size2i;
 	      return data->push_partial_def (pd, get_alias_set (lhs), maxsizei);
 	    }
 	}
@@ -2945,14 +3074,14 @@  vn_reference_lookup_3 (ao_ref *ref, tree
 	     coming from targets that like to gimplify init-ctors as
 	     aggregate copies from constant data like aarch64 for
 	     PR83518.  */
-	  if (maxsize.is_constant (&maxsizei)
-	      && known_eq (ref->size, maxsize))
+	  if (maxsize.is_constant (&maxsizei) && known_eq (ref->size, maxsize))
 	    {
 	      pd_data pd;
 	      pd.rhs = val;
 	      pd.offset = 0;
-	      pd.size = maxsizei / BITS_PER_UNIT;
-	      return data->push_partial_def (pd, get_alias_set (lhs), maxsizei);
+	      pd.size = maxsizei;
+	      return data->push_partial_def (pd, get_alias_set (lhs),
+					     maxsizei);
 	    }
 	}
 
--- gcc/testsuite/gcc.dg/tree-ssa/pr93582-4.c.jj	2020-02-18 10:39:51.709597019 +0100
+++ gcc/testsuite/gcc.dg/tree-ssa/pr93582-4.c	2020-02-18 10:39:51.708597035 +0100
@@ -0,0 +1,23 @@ 
+/* PR tree-optimization/93582 */
+/* { dg-do compile { target int32 } } */
+/* { dg-options "-O2 -fdump-tree-fre1" } */
+/* { dg-final { scan-tree-dump "return -1991560811;" "fre1" { target le } } } */
+/* { dg-final { scan-tree-dump "return -733324916;" "fre1" { target be } } } */
+
+union U {
+  struct S { int a : 1, b : 4, c : 27; } s;
+  unsigned int i;
+};
+struct A { char a[24]; union U u; };
+void bar (struct A *);
+
+int
+foo (void)
+{
+  struct A a;
+  bar (&a);
+  a.u.s.a = -1;
+  a.u.s.b = -6;
+  a.u.s.c = -62236276;
+  return a.u.i;
+}
--- gcc/testsuite/gcc.dg/tree-ssa/pr93582-5.c.jj	2020-02-18 10:39:51.709597019 +0100
+++ gcc/testsuite/gcc.dg/tree-ssa/pr93582-5.c	2020-02-18 10:39:51.709597019 +0100
@@ -0,0 +1,25 @@ 
+/* PR tree-optimization/93582 */
+/* { dg-do compile { target int32 } } */
+/* { dg-options "-O2 -fdump-tree-fre1" } */
+/* { dg-final { scan-tree-dump "return -1462729318;" "fre1" { target le } } } */
+/* { dg-final { scan-tree-dump "return 1300568597;" "fre1" { target be } } } */
+
+union U {
+  struct S { int a : 1, b : 7, c : 8, d : 11, e : 5; } s;
+  unsigned int i;
+};
+struct A { char a[8]; union U u; };
+void bar (struct A *);
+
+int
+foo (void)
+{
+  struct A a;
+  bar (&a);
+  a.u.s.a = 0;
+  a.u.s.b = -51;
+  a.u.s.c = -123;
+  a.u.s.d = 208;
+  a.u.s.e = -11;
+  return a.u.i;
+}
--- gcc/testsuite/gcc.dg/tree-ssa/pr93582-6.c.jj	2020-02-18 10:39:51.709597019 +0100
+++ gcc/testsuite/gcc.dg/tree-ssa/pr93582-6.c	2020-02-18 10:39:51.709597019 +0100
@@ -0,0 +1,24 @@ 
+/* PR tree-optimization/93582 */
+/* { dg-do compile { target int32 } } */
+/* { dg-options "-O2 -fdump-tree-fre1" } */
+/* { dg-final { scan-tree-dump "return 890118;" "fre1" { target le } } } */
+/* { dg-final { scan-tree-dump "return 447899;" "fre1" { target be } } } */
+
+union U {
+  struct S { int a : 16, b : 5, c : 10, d : 1; } s;
+  struct T { int a : 8, b : 21, c : 3; } t;
+};
+struct A { char a[4]; union U u; };
+void bar (struct A *);
+
+int
+foo (void)
+{
+  struct A a;
+  bar (&a);
+  a.u.s.a = 1590;
+  a.u.s.b = -11;
+  a.u.s.c = 620;
+  a.u.s.d = -1;
+  return a.u.t.b;
+}
--- gcc/testsuite/gcc.dg/tree-ssa/pr93582-7.c.jj	2020-02-18 10:39:51.709597019 +0100
+++ gcc/testsuite/gcc.dg/tree-ssa/pr93582-7.c	2020-02-18 10:39:51.709597019 +0100
@@ -0,0 +1,24 @@ 
+/* PR tree-optimization/93582 */
+/* { dg-do compile { target int32 } } */
+/* { dg-options "-O2 -fdump-tree-fre1" } */
+/* { dg-final { scan-tree-dump "return -413012;" "fre1" { target le } } } */
+/* { dg-final { scan-tree-dump "return -611112;" "fre1" { target be } } } */
+
+union U {
+  struct S { int a : 12, b : 5, c : 10, d : 5; } s;
+  struct T { int a : 7, b : 21, c : 4; } t;
+};
+struct A { char a[48]; union U u; };
+void bar (struct A *);
+
+int
+foo (void)
+{
+  struct A a;
+  bar (&a);
+  a.u.s.a = 1590;
+  a.u.s.b = -11;
+  a.u.s.c = -404;
+  a.u.s.d = 7;
+  return a.u.t.b;
+}
--- gcc/testsuite/gcc.dg/tree-ssa/pr93582-8.c.jj	2020-02-15 00:40:16.234371422 +0100
+++ gcc/testsuite/gcc.dg/tree-ssa/pr93582-8.c	2020-02-18 16:06:31.002311978 +0100
@@ -0,0 +1,14 @@ 
+/* PR tree-optimization/93582 */
+/* { dg-do compile { target int32 } } */
+/* { dg-options "-O2 -fdump-tree-fre1" } */
+/* { dg-final { scan-tree-dump "return 0;" "fre1" { target le } } } */
+/* { dg-final { scan-tree-dump "return -8531;" "fre1" { target be } } } */
+
+short
+foo (void)
+{
+  union U { char c[32]; short s[16]; int i[8]; } u;
+  __builtin_memset (u.c + 1, '\0', 5);
+  u.s[3] = 0xdead;
+  return u.i[1];
+}