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.

Reply via email to