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]

[csl-arm] Arm tls ICE


The Arm tls patterns use match_dup in a define_insn. This results in 
unrecognisable insns if the web pass modifies the set destination.

The attached patch changes these patterns to use a separate match_operand, 
with a "0" constraint in the thumb case.

It also cleans up similar match_operand/match_dup weirdness in the related 
peephole2, and makes the thumb-2 RTL reflect the actual insn semantics.

Tested with cross to arm-linux-gnueabi.
Applied to csl-arm-branch.

Dan: It looks like your TLS patch for mainline may be effected by this.

Paul
2005-10-22 Paul Brook  <paul@codesourcery.com>

gcc/
	* config/arm/arm.c (arm_load_pic_register): Pass extra reg to
	gen_pic_add_dot_plus_*. Handle Thumb-2.
	* config/arm/arm.md (pic_add_dot_plus_four): Use match_operand instead
	of match_dup.
	(pic_add_dot_plus_eight): Ditto.
	Remove constraints from peephole2.  Use match_dup in output template.
	* config/arm/thumb2.md (pic_load_dot_plus_four): Use match_operand
	instead of match_dup.
gcc/testsuite/
	* gcc.dg/tls/opt-10.c: New test.

Index: gcc/config/arm/arm.c
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/config/arm/arm.c,v
retrieving revision 1.303.2.97
diff -u -p -r1.303.2.97 arm.c
--- gcc/config/arm/arm.c	21 Oct 2005 14:24:51 -0000	1.303.2.97
+++ gcc/config/arm/arm.c	22 Oct 2005 21:59:27 -0000
@@ -3372,7 +3372,8 @@ arm_load_pic_register (unsigned int scra
   if (TARGET_ARM)
     {
       emit_insn (gen_pic_load_addr_arm (pic_offset_table_rtx, pic_rtx));
-      emit_insn (gen_pic_add_dot_plus_eight (pic_offset_table_rtx, l1));
+      emit_insn (gen_pic_add_dot_plus_eight (pic_offset_table_rtx,
+					     pic_offset_table_rtx, l1));
     }
   else if (TARGET_THUMB2)
     {
@@ -3396,7 +3397,8 @@ arm_load_pic_register (unsigned int scra
 	}
       else
 	emit_insn (gen_pic_load_addr_thumb1 (pic_offset_table_rtx, pic_rtx));
-      emit_insn (gen_pic_add_dot_plus_four (pic_offset_table_rtx, l1));
+      emit_insn (gen_pic_add_dot_plus_four (pic_offset_table_rtx,
+					    pic_offset_table_rtx, l1));
     }
 
   /* Need to emit this whether or not we obey regdecls,
@@ -3999,9 +4001,17 @@ legitimize_tls_address (rtx x, unsigned 
       reg = load_tls_operand (sum, reg);
 
       if (TARGET_ARM)
-	insn = emit_insn (gen_pic_add_dot_plus_eight (reg, label));
+	insn = emit_insn (gen_pic_add_dot_plus_eight (reg, reg, label));
+      else if (TARGET_THUMB2)
+	{
+	  /* Thumb-2 only allows very limited access to the PC.  Calculate the
+	     address in a temporary reggister.  */
+	  tmp = gen_reg_rtx (SImode);
+	  insn = emit_insn (gen_pic_load_dot_plus_four (tmp, label));
+	  emit_insn (gen_addsi3(reg, reg, tmp));
+	}
       else
-	insn = emit_insn (gen_pic_add_dot_plus_four (reg, label));
+	insn = emit_insn (gen_pic_add_dot_plus_four (reg, reg, label));
 
       emit_label_before (dummy_label, insn);
 
Index: gcc/config/arm/arm.md
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/config/arm/arm.md,v
retrieving revision 1.145.2.39
diff -u -p -r1.145.2.39 arm.md
--- gcc/config/arm/arm.md	5 Oct 2005 15:25:17 -0000	1.145.2.39
+++ gcc/config/arm/arm.md	22 Oct 2005 19:41:57 -0000
@@ -4455,11 +4455,11 @@
 )
 
 (define_insn "pic_add_dot_plus_four"
-  [(set (match_operand:SI 0 "register_operand" "+r")
-	(unspec:SI [(plus:SI (match_dup 0)
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec:SI [(plus:SI (match_operand:SI 1 "register_operand" "0")
 			     (const (plus:SI (pc) (const_int 4))))]
 		   UNSPEC_PIC_BASE))
-   (use (label_ref (match_operand 1 "" "")))]
+   (use (label_ref (match_operand 2 "" "")))]
   "TARGET_THUMB1"
   "*
   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
@@ -4470,16 +4470,16 @@
 )
 
 (define_insn "pic_add_dot_plus_eight"
-  [(set (match_operand:SI 0 "register_operand" "+r")
-	(unspec:SI [(plus:SI (match_dup 0)
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec:SI [(plus:SI (match_operand:SI 1 "register_operand" "r")
 			     (const (plus:SI (pc) (const_int 8))))]
 		   UNSPEC_PIC_BASE))
-   (use (label_ref (match_operand 1 "" "")))]
+   (use (label_ref (match_operand 2 "" "")))]
   "TARGET_ARM"
   "*
     (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
-			       CODE_LABEL_NUMBER (operands[1]));
-    return \"add%?\\t%0, %|pc, %0\";
+			       CODE_LABEL_NUMBER (operands[2]));
+    return \"add%?\\t%0, %|pc, %1\";
   "
   [(set_attr "predicable" "yes")]
 )
@@ -4522,34 +4522,34 @@
 ;; tls_load_dot_plus_x by a peephole.
 
 (define_peephole2
-  [(parallel [(set (match_operand:SI 0 "register_operand" "+r")
-		   (unspec:SI [(plus:SI (match_dup 0)
+  [(parallel [(set (match_operand:SI 0 "register_operand" "")
+		   (unspec:SI [(plus:SI (match_operand:SI 3 "register_operand" "")
 			     	 	(const (plus:SI (pc) (const_int 8))))]
 		      UNSPEC_PIC_BASE))
    	      (use (label_ref (match_operand 1 "" "")))])
-   (set (match_operand:SI 2 "register_operand" "+r") (mem:SI (match_dup 0)))]
+   (set (match_operand:SI 2 "register_operand" "") (mem:SI (match_dup 0)))]
   "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
-  [(parallel [(set (match_operand:SI 2 "register_operand" "+r")
-			(mem:SI (unspec:SI [(plus:SI (match_dup 0)
+  [(parallel [(set (match_dup 2)
+			(mem:SI (unspec:SI [(plus:SI (match_dup 3)
 			     			     (const (plus:SI (pc) (const_int 8))))]
 		   		 UNSPEC_PIC_BASE)))	
-   	      (use (label_ref (match_operand 1 "" "")))])]
+   	      (use (label_ref (match_dup 1)))])]
   ""
 )
 
 (define_peephole2
-  [(parallel [(set (match_operand:SI 0 "register_operand" "+r")
+  [(parallel [(set (match_operand:SI 0 "register_operand" "")
 		   (unspec:SI [(plus:SI (match_dup 0)
 			     	 	(const (plus:SI (pc) (const_int 4))))]
 		      UNSPEC_PIC_BASE))
    	      (use (label_ref (match_operand 1 "" "")))])
-   (set (match_operand:SI 2 "register_operand" "+r") (mem:SI (match_dup 0)))]
+   (set (match_operand:SI 2 "register_operand" "") (mem:SI (match_dup 0)))]
   "TARGET_THUMB && peep2_reg_dead_p (2, operands[0])"
-  [(parallel [(set (match_operand:SI 2 "register_operand" "+r")
+  [(parallel [(set (match_dup 2)
 			(mem:SI (unspec:SI [(plus:SI (match_dup 0)
 			     			     (const (plus:SI (pc) (const_int 4))))]
 		   		 UNSPEC_PIC_BASE)))	
-   	      (use (label_ref (match_operand 1 "" "")))])]
+   	      (use (label_ref (match_dup 1)))])]
   ""
 )
 
Index: gcc/config/arm/thumb2.md
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/config/arm/Attic/thumb2.md,v
retrieving revision 1.1.2.2
diff -u -p -r1.1.2.2 thumb2.md
--- gcc/config/arm/thumb2.md	1 Sep 2005 16:51:13 -0000	1.1.2.2
+++ gcc/config/arm/thumb2.md	22 Oct 2005 21:51:56 -0000
@@ -274,9 +274,8 @@
 ;; bits of the PC are always read as zero, so ensure the instructions is
 ;; word aligned.
 (define_insn "pic_load_dot_plus_four"
-  [(set (match_operand:SI 0 "register_operand" "+r")
-	(unspec:SI [(plus:SI (match_dup 0)
-			     (const (plus:SI (pc) (const_int 4))))]
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec:SI [(const (plus:SI (pc) (const_int 4)))]
 		   UNSPEC_PIC_BASE))
    (use (label_ref (match_operand 1 "" "")))]
   "TARGET_THUMB2"
Index: gcc/testsuite/gcc.dg/tls/opt-10.c
===================================================================
RCS file: gcc/testsuite/gcc.dg/tls/opt-10.c
diff -N gcc/testsuite/gcc.dg/tls/opt-10.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/gcc.dg/tls/opt-10.c	22 Oct 2005 22:11:47 -0000
@@ -0,0 +1,13 @@
+/* { dg-do compile */
+/* { dg-options "-O3 -fpic" } */
+/* The web pass was creating unrecognisable pic_load_dot_plus_four insns.  */
+__thread int a_thread_local;
+void *
+spin (int n)
+{
+  int i;
+  for (i = 0; i <= n; i++)
+    {
+      a_thread_local += i;
+    }
+}

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