This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix wrong code with autoinc/autodec


This problem is responsible for the following ACATS regressions on IA-64:

FAIL:   cxf3a01
FAIL:   cxf3a02
FAIL:   cxf3a03
FAIL:   cxf3a04
FAIL:   cxf3a06
FAIL:   cxf3a07
FAIL:   cxf3a08

It's a reload issue.  We start with:

(insn 1066 1091 1096 4 fxf3a00.ads:88 (set (mem/s/f/j:DI (post_inc:DI 
(reg/f:DI 1062)) [14 <variable>.P_ARRAY+0 S8 A128])
        (reg/f:DI 566)) 5 {movdi_internal} (expr_list:REG_DEAD (reg/f:DI 566)
        (expr_list:REG_INC (reg/f:DI 1062)
            (nil))))

Then caller-save adds a new insn right before:

(insn 3852 1091 1066 4 (set (reg:DI 126 out6)
        (mem/c:DI (plus:DI (reg/f:DI 328 sfp)
                (const_int 192 [0xc0])) [137 S8 A64])) -1 (nil))

(insn 1066 1091 1096 4 fxf3a00.ads:88 (set (mem/s/f/j:DI (post_inc:DI 
(reg/f:DI 11 r11 [1062])) [14 <variable>.P_ARRAY+0 S8 A128])
        (reg/f:DI 126 out6 [566])) 5 {movdi_internal} (expr_list:REG_DEAD 
(reg/f:DI 126 out6 [566])
        (expr_list:REG_INC (reg/f:DI 11 r11 [1062])
            (nil))))

Then a reload is called for insn 3852:

Reloads for insn # 3852
Reload 0: reload_in (DI) = (plus:DI (reg/f:DI 12 r12)
                                                    (const_int 208 [0xd0]))
	GR_REGS, RELOAD_FOR_OPERAND_ADDRESS (opnum = 1), can't combine
	reload_in_reg: (plus:DI (reg/f:DI 12 r12)
                                                    (const_int 208 [0xd0]))
	reload_reg_rtx: (reg:DI 11 r11)

The problem is that the reload register r11 is live as it's used in insn 1066.


It's a variant of
  http://gcc.gnu.org/ml/gcc-patches/2007-11/msg00838.html

When the new insn 3852 is added in insert_one_insn, we have for its associated 
reload chain:

(gdb) p debug_regset(chain->live_throughout)
 560 561 564 568 569 571 573 577 579 581 582 583 584 586 590 592 596 597 603 
608 614 620 621 625 627 633 639 641 642 644 646 650 652 655 656 657 661 663 
664 667 668 672 674 678 679 683 685 686 690 696 701 707 712 718 723 729 734 
740 745 749 751 753 755 756 762 767 773 778 784 789 795 800 806 811 815 817 
824 830 832 837 843 849 850 856 863 869 877 883 891 897 899 905 911 919 925 
932 933 939 947 953 955 960 966 973 979 987 993 1001 1007 1015 1021 1031 1037 
1045 1048 1051 1052 1058 1065 1069 1072 1076 1079 1335 1366 1529 1540 1548 
1555 1571 1628 1767 1773 1970 1971 1972 1973 1974 1996 1998 2022 2089 2116 
2117 2166 2211 2556
$59 = void
(gdb) p debug_regset(chain->dead_or_set)
 1062

but, as already pointed out in the linked to discussion, dead_or_set is 
disregarded in insert_one_insn and only notes are used to compute the new 
live_throughout.

Minimally fixed in the same spirit by scanning REG_INC notes as well.

Tested on ia64-suse-linux, applied on the mainline.


2008-11-21 ?Eric Botcazou ?<ebotcazou@adacore.com>

	* caller-save.c (insert_one_insn): Take into account REG_INC notes
	for the liveness computation of the new insn.


-- 
Eric Botcazou
Index: caller-save.c
===================================================================
--- caller-save.c	(revision 141915)
+++ caller-save.c	(working copy)
@@ -1216,10 +1216,12 @@ insert_one_insn (struct insn_chain *chai
       /* ??? It would be nice if we could exclude the already / still saved
 	 registers from the live sets.  */
       COPY_REG_SET (&new_chain->live_throughout, &chain->live_throughout);
-      /* Registers that die in CHAIN->INSN still live in the new insn.  */
+      /* Registers that die in CHAIN->INSN still live in the new insn.
+	 Likewise for those which are autoincremented or autodecremented.  */
       for (link = REG_NOTES (chain->insn); link; link = XEXP (link, 1))
 	{
-	  if (REG_NOTE_KIND (link) == REG_DEAD)
+	  enum reg_note kind = REG_NOTE_KIND (link);
+	  if (kind == REG_DEAD || kind == REG_INC)
 	    {
 	      rtx reg = XEXP (link, 0);
 	      int regno, i;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]