re PR target/39431 (ICE in spill_failure, at reload1.c:2093)
PR target/39431 * config/i386/predicates.md (cmpxchg8b_pic_memory_operand): New predicate. * config/i386/sync.md (sync_compare_and_swap<mode>, sync_compare_and_swap_cc<mode>): For DImode with -m32 -fpic check if operands[1] is cmpxchg8b_pic_memory_operand, if not force address into a register. (sync_double_compare_and_swapdi_pic, sync_double_compare_and_swap_ccdi_pic): Require operand 1 to be cmpxchg8b_pic_memory_operand instead of just memory_operand. * gcc.target/i386/pr39431.c: New test. From-SVN: r144825
This commit is contained in:
parent
122c59c73b
commit
03a181983d
5 changed files with 82 additions and 7 deletions
|
@ -1,3 +1,16 @@
|
|||
2008-03-12 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR target/39431
|
||||
* config/i386/predicates.md (cmpxchg8b_pic_memory_operand): New
|
||||
predicate.
|
||||
* config/i386/sync.md (sync_compare_and_swap<mode>,
|
||||
sync_compare_and_swap_cc<mode>): For DImode with -m32 -fpic check
|
||||
if operands[1] is cmpxchg8b_pic_memory_operand, if not force address
|
||||
into a register.
|
||||
(sync_double_compare_and_swapdi_pic,
|
||||
sync_double_compare_and_swap_ccdi_pic): Require operand 1 to be
|
||||
cmpxchg8b_pic_memory_operand instead of just memory_operand.
|
||||
|
||||
2009-03-12 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR target/39445
|
||||
|
|
|
@ -887,6 +887,34 @@
|
|||
return parts.disp != NULL_RTX;
|
||||
})
|
||||
|
||||
;; Returns 1 if OP is memory operand which will need zero or
|
||||
;; one register at most, not counting stack pointer or frame pointer.
|
||||
(define_predicate "cmpxchg8b_pic_memory_operand"
|
||||
(match_operand 0 "memory_operand")
|
||||
{
|
||||
struct ix86_address parts;
|
||||
int ok;
|
||||
|
||||
ok = ix86_decompose_address (XEXP (op, 0), &parts);
|
||||
gcc_assert (ok);
|
||||
if (parts.base == NULL_RTX
|
||||
|| parts.base == arg_pointer_rtx
|
||||
|| parts.base == frame_pointer_rtx
|
||||
|| parts.base == hard_frame_pointer_rtx
|
||||
|| parts.base == stack_pointer_rtx)
|
||||
return 1;
|
||||
|
||||
if (parts.index == NULL_RTX
|
||||
|| parts.index == arg_pointer_rtx
|
||||
|| parts.index == frame_pointer_rtx
|
||||
|| parts.index == hard_frame_pointer_rtx
|
||||
|| parts.index == stack_pointer_rtx)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
})
|
||||
|
||||
|
||||
;; Returns 1 if OP is memory operand that cannot be represented
|
||||
;; by the modRM array.
|
||||
(define_predicate "long_memory_operand"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
;; GCC machine description for i386 synchronization instructions.
|
||||
;; Copyright (C) 2005, 2006, 2007, 2008
|
||||
;; Copyright (C) 2005, 2006, 2007, 2008, 2009
|
||||
;; Free Software Foundation, Inc.
|
||||
;;
|
||||
;; This file is part of GCC.
|
||||
|
@ -82,8 +82,15 @@
|
|||
low = force_reg (hmode, low);
|
||||
high = force_reg (hmode, high);
|
||||
if (<MODE>mode == DImode)
|
||||
emit_insn (gen_sync_double_compare_and_swapdi
|
||||
(operands[0], operands[1], operands[2], low, high));
|
||||
{
|
||||
if (flag_pic && !cmpxchg8b_pic_memory_operand (operands[1], DImode))
|
||||
operands[1] = replace_equiv_address (operands[1],
|
||||
force_reg (Pmode,
|
||||
XEXP (operands[1],
|
||||
0)));
|
||||
emit_insn (gen_sync_double_compare_and_swapdi
|
||||
(operands[0], operands[1], operands[2], low, high));
|
||||
}
|
||||
else if (<MODE>mode == TImode)
|
||||
emit_insn (gen_sync_double_compare_and_swapti
|
||||
(operands[0], operands[1], operands[2], low, high));
|
||||
|
@ -131,7 +138,7 @@
|
|||
;; are just esi and edi.
|
||||
(define_insn "*sync_double_compare_and_swapdi_pic"
|
||||
[(set (match_operand:DI 0 "register_operand" "=A")
|
||||
(match_operand:DI 1 "memory_operand" "+m"))
|
||||
(match_operand:DI 1 "cmpxchg8b_pic_memory_operand" "+m"))
|
||||
(set (match_dup 1)
|
||||
(unspec_volatile:DI
|
||||
[(match_dup 1)
|
||||
|
@ -173,8 +180,15 @@
|
|||
low = force_reg (hmode, low);
|
||||
high = force_reg (hmode, high);
|
||||
if (<MODE>mode == DImode)
|
||||
emit_insn (gen_sync_double_compare_and_swap_ccdi
|
||||
(operands[0], operands[1], operands[2], low, high));
|
||||
{
|
||||
if (flag_pic && !cmpxchg8b_pic_memory_operand (operands[1], DImode))
|
||||
operands[1] = replace_equiv_address (operands[1],
|
||||
force_reg (Pmode,
|
||||
XEXP (operands[1],
|
||||
0)));
|
||||
emit_insn (gen_sync_double_compare_and_swap_ccdi
|
||||
(operands[0], operands[1], operands[2], low, high));
|
||||
}
|
||||
else if (<MODE>mode == TImode)
|
||||
emit_insn (gen_sync_double_compare_and_swap_ccti
|
||||
(operands[0], operands[1], operands[2], low, high));
|
||||
|
@ -224,7 +238,7 @@
|
|||
;; operand 3.
|
||||
(define_insn "*sync_double_compare_and_swap_ccdi_pic"
|
||||
[(set (match_operand:DI 0 "register_operand" "=A")
|
||||
(match_operand:DI 1 "memory_operand" "+m"))
|
||||
(match_operand:DI 1 "cmpxchg8b_pic_memory_operand" "+m"))
|
||||
(set (match_dup 1)
|
||||
(unspec_volatile:DI
|
||||
[(match_dup 1)
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2008-03-12 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR target/39431
|
||||
* gcc.target/i386/pr39431.c: New test.
|
||||
|
||||
2009-03-12 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR target/39445
|
||||
|
|
15
gcc/testsuite/gcc.target/i386/pr39431.c
Normal file
15
gcc/testsuite/gcc.target/i386/pr39431.c
Normal file
|
@ -0,0 +1,15 @@
|
|||
/* PR target/39431 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
/* { dg-options "-O2 -march=i686 -fpic" { target { ilp32 && fpic } } } */
|
||||
|
||||
extern void bar (char *, int);
|
||||
|
||||
int
|
||||
foo (long long *p, long long oldv, long long *q, int n)
|
||||
{
|
||||
char buf[n];
|
||||
bar (buf, n);
|
||||
p[256 + n] = __sync_val_compare_and_swap (p + n, oldv, oldv + 6);
|
||||
return __sync_bool_compare_and_swap (q + n, oldv, oldv + 8);
|
||||
}
|
Loading…
Add table
Reference in a new issue