https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87076
Bug ID: 87076 Summary: -mpcu/-march not propagated through LTO bytecode (ice/segfault if arch flags do not match) Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: lto Assignee: unassigned at gcc dot gnu.org Reporter: vlad at ispras dot ru CC: marxin at gcc dot gnu.org Target Milestone: --- # run.sh: cat << EOF > 1.c typedef int i1 __attribute__((aligned(1))); int f(i1 *p) { return *p; } EOF # base=/usr/lib/gcc/arm-none-eabi/8.2.0/ case $1 in ice|"") $base/cc1 1.c -march=armv7-r -mthumb -flto arm-none-eabi-as 1.s -o 1.o # Next line yields a warning. Also note Tag_CPU_unaligned_access in 2.s $base/lto1 -munaligned-access -fverbose-asm 1.o -o 2.s ;; segfault) $base/cc1 1.c -mthumb -flto arm-none-eabi-as 1.s -o 1.o $base/lto1 -march=armv7-r 1.o ;; esac # end of run.sh FWIW, having -mcpu=cortex-r4 in place of -march=armv7-r in this script doesn't change anything. $ ./run.sh ice Looks like it has always given the warning: target CPU does not support unaligned accesses (I tested on gcc-{5,6,7,8,trunk}.) This is because -march=armv7-r (which would cause unaligned_access to be set) is not visible in lto1 -- it seems neither -march/-mcpu, nor Tag_CPU_unaligned_access is serialized. Also, since r231114 -- gcc-6 and above -- lto1 throws an ICE: 1.c: In function 'f': 1.c:5:1: internal compiler error: output_operand: invalid %-code } ^ 0x89b17a output_operand_lossage(char const*, ...) /mnt/co/gcc/gcc/final.c:3409 0x89bcdb output_asm_insn(char const*, rtx_def**) /mnt/co/gcc/gcc/final.c:3774 0x89a796 final_scan_insn(rtx_insn*, _IO_FILE*, int, int, int*) /mnt/co/gcc/gcc/final.c:3015 0x898a44 final(rtx_insn*, _IO_FILE*, int) /mnt/co/gcc/gcc/final.c:2045 0x89d237 rest_of_handle_final /mnt/co/gcc/gcc/final.c:4441 0x89d436 execute /mnt/co/gcc/gcc/final.c:4516 Probably because this - if (unaligned_access) - builtin_define ("__ARM_FEATURE_UNALIGNED"); + def_or_undef_macro (pfile, "__ARM_FEATURE_UNALIGNED", unaligned_access); changed the semantics: it used to only define, now it also undefs the macro. But it only made the underlying problem surface. $ ./run.sh segfault segfaults with gcc-8 and trunk: In function 'f': lto1: internal compiler error: Segmentation fault 0xec8f1c crash_signal /mnt/co/gcc/gcc/toplev.c:325 0x1aa3dca arm_parse_arch_option_name(arch_option const*, char const*, char const*, bool) /mnt/co/gcc/gcc/common/config/arm/arm-common.c:394 0x133e85c arm_configure_build_target(arm_build_target*, cl_target_option*, gcc_options*, bool) /mnt/co/gcc/gcc/config/arm/arm.c:3123 0x133e3dd arm_option_restore /mnt/co/gcc/gcc/config/arm/arm.c:2989 0xd7328e cl_target_option_restore(gcc_options*, cl_target_option*) /mnt/bld/gcc-trunk-arm/gcc-gomp-host/gcc/options-save.c:3749 0x138ddec arm_set_current_function /mnt/co/gcc/gcc/config/arm/arm.c:30609 0xaa339d invoke_set_current_function_hook /mnt/co/gcc/gcc/function.c:4616 0xaa36d1 allocate_struct_function(tree_node*, bool) /mnt/co/gcc/gcc/function.c:4729 0xaa39d8 push_struct_function(tree_node*) /mnt/co/gcc/gcc/function.c:4792 0xccbbbd input_function /mnt/co/gcc/gcc/lto-streamer-in.c:1065 0xccc668 lto_read_body_or_constructor /mnt/co/gcc/gcc/lto-streamer-in.c:1295 0xccc97c lto_input_function_body(lto_file_decl_data*, cgraph_node*, char const*) /mnt/co/gcc/gcc/lto-streamer-in.c:1343 0x8d1084 cgraph_node::get_untransformed_body() /mnt/co/gcc/gcc/cgraph.c:3548 0x8de11b cgraph_node::expand() /mnt/co/gcc/gcc/cgraphunit.c:2091 0x8ded39 output_in_order /mnt/co/gcc/gcc/cgraphunit.c:2365 0x8df479 symbol_table::compile() /mnt/co/gcc/gcc/cgraphunit.c:2609 0x7ee5d3 lto_main() /mnt/co/gcc/gcc/lto/lto.c:3428 Of course, none of this happens if the user specifies same arch flags for lto1 as they did for cc1. But my understanding is that a. the compiler should not segfault; b. it could store this information in the bytecode as it does for other function attributes. And it probably should: consider what happens if we specify __attribute__ ((__target__ ("arch=armv7-r"))) for f [for some reason, this feature doesn't work for me without LTO either, but that's a separate issue], or what happens if different TUs were compiled with different -march's; c. from the usability standpoint, this would allow the lazy user to forget to specify the flags for LTO link and still have the correct ones deduced for them.