patch for ia64 epilogue scheduling bug
Jim Wilson
wilson@cygnus.com
Thu Mar 23 11:41:00 GMT 2000
This fixes a bug where the predicate register restores in the epilogue could
be moved before the last use of predicate registers in the function. The
particular example that found the problem had a conditional expression as
the return value.
Thu Mar 23 11:34:39 2000 Jim Wilson <wilson@cygnus.com>
* config/ia64/ia64.c (rtx_needs_barrier, case UNSPEC): Move case 6...
(rtx_needs_barrier, case UNSPEC_VOLATILE): to here.
* config/ia64/ia64.md (pr_restore): Change UNSPEC to UNSPEC_VOLATILE.
Index: ia64.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/ia64/ia64.c,v
retrieving revision 1.6
diff -p -r1.6 ia64.c
*** ia64.c 2000/03/21 04:05:49 1.6
--- ia64.c 2000/03/23 19:34:02
*************** rtx_needs_barrier (x, flags, pred)
*** 2421,2436 ****
need_barrier |= rws_access_reg (i, flags, pred);
break;
! case 6: /* mov pr= */
! /* This writes all predicate registers. */
! new_flags.is_write = 1;
! /* We need to skip by two, because rws_access_reg always writes
! to two predicate registers at a time. */
! /* ??? Strictly speaking, we shouldn't be counting writes to pr0. */
! for (i = PR_REG (0); i < PR_REG (64); i += 2)
! need_barrier |= rws_access_reg (i, new_flags, pred);
! break;
!
case 7:
abort ();
--- 2421,2427 ----
need_barrier |= rws_access_reg (i, flags, pred);
break;
! case 6:
case 7:
abort ();
*************** rtx_needs_barrier (x, flags, pred)
*** 2484,2489 ****
--- 2475,2490 ----
case 4: /* mov ar.pfs= */
new_flags.is_write = 1;
need_barrier = rws_access_reg (REG_AR_PFS, new_flags, pred);
+ break;
+
+ case 6: /* mov pr= */
+ /* This writes all predicate registers. */
+ new_flags.is_write = 1;
+ /* We need to skip by two, because rws_access_reg always writes
+ to two predicate registers at a time. */
+ /* ??? Strictly speaking, we shouldn't be counting writes to pr0. */
+ for (i = PR_REG (0); i < PR_REG (64); i += 2)
+ need_barrier |= rws_access_reg (i, new_flags, pred);
break;
default:
Index: ia64.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/ia64/ia64.md,v
retrieving revision 1.5
diff -p -r1.5 ia64.md
*** ia64.md 2000/03/17 20:22:18 1.5
--- ia64.md 2000/03/23 19:34:02
***************
*** 3049,3056 ****
"mov %0 = pr"
[(set_attr "type" "I")])
(define_insn "pr_restore"
! [(unspec [(const_int 0)] 6)
(use (match_operand:DI 0 "register_operand" "r"))]
""
"mov pr = %0, -1"
--- 3049,3059 ----
"mov %0 = pr"
[(set_attr "type" "I")])
+ ;; ??? This is volatile to prevent it from being moved before a conditional
+ ;; expression that calculates the return value.
+
(define_insn "pr_restore"
! [(unspec_volatile [(const_int 0)] 6)
(use (match_operand:DI 0 "register_operand" "r"))]
""
"mov pr = %0, -1"
More information about the Gcc-patches
mailing list