https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97295
--- Comment #3 from Sergei Trofimovich <slyfox at gcc dot gnu.org> --- Poking at the crash to get clues: """ (gdb) bt #0 internal_error (gmsgid=0x285ac9f "in %s, at %s:%d") at ../../gcc-10/gcc/diagnostic.c:1706 #1 0x0000000001f7c34a in fancy_abort (file=0x20c3e90 "../../gcc-10/gcc/profile-count.c", line=273, function=0x20c3e81 "to_frequency") at ../../gcc-10/gcc/diagnostic.c:1778 #2 0x0000000000f0563a in profile_count::to_frequency (this=0x7ffff759b190, fun=0x7ffff7585000) at ../../gcc-10/gcc/profile-count.c:273 #3 0x0000000000f3b5a4 in regstat_bb_compute_ri (bb=0x7ffff759b138, live=0x2ee0c20) at ../../gcc-10/gcc/regstat.c:200 #4 0x0000000000f3b9df in regstat_compute_ri () at ../../gcc-10/gcc/regstat.c:253 #5 0x0000000000d23399 in ira (f=0x0) at ../../gcc-10/gcc/ira.c:5294 #6 0x0000000000d23d95 in (anonymous namespace)::pass_ira::execute (this=0x2ddb750) at ../../gcc-10/gcc/ira.c:5666 #7 0x0000000000ec631d in execute_one_pass (pass=0x2ddb750) at ../../gcc-10/gcc/passes.c:2502 #8 0x0000000000ec6655 in execute_pass_list_1 (pass=0x2ddb750) at ../../gcc-10/gcc/passes.c:2590 #9 0x0000000000ec6686 in execute_pass_list_1 (pass=0x2dda4d0) at ../../gcc-10/gcc/passes.c:2591 #10 0x0000000000ec66df in execute_pass_list (fn=0x7ffff7585000, pass=0x2dd6790) at ../../gcc-10/gcc/passes.c:2601 #11 0x00000000009c5de3 in cgraph_node::expand (this=0x7ffff758e2d0) at ../../gcc-10/gcc/cgraphunit.c:2300 #12 0x00000000009c682d in output_in_order () at ../../gcc-10/gcc/cgraphunit.c:2578 #13 0x00000000009c6e6d in symbol_table::compile (this=0x7ffff773e100) at ../../gcc-10/gcc/cgraphunit.c:2819 #14 0x00000000008c41e7 in lto_main () at ../../gcc-10/gcc/lto/lto.c:653 #15 0x00000000010222ab in compile_file () at ../../gcc-10/gcc/toplev.c:458 #16 0x00000000010254cd in do_compile () at ../../gcc-10/gcc/toplev.c:2278 #17 0x00000000010257d8 in toplev::main (this=0x7fffffffd526, argc=21, argv=0x2db0700) at ../../gcc-10/gcc/toplev.c:2417 #18 0x0000000001f4b529 in main (argc=21, argv=0x7fffffffd638) at ../../gcc-10/gcc/main.c:39 """ """ (gdb) fr 2 #2 0x0000000000f0563a in profile_count::to_frequency (this=0x7ffff759b190, fun=0x7ffff7585000) at ../../gcc-10/gcc/profile-count.c:273 273 gcc_assert (REG_BR_PROB_BASE == BB_FREQ_MAX (gdb) call print_generic_decl(stderr, fun->decl, 0) static long unsigned int BitwiseCast (double); (gdb) call debug_gimple_stmt(fun->gimple_body) # .MEM_6 = VDEF <.MEM_5(D)> BitwiseCast (aFrom_2(D), &temp); """ """ $ lto-dump -dump-body=BitwiseCast Unified_cpp_mfbt0.o Gimple Body of Function: BitwiseCast BitwiseCast (const double aFrom) { <bb 2> [count: 1509]: _3 = VIEW_CONVERT_EXPR<long unsigned int>(aFrom_2(D)); return _3; } $ lto-dump -dump-body=BitwiseCast TestFloatingPoint.o ... Gimple Body of Function: BitwiseCast BitwiseCast (const double aFrom) { long unsigned int temp; long unsigned int D.4528; <bb 2> : BitwiseCast (aFrom_2(D), &temp); _4 = temp; temp ={v} {CLOBBER}; <bb 3> : <L0>: return _4; } Gimple Body of Function: BitwiseCast BitwiseCast (const double aFrom, long unsigned int * aResult) { long unsigned int D.4534; <bb 2> : _2 = MEM <long unsigned int> [(char * {ref-all})&aFrom]; MEM <long unsigned int> [(char * {ref-all})aResult_3(D)] = _2; return; } ... """ Source definition of the template: """ // from firefox-81.0.1/mfbt/Casting.h template <typename To, typename From> inline void BitwiseCast(const From aFrom, To* aResult) { static_assert(sizeof(From) == sizeof(To), "To and From must have the same size"); // We could maybe downgrade these to std::is_trivially_copyable, but the // various STLs we use don't all provide it. static_assert(std::is_trivial<From>::value, "shouldn't bitwise-copy a type having non-trivial " "initialization"); static_assert(std::is_trivial<To>::value, "shouldn't bitwise-copy a type having non-trivial " "initialization"); std::memcpy(static_cast<void*>(aResult), static_cast<const void*>(&aFrom), sizeof(From)); } """ My interpretation of the above: under some circumstances (different profile data?) gcc generates two variants of specialised form of BitwiseCast<double,unsigned long>: 1. VIEW_CONVERT_EXPR form 2. and 'call BitwiseCast (const double aFrom, long unsigned int * aResult)' form Once LTO merges both definitions somehow one of them becomes unreachable for initial part of register allocator (initial analysis?) but not later phase (actual register allocation?). And assertion fails.