This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[csl-arm] Arm tls ICE
- From: Paul Brook <paul at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: drow at codesourcery dot com
- Date: Sat, 22 Oct 2005 23:37:52 +0100
- Subject: [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;
+ }
+}