This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
fix alpha iostreams miscompile
- From: Richard Henderson <rth at twiddle dot net>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 26 Oct 2003 22:56:15 -0800
- Subject: fix alpha iostreams miscompile
All iostreams test cases have been failing on alpha for the last
month or two. I finally tracked it down to a miscompilation of
some of the locale initialization code.
BB-reorder decided to duplicate a block that ended in a call that
had an internal exception edge. It then inserted a branch from
the duplicated call to the GP reload instructions, which were in
the next block (obviously, because of the exception edge). Except
that doesn't work. The GP is reloaded with pc-relative relocations
based off of the return address of the call. The call and the
GP reload are tightly coupled.
So we prevent the bug by prohibiting calls associated with GP
reloads from being copied.
r~
* config/alpha/alpha.md (attr cannot_copy): New.
(call_osf_2_er, call_value_osf_2_er, ldgp_er_1, ldgp_er_2,
prologue_ldgp_er_2, prologue_ldgp_1): Set it.
* config/alpha/alpha.c (alpha_cannot_copy_insn_p): Test it.
Index: alpha.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.c,v
retrieving revision 1.335
diff -c -p -d -u -r1.335 alpha.c
--- alpha.c 22 Oct 2003 12:12:15 -0000 1.335
+++ alpha.c 26 Oct 2003 19:53:55 -0000
@@ -2012,38 +2012,22 @@ split_small_symbolic_operand (rtx x)
Technically we could copy them if we could set up a mapping from one
sequence number to another, across the set of insns to be duplicated.
This seems overly complicated and error-prone since interblock motion
- from sched-ebb could move one of the pair of insns to a different block. */
+ from sched-ebb could move one of the pair of insns to a different block.
+
+ Also cannot allow jsr insns to be duplicated. If they throw exceptions,
+ then they'll be in a different block from their ldgp. Which could lead
+ the bb reorder code to think that it would be ok to copy just the block
+ containing the call and branch to the block containing the ldgp. */
static bool
alpha_cannot_copy_insn_p (rtx insn)
{
- rtx pat;
-
if (!reload_completed || !TARGET_EXPLICIT_RELOCS)
return false;
-
- if (GET_CODE (insn) != INSN)
- return false;
- if (asm_noperands (insn) >= 0)
- return false;
-
- pat = PATTERN (insn);
- if (GET_CODE (pat) != SET)
+ if (recog_memoized (insn) >= 0)
+ return get_attr_cannot_copy (insn);
+ else
return false;
- pat = SET_SRC (pat);
- if (GET_CODE (pat) == UNSPEC_VOLATILE)
- {
- if (XINT (pat, 1) == UNSPECV_LDGP1
- || XINT (pat, 1) == UNSPECV_PLDGP2)
- return true;
- }
- else if (GET_CODE (pat) == UNSPEC)
- {
- if (XINT (pat, 1) == UNSPEC_LDGP2)
- return true;
- }
-
- return false;
}
Index: alpha.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.md,v
retrieving revision 1.214
diff -c -p -d -u -r1.214 alpha.md
--- alpha.md 19 Oct 2003 11:10:59 -0000 1.214
+++ alpha.md 26 Oct 2003 19:54:01 -0000
@@ -97,8 +97,8 @@
;; separately.
(define_attr "type"
- "ild,fld,ldsym,ist,fst,ibr,callpal,fbr,jsr,iadd,ilog,shift,icmov,fcmov,icmp,imul,\
-fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
+ "ild,fld,ldsym,ist,fst,ibr,callpal,fbr,jsr,iadd,ilog,shift,icmov,fcmov,
+ icmp,imul,fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(const_string "iadd"))
;; Describe a user's asm statement.
@@ -154,6 +154,14 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
]
(const_string "no")))
+;; The CANNOT_COPY attribute marks instructions with relocations that
+;; cannot easily be duplicated. This includes insns with gpdisp relocs
+;; since they have to stay in 1-1 correspondence with one another. This
+;; also includes jsr insns, since they must stay in correspondence with
+;; the immediately following gpdisp instructions.
+
+(define_attr "cannot_copy" "false,true"
+ (const_string "false"))
;; Include scheduling descriptions.
@@ -4740,7 +4748,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
(use (match_operand 3 "const_int_operand" ""))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"jsr $26,(%0),%2%J3"
- [(set_attr "type" "jsr")])
+ [(set_attr "type" "jsr")
+ (set_attr "cannot_copy" "true")])
;; We output a nop after noreturn calls at the very end of the function to
;; ensure that the return address always remains in the caller's code range,
@@ -6814,7 +6823,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
(match_operand 2 "const_int_operand" "")]
UNSPECV_LDGP1))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
- "ldah %0,0(%1)\t\t!gpdisp!%2")
+ "ldah %0,0(%1)\t\t!gpdisp!%2"
+ [(set_attr "cannot_copy" "true")])
(define_insn "*ldgp_er_2"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -6822,7 +6832,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
(match_operand 2 "const_int_operand" "")]
UNSPEC_LDGP2))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
- "lda %0,0(%1)\t\t!gpdisp!%2")
+ "lda %0,0(%1)\t\t!gpdisp!%2"
+ [(set_attr "cannot_copy" "true")])
(define_insn "*prologue_ldgp_er_2"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -6830,7 +6841,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
(match_operand 2 "const_int_operand" "")]
UNSPECV_PLDGP2))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
- "lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:")
+ "lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:"
+ [(set_attr "cannot_copy" "true")])
(define_insn "*prologue_ldgp_1"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -6838,7 +6850,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
(match_operand 2 "const_int_operand" "")]
UNSPECV_LDGP1))]
""
- "ldgp %0,0(%1)\n$%~..ng:")
+ "ldgp %0,0(%1)\n$%~..ng:"
+ [(set_attr "cannot_copy" "true")])
(define_insn "*prologue_ldgp_2"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -7974,7 +7987,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
(use (match_operand 4 "" ""))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"jsr $26,(%1),%3%J4"
- [(set_attr "type" "jsr")])
+ [(set_attr "type" "jsr")
+ (set_attr "cannot_copy" "true")])
(define_insn "*call_value_osf_1_noreturn"
[(set (match_operand 0 "" "")