x86: Skip ISA check for always_inline in system headers
For always_inline in system headers, we don't know if caller's ISAs are compatible with callee's ISAs until much later. Skip ISA check for always_inline in system headers if caller has target attribute. gcc/ PR target/98209 PR target/99744 * config/i386/i386.c (ix86_can_inline_p): Don't check ISA for always_inline in system headers. gcc/testsuite/ PR target/98209 PR target/99744 * gcc.target/i386/pr98209.c: New test. * gcc.target/i386/pr99744-1.c: Likewise. * gcc.target/i386/pr99744-2.c: Likewise.
This commit is contained in:
parent
d99111fd8e
commit
72982851d7
@ -578,21 +578,29 @@ ix86_can_inline_p (tree caller, tree callee)
|
||||
&& lookup_attribute ("always_inline",
|
||||
DECL_ATTRIBUTES (callee)));
|
||||
|
||||
/* NB: Skip ISA check for always_inline in system headers if caller
|
||||
has target attribute. */
|
||||
bool skip_isa_check = (always_inline
|
||||
&& caller_tree != target_option_default_node
|
||||
&& DECL_IN_SYSTEM_HEADER (callee));
|
||||
|
||||
cgraph_node *callee_node = cgraph_node::get (callee);
|
||||
/* Callee's isa options should be a subset of the caller's, i.e. a SSE4
|
||||
function can inline a SSE2 function but a SSE2 function can't inline
|
||||
a SSE4 function. */
|
||||
if (((caller_opts->x_ix86_isa_flags & callee_opts->x_ix86_isa_flags)
|
||||
!= callee_opts->x_ix86_isa_flags)
|
||||
|| ((caller_opts->x_ix86_isa_flags2 & callee_opts->x_ix86_isa_flags2)
|
||||
!= callee_opts->x_ix86_isa_flags2))
|
||||
if (!skip_isa_check
|
||||
&& (((caller_opts->x_ix86_isa_flags & callee_opts->x_ix86_isa_flags)
|
||||
!= callee_opts->x_ix86_isa_flags)
|
||||
|| ((caller_opts->x_ix86_isa_flags2 & callee_opts->x_ix86_isa_flags2)
|
||||
!= callee_opts->x_ix86_isa_flags2)))
|
||||
ret = false;
|
||||
|
||||
/* See if we have the same non-isa options. */
|
||||
else if ((!always_inline
|
||||
&& caller_opts->x_target_flags != callee_opts->x_target_flags)
|
||||
|| (caller_opts->x_target_flags & ~always_inline_safe_mask)
|
||||
!= (callee_opts->x_target_flags & ~always_inline_safe_mask))
|
||||
else if (!skip_isa_check
|
||||
&& ((!always_inline
|
||||
&& caller_opts->x_target_flags != callee_opts->x_target_flags)
|
||||
|| ((caller_opts->x_target_flags & ~always_inline_safe_mask)
|
||||
!= (callee_opts->x_target_flags & ~always_inline_safe_mask))))
|
||||
ret = false;
|
||||
|
||||
/* See if arch, tune, etc. are the same. */
|
||||
|
13
gcc/testsuite/gcc.target/i386/pr98209.c
Normal file
13
gcc/testsuite/gcc.target/i386/pr98209.c
Normal file
@ -0,0 +1,13 @@
|
||||
/* { dg-do run { target *-*-linux* } } */
|
||||
/* { dg-options "-O2 -D_FORTIFY_SOURCE=2" } */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
extern int main(int argc, char** argv)
|
||||
__attribute__ ((__target__ ("no-sse,no-mmx")));
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
printf ("hello!\n");
|
||||
return 0;
|
||||
}
|
16
gcc/testsuite/gcc.target/i386/pr99744-1.c
Normal file
16
gcc/testsuite/gcc.target/i386/pr99744-1.c
Normal file
@ -0,0 +1,16 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O0" } */
|
||||
|
||||
#include <x86intrin.h>
|
||||
|
||||
extern unsigned long long int curr_deadline;
|
||||
extern void bar (void);
|
||||
|
||||
__attribute__ ((target("general-regs-only")))
|
||||
void
|
||||
foo (void)
|
||||
{
|
||||
if (__rdtsc () < curr_deadline)
|
||||
return;
|
||||
bar ();
|
||||
}
|
13
gcc/testsuite/gcc.target/i386/pr99744-2.c
Normal file
13
gcc/testsuite/gcc.target/i386/pr99744-2.c
Normal file
@ -0,0 +1,13 @@
|
||||
/* { dg-do compile { target { ! ia32 } } } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
#include <x86intrin.h>
|
||||
|
||||
extern __m128i x, y;
|
||||
|
||||
__attribute__ ((target("general-regs-only")))
|
||||
void
|
||||
foo (void)
|
||||
{
|
||||
x = _mm_move_epi64 (y); /* { dg-error "SSE register return with SSE disabled" } */
|
||||
}
|
Loading…
Reference in New Issue
Block a user