Committed, CRIS: Fix PR target/6838 on main trunk
Hans-Peter Nilsson
hans-peter.nilsson@axis.com
Wed May 29 09:57:00 GMT 2002
The bug was visible on main trunk too. I tweaked constraints to
try and avoid this combination. Tested on cris-elf in
simulator. See also
<URL:http://gcc.gnu.org/ml/gcc-patches/2002-05/msg02300.html>
and <URL:http://gcc.gnu.org/ml/gcc-patches/2002-05/msg02269.html>.
gcc/testsuite:
* gcc.c-torture/execute/20020529-1.c: New test.
gcc:
PR target/6838
* config/cris/cris.md: Fix typos and thinkos in comments.
("*mov_sideqi_biap_mem"): Remove '*' in constraint for operand 4,
second alternative.
("*mov_sidehi_biap_mem", "*mov_sidesi_biap_mem"): Ditto.
("*mov_sideqi_mem"): Similar, but for operand 3.
("*mov_sidehi_mem", "*mov_sidesi_mem"): Ditto.
(splitter for mov_sideqi_mem, mov_sidehi_mem, mov_sidesi_mem):
Remove spurious mode specifier on operand 2.
*** /dev/null Tue Jan 1 05:00:00 1980
--- gcc.c-torture/execute/20020529-1.c Wed May 29 02:30:03 2002
***************
*** 0 ****
--- 1,78 ----
+ /* PR target/6838 from cato@df.lth.se.
+ cris-elf got an ICE with -O2: the insn matching
+ (insn 49 48 52 (parallel[
+ (set (mem/s:HI (plus:SI (reg/v/f:SI 0 r0 [24])
+ (const_int 8 [0x8])) [5 <variable>.c+0 S2 A8])
+ (reg:HI 2 r2 [27]))
+ (set (reg/f:SI 2 r2 [31])
+ (plus:SI (reg/v/f:SI 0 r0 [24])
+ (const_int 8 [0x8])))
+ ] ) 24 {*mov_sidehi_mem} (nil)
+ (nil))
+ forced a splitter through the output pattern "#", but there was no
+ matching splitter. */
+
+ struct xx
+ {
+ int a;
+ struct xx *b;
+ short c;
+ };
+
+ int f1 (struct xx *);
+ void f2 (void);
+
+ int
+ foo (struct xx *p, int b, int c, int d)
+ {
+ int a;
+
+ for (;;)
+ {
+ a = f1(p);
+ if (a)
+ return (0);
+ if (b)
+ continue;
+ p->c = d;
+ if (p->a)
+ f2 ();
+ if (c)
+ f2 ();
+ d = p->c;
+ switch (a)
+ {
+ case 1:
+ if (p->b)
+ f2 ();
+ if (c)
+ f2 ();
+ default:
+ break;
+ }
+ }
+ return d;
+ }
+
+ int main (void)
+ {
+ struct xx s = {0, &s, 23};
+ if (foo (&s, 0, 0, 0) != 0 || s.a != 0 || s.b != &s || s.c != 0)
+ abort ();
+ exit (0);
+ }
+
+ int
+ f1 (struct xx *p)
+ {
+ static int beenhere = 0;
+ if (beenhere++ > 1)
+ abort ();
+ return beenhere > 1;
+ }
+
+ void
+ f2 (void)
+ {
+ abort ();
+ }
Index: cris.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/cris/cris.md,v
retrieving revision 1.2
diff -p -c -r1.2 cris.md
*** cris.md 4 Nov 2001 02:51:23 -0000 1.2
--- cris.md 29 May 2002 15:42:07 -0000
***************
*** 1,5 ****
;; GCC machine description for CRIS cpu cores.
! ;; Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
;; Contributed by Axis Communications.
;; This file is part of GCC.
--- 1,5 ----
;; GCC machine description for CRIS cpu cores.
! ;; Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
;; Contributed by Axis Communications.
;; This file is part of GCC.
***************
*** 385,391 ****
prefer to split up constants early, like this. The testcase in
gcc.c-torture/execute/961213-1.c shows that CSE2 gets confused by the
resulting subreg sets when using the construct from mcore (as of FSF
! CVS, version -r 1.5), and it believe that the high part (the last one
emitted) is the final value. This construct from romp seems more
robust, especially considering the head comments from
emit_no_conflict_block. */
--- 385,391 ----
prefer to split up constants early, like this. The testcase in
gcc.c-torture/execute/961213-1.c shows that CSE2 gets confused by the
resulting subreg sets when using the construct from mcore (as of FSF
! CVS, version -r 1.5), and it believes that the high part (the last one
emitted) is the final value. This construct from romp seems more
robust, especially considering the head comments from
emit_no_conflict_block. */
***************
*** 561,577 ****
;; Other way around; move to memory.
! ;; For all side-effect patterns, it seems to be the case that the
! ;; predicate isn't consulted after combine. For sake of stability, we
! ;; recognize and split the cases where dangerous register combinations are
! ;; spotted: where a register is set in the side-effect, and used in the
! ;; main insn. We don't handle the case where the set in the main insn
! ;; overlaps the set in the side-effect; that would be too big a bug to
! ;; paper over. We handle just the case where the set in the side-effect
! ;; overlaps the input operand of the main insn (i.e. just moves to memory).
;;
! ;; move.s rx,[ry=rx+rw.S]
;; FIXME: These could have anonymous mode for operand 3.
;; QImode
--- 561,582 ----
;; Other way around; move to memory.
! ;; Note that the condition (which for side-effect patterns is usually a
! ;; call to cris_side_effect_mode_ok), isn't consulted for register
! ;; allocation preferences -- constraints is the method for that. The
! ;; drawback is that we can't exclude register allocation to cause
! ;; "move.s rw,[rx=ry+rz.S]" when rw==rx without also excluding rx==ry or
! ;; rx==rz if we use an earlyclobber modifier for the constraint for rx.
! ;; Instead of that, we recognize and split the cases where dangerous
! ;; register combinations are spotted: where a register is set in the
! ;; side-effect, and used in the main insn. We don't handle the case where
! ;; the set in the main insn overlaps the set in the side-effect; that case
! ;; must be handled in gcc. We handle just the case where the set in the
! ;; side-effect overlaps the input operand of the main insn (i.e. just
! ;; moves to memory).
;;
! ;; move.s rz,[ry=rx+rw.S]
;; FIXME: These could have anonymous mode for operand 3.
;; QImode
***************
*** 582,588 ****
(match_operand:SI 1 "const_int_operand" "n,n,n"))
(match_operand:SI 2 "register_operand" "r,r,r")))
(match_operand:QI 3 "register_operand" "r,r,r"))
! (set (match_operand:SI 4 "register_operand" "=*2,!*3,r")
(plus:SI (mult:SI (match_dup 0)
(match_dup 1))
(match_dup 2)))]
--- 587,593 ----
(match_operand:SI 1 "const_int_operand" "n,n,n"))
(match_operand:SI 2 "register_operand" "r,r,r")))
(match_operand:QI 3 "register_operand" "r,r,r"))
! (set (match_operand:SI 4 "register_operand" "=*2,!3,r")
(plus:SI (mult:SI (match_dup 0)
(match_dup 1))
(match_dup 2)))]
***************
*** 600,606 ****
(match_operand:SI 1 "const_int_operand" "n,n,n"))
(match_operand:SI 2 "register_operand" "r,r,r")))
(match_operand:HI 3 "register_operand" "r,r,r"))
! (set (match_operand:SI 4 "register_operand" "=*2,!*3,r")
(plus:SI (mult:SI (match_dup 0)
(match_dup 1))
(match_dup 2)))]
--- 605,611 ----
(match_operand:SI 1 "const_int_operand" "n,n,n"))
(match_operand:SI 2 "register_operand" "r,r,r")))
(match_operand:HI 3 "register_operand" "r,r,r"))
! (set (match_operand:SI 4 "register_operand" "=*2,!3,r")
(plus:SI (mult:SI (match_dup 0)
(match_dup 1))
(match_dup 2)))]
***************
*** 618,624 ****
(match_operand:SI 1 "const_int_operand" "n,n,n"))
(match_operand:SI 2 "register_operand" "r,r,r")))
(match_operand:SI 3 "register_operand" "r,r,r"))
! (set (match_operand:SI 4 "register_operand" "=*2,!*3,r")
(plus:SI (mult:SI (match_dup 0)
(match_dup 1))
(match_dup 2)))]
--- 623,629 ----
(match_operand:SI 1 "const_int_operand" "n,n,n"))
(match_operand:SI 2 "register_operand" "r,r,r")))
(match_operand:SI 3 "register_operand" "r,r,r"))
! (set (match_operand:SI 4 "register_operand" "=*2,!3,r")
(plus:SI (mult:SI (match_dup 0)
(match_dup 1))
(match_dup 2)))]
***************
*** 628,637 ****
#
move.%s3 %3,[%4=%2+%0%T1]")
! ;; Split for the case above where the predicate isn't honored; only the
! ;; constraint, and we end up with the set in the side-effect gets the same
! ;; register as the input register. Arguably a GCC bug, but we'll spot it
! ;; rarely enough that we need to catch it ourselves to be safe.
(define_split
[(parallel
--- 633,642 ----
#
move.%s3 %3,[%4=%2+%0%T1]")
! ;; Split for the case above where we're out of luck with register
! ;; allocation (again, the condition isn't checked for that), and we end up
! ;; with the set in the side-effect getting the same register as the input
! ;; register.
(define_split
[(parallel
***************
*** 668,674 ****
(plus:SI (match_operand:SI 0 "cris_bdap_operand" "%r,r,r,r")
(match_operand:SI 1 "cris_bdap_operand" "r>Ri,r>Ri,r,>Ri")))
(match_operand:QI 2 "register_operand" "r,r,r,r"))
! (set (match_operand:SI 3 "register_operand" "=*0,!*2,r,r")
(plus:SI (match_dup 0)
(match_dup 1)))]
"cris_side_effect_mode_ok (PLUS, operands, 3, 0, 1, -1, 2)"
--- 673,679 ----
(plus:SI (match_operand:SI 0 "cris_bdap_operand" "%r,r,r,r")
(match_operand:SI 1 "cris_bdap_operand" "r>Ri,r>Ri,r,>Ri")))
(match_operand:QI 2 "register_operand" "r,r,r,r"))
! (set (match_operand:SI 3 "register_operand" "=*0,!2,r,r")
(plus:SI (match_dup 0)
(match_dup 1)))]
"cris_side_effect_mode_ok (PLUS, operands, 3, 0, 1, -1, 2)"
***************
*** 693,699 ****
(plus:SI (match_operand:SI 0 "cris_bdap_operand" "%r,r,r,r")
(match_operand:SI 1 "cris_bdap_operand" "r>Ri,r>Ri,r,>Ri")))
(match_operand:HI 2 "register_operand" "r,r,r,r"))
! (set (match_operand:SI 3 "register_operand" "=*0,!*2,r,r")
(plus:SI (match_dup 0)
(match_dup 1)))]
"cris_side_effect_mode_ok (PLUS, operands, 3, 0, 1, -1, 2)"
--- 698,704 ----
(plus:SI (match_operand:SI 0 "cris_bdap_operand" "%r,r,r,r")
(match_operand:SI 1 "cris_bdap_operand" "r>Ri,r>Ri,r,>Ri")))
(match_operand:HI 2 "register_operand" "r,r,r,r"))
! (set (match_operand:SI 3 "register_operand" "=*0,!2,r,r")
(plus:SI (match_dup 0)
(match_dup 1)))]
"cris_side_effect_mode_ok (PLUS, operands, 3, 0, 1, -1, 2)"
***************
*** 718,724 ****
(plus:SI (match_operand:SI 0 "cris_bdap_operand" "%r,r,r,r")
(match_operand:SI 1 "cris_bdap_operand" "r>Ri,r>Ri,r,>Ri")))
(match_operand:SI 2 "register_operand" "r,r,r,r"))
! (set (match_operand:SI 3 "register_operand" "=*0,!*2,r,r")
(plus:SI (match_dup 0)
(match_dup 1)))]
"cris_side_effect_mode_ok (PLUS, operands, 3, 0, 1, -1, 2)"
--- 723,729 ----
(plus:SI (match_operand:SI 0 "cris_bdap_operand" "%r,r,r,r")
(match_operand:SI 1 "cris_bdap_operand" "r>Ri,r>Ri,r,>Ri")))
(match_operand:SI 2 "register_operand" "r,r,r,r"))
! (set (match_operand:SI 3 "register_operand" "=*0,!2,r,r")
(plus:SI (match_dup 0)
(match_dup 1)))]
"cris_side_effect_mode_ok (PLUS, operands, 3, 0, 1, -1, 2)"
***************
*** 737,751 ****
}")
;; Like the biap case, a split where the set in the side-effect gets the
! ;; same register as the input register to the main insn due to gcc not
! ;; always checking the predicate.
(define_split
[(parallel
[(set (mem (plus:SI
(match_operand:SI 0 "cris_bdap_operand" "")
(match_operand:SI 1 "cris_bdap_operand" "")))
! (match_operand:SI 2 "register_operand" ""))
(set (match_operand:SI 3 "register_operand" "")
(plus:SI (match_dup 0) (match_dup 1)))])]
"reload_completed && reg_overlap_mentioned_p (operands[3], operands[2])"
--- 742,756 ----
}")
;; Like the biap case, a split where the set in the side-effect gets the
! ;; same register as the input register to the main insn, since the
! ;; condition isn't checked at register allocation.
(define_split
[(parallel
[(set (mem (plus:SI
(match_operand:SI 0 "cris_bdap_operand" "")
(match_operand:SI 1 "cris_bdap_operand" "")))
! (match_operand 2 "register_operand" ""))
(set (match_operand:SI 3 "register_operand" "")
(plus:SI (match_dup 0) (match_dup 1)))])]
"reload_completed && reg_overlap_mentioned_p (operands[3], operands[2])"
***************
*** 4272,4278 ****
(set (match_dup 5) (match_dup 2))]
"operands[5] = gen_rtx_MEM (GET_MODE (operands[2]), operands[3]);")
! ;; clear.d ry,[rx=rx+rz.S2]
(define_split
[(parallel
--- 4277,4283 ----
(set (match_dup 5) (match_dup 2))]
"operands[5] = gen_rtx_MEM (GET_MODE (operands[2]), operands[3]);")
! ;; clear.d [rx=rx+rz.S2]
(define_split
[(parallel
***************
*** 4292,4298 ****
(set (mem:SI (match_dup 3)) (const_int 0))]
"")
! ;; clear.w ry,[rx=rx+rz.S2]
(define_split
[(parallel
--- 4297,4303 ----
(set (mem:SI (match_dup 3)) (const_int 0))]
"")
! ;; clear.w [rx=rx+rz.S2]
(define_split
[(parallel
***************
*** 4312,4318 ****
(set (mem:HI (match_dup 3)) (const_int 0))]
"")
! ;; clear.b ry,[rx=rx+rz.S2]
(define_split
[(parallel
--- 4317,4323 ----
(set (mem:HI (match_dup 3)) (const_int 0))]
"")
! ;; clear.b [rx=rx+rz.S2]
(define_split
[(parallel
***************
*** 4332,4338 ****
(set (mem:QI (match_dup 3)) (const_int 0))]
"")
! ;; clear.d ry,[rx=rx+i]
(define_split
[(parallel
--- 4337,4343 ----
(set (mem:QI (match_dup 3)) (const_int 0))]
"")
! ;; clear.d [rx=rx+i]
(define_split
[(parallel
***************
*** 4349,4355 ****
(set (mem:SI (match_dup 2)) (const_int 0))]
"")
! ;; clear.w ry,[rx=rx+i]
(define_split
[(parallel
--- 4354,4360 ----
(set (mem:SI (match_dup 2)) (const_int 0))]
"")
! ;; clear.w [rx=rx+i]
(define_split
[(parallel
***************
*** 4366,4372 ****
(set (mem:HI (match_dup 2)) (const_int 0))]
"")
! ;; clear.b ry,[rx=rx+i]
(define_split
[(parallel
--- 4371,4377 ----
(set (mem:HI (match_dup 2)) (const_int 0))]
"")
! ;; clear.b [rx=rx+i]
(define_split
[(parallel
brgds, H-P
More information about the Gcc-patches
mailing list