diff mbox

[ARM] Fix PR target/64460: Set 'shift' attr properly on some patterns

Message ID 54B3DA2E.3000209@arm.com
State New
Headers show

Commit Message

Kyrylo Tkachov Jan. 12, 2015, 2:29 p.m. UTC
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.tkachov@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.tkachov@arm.com>
>
>       PR target/64460
>       * gcc.target/arm/pr64460_1.c: New test.
>
>

Comments

Ramana Radhakrishnan Jan. 14, 2015, 9:54 a.m. UTC | #1
On Mon, Jan 12, 2015 at 2:29 PM, Kyrill Tkachov <kyrylo.tkachov@arm.com> wrote:
> 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.tkachov@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.tkachov@arm.com>
>>
>>       PR target/64460
>>       * gcc.target/arm/pr64460_1.c: New test.
>>
>>
>

OK.

Thanks,
Ramana
diff mbox

Patch

commit c89087db2f16eda521d6c938d342570c1d69a7a2
Author: Kyrylo Tkachov <kyrylo.tkachov@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 {
+		}
+	}
+}