Now with patch attached Kyrill
On 12/01/15 14:27, Kyrill Tkachov wrote:
Hi all, In this PR we ICE when compiling with -mtune=xscale. The ICE is a segfault in xscale_sched_adjust_cost. The root cause is that xscale_sched_adjust_cost uses the value of the 'shift' insn attribute to index the recog operands. In GCC 5 the form and number of operands in those patterns were updated but the shift value was not: Author: rearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Thu May 29 09:39:07 2014 +0000 * arm/iterators.md (shiftable_ops): New code iterator. (t2_binop0, arith_shift_insn): New code attributes. * arm/predicates.md (shift_nomul_operator): New predicate. * arm/arm.md (insn_enabled): Delete. (enabled): Remove insn_enabled test. (*arith_shiftsi): Delete. Replace with ... (*<arith_shift_insn>_multsi): ... new pattern. (*<arith_shift_insn>_shiftsi): ... new pattern. * config/arm/arm.c (arm_print_operand): Handle operand format 'b'. This led to an out-of-bounds array access. Only xscale_sched_adjust_cost uses the shift attribute, so the segfault only happens for xscale tuning. In the future we might want to use a more general pattern-matching approach to find the shifted operand in an rtx... In any case, this patch fixes the value of 'shift' for the offending pattern and also updates 'shift' for the *<arith_shift_insn>_shiftsi pattern to point to the correct operand that is being shifted. Tested arm-none-eabi and bootstrapped with -mtune=xscale in BOOT_CFLAGS. Ok for trunk? Thanks, Kyrill 2014-01-12 Kyrylo Tkachov <kyrylo.tkac...@arm.com> PR target/64460 * config/arm/arm.md (*<arith_shift_insn>_multsi): Set 'shift' attr to 2. (*<arith_shift_insn>_shiftsi): Set 'shift' attr to 3. 2014-01-12 Kyrylo Tkachov <kyrylo.tkac...@arm.com> PR target/64460 * gcc.target/arm/pr64460_1.c: New test.
commit c89087db2f16eda521d6c938d342570c1d69a7a2 Author: Kyrylo Tkachov <kyrylo.tkac...@arm.com> Date: Fri Jan 9 16:41:44 2015 +0000 [ARM] PR target/64460 ICE with -mtune=xscale in shift attr diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index c61057f..bbefb93 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -8255,36 +8255,36 @@ (define_insn "trap" (define_insn "*<arith_shift_insn>_multsi" [(set (match_operand:SI 0 "s_register_operand" "=r,r") (shiftable_ops:SI (mult:SI (match_operand:SI 2 "s_register_operand" "r,r") (match_operand:SI 3 "power_of_two_operand" "")) (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))] "TARGET_32BIT" "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3" [(set_attr "predicable" "yes") (set_attr "predicable_short_it" "no") - (set_attr "shift" "4") + (set_attr "shift" "2") (set_attr "arch" "a,t2") (set_attr "type" "alu_shift_imm")]) (define_insn "*<arith_shift_insn>_shiftsi" [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") (shiftable_ops:SI (match_operator:SI 2 "shift_nomul_operator" [(match_operand:SI 3 "s_register_operand" "r,r,r") (match_operand:SI 4 "shift_amount_operand" "M,M,r")]) (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))] "TARGET_32BIT && GET_CODE (operands[2]) != MULT" "<arith_shift_insn>%?\\t%0, %1, %3%S2" [(set_attr "predicable" "yes") (set_attr "predicable_short_it" "no") - (set_attr "shift" "4") + (set_attr "shift" "3") (set_attr "arch" "a,t2,a") (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")]) (define_split [(set (match_operand:SI 0 "s_register_operand" "") (match_operator:SI 1 "shiftable_operator" [(match_operator:SI 2 "shiftable_operator" [(match_operator:SI 3 "shift_operator" [(match_operand:SI 4 "s_register_operand" "") (match_operand:SI 5 "reg_or_int_operand" "")]) diff --git a/gcc/testsuite/gcc.target/arm/pr64460_1.c b/gcc/testsuite/gcc.target/arm/pr64460_1.c new file mode 100644 index 0000000..ee6ad4a --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr64460_1.c @@ -0,0 +1,69 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=xscale" } */ + +typedef unsigned int size_t; +typedef short unsigned int __uint16_t; +typedef long unsigned int __uint32_t; +typedef unsigned int __uintptr_t; +typedef __uint16_t uint16_t ; +typedef __uint32_t uint32_t ; +typedef __uintptr_t uintptr_t; +typedef uint32_t Objects_Id; +typedef uint16_t Objects_Maximum; +typedef struct { } Objects_Control; + +static __inline__ void *_Addresses_Align_up (void *address, size_t alignment) +{ + uintptr_t mask = alignment - (uintptr_t)1; + return (void*)(((uintptr_t)address + mask) & ~mask); +} + +typedef struct { + Objects_Id minimum_id; + Objects_Maximum maximum; + _Bool + auto_extend; + Objects_Maximum allocation_size; + void **object_blocks; +} Objects_Information; + +extern uint32_t _Objects_Get_index (Objects_Id); +extern void** _Workspace_Allocate (size_t); + +void _Objects_Extend_information (Objects_Information *information) +{ + uint32_t block_count; + uint32_t minimum_index; + uint32_t maximum; + size_t block_size; + _Bool + do_extend = + minimum_index = _Objects_Get_index( information->minimum_id ); + if ( information->object_blocks == + ((void *)0) + ) + block_count = 0; + else { + block_count = information->maximum / information->allocation_size; + } + if ( do_extend ) { + void **object_blocks; + uintptr_t object_blocks_size; + uintptr_t inactive_per_block_size; + object_blocks_size = (uintptr_t)_Addresses_Align_up( + (void*)(block_count * sizeof(void*)), + 8 + ); + inactive_per_block_size = + (uintptr_t)_Addresses_Align_up( + (void*)(block_count * sizeof(uint32_t)), + 8 + ); + block_size = object_blocks_size + inactive_per_block_size + + ((maximum + minimum_index) * sizeof(Objects_Control *)); + if ( information->auto_extend ) { + object_blocks = _Workspace_Allocate( block_size ); + } else { + } + } +}