Bug 100216

Summary: arm: UB in arm_canonicalize_comparison (shift exponent 127 is too large for 64-bit type)
Product: gcc Reporter: Alex Coplan <acoplan>
Component: targetAssignee: Not yet assigned to anyone <unassigned>
Status: NEW ---    
Severity: normal CC: clyon
Priority: P3    
Version: 11.0   
Target Milestone: ---   
Host: Target: arm
Build: Known to work:
Known to fail: 11.0 Last reconfirmed: 2021-04-23 00:00:00
Bug Depends on:    
Bug Blocks: 63426    

Description Alex Coplan 2021-04-22 17:54:24 UTC
The following fails:

$ cat test.c
int *a, *b;
void c() {
  int d;
  for (; d; d++)
    b = a[d] ? b : a;
}
$ gcc/xgcc -B gcc test.c -c -march=armv8-a+simd -mfloat-abi=hard -O3
/data_sdb/toolchain/src/gcc/gcc/config/arm/arm.c:5532:30: runtime error: shift exponent 127 is too large for 64-bit type 'long unsigned int'
    #0 0x2369893 in arm_canonicalize_comparison(int*, rtx_def**, rtx_def**, bool) (/data_sdb/toolchain/cc1s/ubsan-arm/gcc/cc1+0x2369893)
    #1 0x3137b28 in target_canonicalize_comparison(rtx_code*, rtx_def**, rtx_def**, bool) (/data_sdb/toolchain/cc1s/ubsan-arm/gcc/cc1+0x3137b28)
    #2 0x3198fe1 in simplify_comparison(rtx_code, rtx_def**, rtx_def**) (/data_sdb/toolchain/cc1s/ubsan-arm/gcc/cc1+0x3198fe1)
    #3 0x31601ed in combine_simplify_rtx(rtx_def*, machine_mode, int, int) (/data_sdb/toolchain/cc1s/ubsan-arm/gcc/cc1+0x31601ed)
    #4 0x315a3fa in subst(rtx_def*, rtx_def*, rtx_def*, int, int, int) (/data_sdb/toolchain/cc1s/ubsan-arm/gcc/cc1+0x315a3fa)
    #5 0x3159d87 in subst(rtx_def*, rtx_def*, rtx_def*, int, int, int) (/data_sdb/toolchain/cc1s/ubsan-arm/gcc/cc1+0x3159d87)
    #6 0x3159d87 in subst(rtx_def*, rtx_def*, rtx_def*, int, int, int) (/data_sdb/toolchain/cc1s/ubsan-arm/gcc/cc1+0x3159d87)
    #7 0x31489f9 in try_combine(rtx_insn*, rtx_insn*, rtx_insn*, rtx_insn*, int*, rtx_insn*) (/data_sdb/toolchain/cc1s/ubsan-arm/gcc/cc1+0x31489f9)
    #8 0x313c027 in combine_instructions(rtx_insn*, unsigned int) (/data_sdb/toolchain/cc1s/ubsan-arm/gcc/cc1+0x313c027)
    #9 0x31a440c in rest_of_handle_combine() (/data_sdb/toolchain/cc1s/ubsan-arm/gcc/cc1+0x31a440c)
    #10 0x31a453c in (anonymous namespace)::pass_combine::execute(function*) (/data_sdb/toolchain/cc1s/ubsan-arm/gcc/cc1+0x31a453c)
    #11 0x17d2355 in execute_one_pass(opt_pass*) (/data_sdb/toolchain/cc1s/ubsan-arm/gcc/cc1+0x17d2355)
    #12 0x17d2b6e in execute_pass_list_1(opt_pass*) (/data_sdb/toolchain/cc1s/ubsan-arm/gcc/cc1+0x17d2b6e)
    #13 0x17d2be5 in execute_pass_list_1(opt_pass*) (/data_sdb/toolchain/cc1s/ubsan-arm/gcc/cc1+0x17d2be5)
    #14 0x17d2c65 in execute_pass_list(function*, opt_pass*) (/data_sdb/toolchain/cc1s/ubsan-arm/gcc/cc1+0x17d2c65)
    #15 0xdf27ac in cgraph_node::expand() (/data_sdb/toolchain/cc1s/ubsan-arm/gcc/cc1+0xdf27ac)
    #16 0xdf370f in expand_all_functions() (/data_sdb/toolchain/cc1s/ubsan-arm/gcc/cc1+0xdf370f)
    #17 0xdf4e10 in symbol_table::compile() (/data_sdb/toolchain/cc1s/ubsan-arm/gcc/cc1+0xdf4e10)
    #18 0xdf55ea in symbol_table::finalize_compilation_unit() (/data_sdb/toolchain/cc1s/ubsan-arm/gcc/cc1+0xdf55ea)
    #19 0x1ac3baa in compile_file() (/data_sdb/toolchain/cc1s/ubsan-arm/gcc/cc1+0x1ac3baa)
    #20 0x1ac8a15 in do_compile() (/data_sdb/toolchain/cc1s/ubsan-arm/gcc/cc1+0x1ac8a15)
    #21 0x1ac8f10 in toplev::main(int, char**) (/data_sdb/toolchain/cc1s/ubsan-arm/gcc/cc1+0x1ac8f10)
    #22 0x36a5ee7 in main (/data_sdb/toolchain/cc1s/ubsan-arm/gcc/cc1+0x36a5ee7)
    #23 0x7ffff5ca1bf6 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6)
    #24 0x980249 in _start (/data_sdb/toolchain/cc1s/ubsan-arm/gcc/cc1+0x980249)
Comment 1 Alex Coplan 2021-04-22 17:55:12 UTC
GCC built with UBSan here, to be clear.
Comment 2 Richard Earnshaw 2021-04-23 09:36:53 UTC
Confirmed by visual inspection.  Clearly this code was written at a time when the largest integral mode on Arm was DImode.  It won't work for wider modes and it won't do anything for non-integral modes.

Needs an overhaul.