re PR target/60104 (load not folded into indirect branch on x86-64)
PR target/60104 * config/i386/i386.c (x86_output_mi_thunk): Add memory case for sibling-tail-calls. * config/i386/i386.md (sibcall_insn_operand): Add memory-constrain to its use. * config/i386/predicates.md (sibcall_memory_operand): New predicate. (sibcall_insn_operand): Add check for sibcall_memory_operand. PR target/60104 * gcc.target/i386/sibcall-1.c: New test. * gcc.target/i386/sibcall-2.c: New test. * gcc.target/i386/sibcall-3.c: New test. * gcc.target/i386/sibcall-4.c: New test. From-SVN: r211089
This commit is contained in:
parent
1007a55ca4
commit
cb10592208
8 changed files with 92 additions and 6 deletions
|
@ -1,3 +1,13 @@
|
|||
2014-05-30 Kai Tietz <ktietz@redhat.com>
|
||||
|
||||
PR target/60104
|
||||
* config/i386/i386.c (x86_output_mi_thunk): Add memory case
|
||||
for sibling-tail-calls.
|
||||
* config/i386/i386.md (sibcall_insn_operand): Add memory-constrain
|
||||
to its use.
|
||||
* config/i386/predicates.md (sibcall_memory_operand): New predicate.
|
||||
(sibcall_insn_operand): Add check for sibcall_memory_operand.
|
||||
|
||||
2014-05-30 Pitchumani Sivanupandi <pitchumani.s@atmel.com>
|
||||
|
||||
* config/avr/avr-mcus.def: Change ATA6289 ISA to AVR4
|
||||
|
|
|
@ -38893,7 +38893,16 @@ x86_output_mi_thunk (FILE *file,
|
|||
For our purposes here, we can get away with (ab)using a jump pattern,
|
||||
because we're going to do no optimization. */
|
||||
if (MEM_P (fnaddr))
|
||||
emit_jump_insn (gen_indirect_jump (fnaddr));
|
||||
{
|
||||
if (sibcall_insn_operand (fnaddr, word_mode))
|
||||
{
|
||||
tmp = gen_rtx_CALL (VOIDmode, fnaddr, const0_rtx);
|
||||
tmp = emit_call_insn (tmp);
|
||||
SIBLING_CALL_P (tmp) = 1;
|
||||
}
|
||||
else
|
||||
emit_jump_insn (gen_indirect_jump (fnaddr));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ix86_cmodel == CM_LARGE_PIC && SYMBOLIC_CONST (fnaddr))
|
||||
|
|
|
@ -11376,7 +11376,7 @@
|
|||
[(set_attr "type" "call")])
|
||||
|
||||
(define_insn "*sibcall"
|
||||
[(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
|
||||
[(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uzm"))
|
||||
(match_operand 1))]
|
||||
"SIBLING_CALL_P (insn)"
|
||||
"* return ix86_output_call_insn (insn, operands[0]);"
|
||||
|
@ -11406,7 +11406,7 @@
|
|||
[(set_attr "type" "call")])
|
||||
|
||||
(define_insn "*sibcall_pop"
|
||||
[(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
|
||||
[(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uzm"))
|
||||
(match_operand 1))
|
||||
(set (reg:SI SP_REG)
|
||||
(plus:SI (reg:SI SP_REG)
|
||||
|
@ -11451,7 +11451,7 @@
|
|||
|
||||
(define_insn "*sibcall_value"
|
||||
[(set (match_operand 0)
|
||||
(call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
|
||||
(call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uzm"))
|
||||
(match_operand 2)))]
|
||||
"SIBLING_CALL_P (insn)"
|
||||
"* return ix86_output_call_insn (insn, operands[1]);"
|
||||
|
@ -11494,7 +11494,7 @@
|
|||
|
||||
(define_insn "*sibcall_value_pop"
|
||||
[(set (match_operand 0)
|
||||
(call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
|
||||
(call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uzm"))
|
||||
(match_operand 2)))
|
||||
(set (reg:SI SP_REG)
|
||||
(plus:SI (reg:SI SP_REG)
|
||||
|
|
|
@ -71,6 +71,12 @@
|
|||
return ANY_QI_REG_P (op);
|
||||
})
|
||||
|
||||
(define_predicate "sibcall_memory_operand"
|
||||
(match_operand 0 "memory_operand")
|
||||
{
|
||||
return CONSTANT_P (XEXP (op, 0));
|
||||
})
|
||||
|
||||
;; Match an SI or HImode register for a zero_extract.
|
||||
(define_special_predicate "ext_register_operand"
|
||||
(match_operand 0 "register_operand")
|
||||
|
@ -600,7 +606,9 @@
|
|||
(define_special_predicate "sibcall_insn_operand"
|
||||
(ior (match_test "constant_call_address_operand
|
||||
(op, mode == VOIDmode ? mode : Pmode)")
|
||||
(match_operand 0 "register_no_elim_operand")))
|
||||
(match_operand 0 "register_no_elim_operand")
|
||||
(and (not (match_test "TARGET_X32"))
|
||||
(match_operand 0 "sibcall_memory_operand"))))
|
||||
|
||||
;; Return true if OP is a call from MS ABI to SYSV ABI function.
|
||||
(define_predicate "call_rex64_ms_sysv_operation"
|
||||
|
|
12
gcc/testsuite/gcc.target/i386/sibcall-1.c
Normal file
12
gcc/testsuite/gcc.target/i386/sibcall-1.c
Normal file
|
@ -0,0 +1,12 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target ia32 } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
extern int (*foo)(int);
|
||||
|
||||
int boo (int a)
|
||||
{
|
||||
return (*foo) (a);
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-not "mov" } } */
|
16
gcc/testsuite/gcc.target/i386/sibcall-2.c
Normal file
16
gcc/testsuite/gcc.target/i386/sibcall-2.c
Normal file
|
@ -0,0 +1,16 @@
|
|||
/* { dg-do compile { xfail { *-*-* } } } */
|
||||
/* { dg-require-effective-target ia32 } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
extern int doo1 (int);
|
||||
extern int doo2 (int);
|
||||
extern void bar (char *);
|
||||
|
||||
int foo (int a)
|
||||
{
|
||||
char s[256];
|
||||
bar (s);
|
||||
return (a < 0 ? doo1 : doo2) (a);
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-not "call[ \t]*.%eax" } } */
|
16
gcc/testsuite/gcc.target/i386/sibcall-3.c
Normal file
16
gcc/testsuite/gcc.target/i386/sibcall-3.c
Normal file
|
@ -0,0 +1,16 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target ia32 } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
extern
|
||||
#ifdef _WIN32
|
||||
__declspec (dllimport)
|
||||
#endif
|
||||
void foo (int a);
|
||||
|
||||
void bar (int a)
|
||||
{
|
||||
return foo (a);
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-not "jmp[ \t]*.%eax" } } */
|
15
gcc/testsuite/gcc.target/i386/sibcall-4.c
Normal file
15
gcc/testsuite/gcc.target/i386/sibcall-4.c
Normal file
|
@ -0,0 +1,15 @@
|
|||
/* Testcase for PR target/46219. */
|
||||
/* { dg-do compile { xfail { *-*-* } } */
|
||||
/* { dg-require-effective-target ia32 } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
typedef void (*dispatch_t)(long offset);
|
||||
|
||||
dispatch_t dispatch[256];
|
||||
|
||||
void male_indirect_jump (long offset)
|
||||
{
|
||||
dispatch[offset](offset);
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-not "jmp[ \t]*.%eax" } } */
|
Loading…
Add table
Reference in a new issue