!= (callee_opts->x_target_flags & ~always_inline_safe_mask))
ret = false;
- /* See if arch, tune, etc. are the same. */
- else if (caller_opts->arch != callee_opts->arch)
- ret = false;
-
- else if (!always_inline && caller_opts->tune != callee_opts->tune)
- ret = false;
-
else if (caller_opts->x_ix86_fpmath != callee_opts->x_ix86_fpmath
/* If the calle doesn't use FP expressions differences in
ix86_fpmath can be ignored. We are called from FEs
|| ipa_fn_summaries->get (callee_node)->fp_expressions))
ret = false;
+ /* At this point we cannot identify whether arch or tune setting
+ comes from target attribute or not. So the most conservative way
+ is to allow the callee that uses default arch and tune string to
+ be inlined. */
+ else if (!strcmp (callee_opts->x_ix86_arch_string, "x86-64")
+ && !strcmp (callee_opts->x_ix86_tune_string, "generic"))
+ ret = true;
+
+ /* See if arch, tune, etc. are the same. As previous ISA flags already
+ checks if callee's ISA is subset of caller's, do not block
+ always_inline attribute for callee even it has different arch. */
+ else if (!always_inline && caller_opts->arch != callee_opts->arch)
+ ret = false;
+
+ else if (!always_inline && caller_opts->tune != callee_opts->tune)
+ ret = false;
+
else if (!always_inline
&& caller_opts->branch_cost != callee_opts->branch_cost)
ret = false;
--- /dev/null
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O3 -march=x86-64" } */
+/* { dg-final { scan-assembler-not "call\[ \t\]+callee" } } */
+
+__attribute__((always_inline,target("arch=haswell")))
+inline float callee (float a, float b, float c, float d,
+ float e, float f, float g, float h)
+{
+ return a * b + c * d + e * f + g + h + a * c + b * c
+ + a * d + b * e + a * f + c * h +
+ b * (a - 0.4f) * (c + h) * (b + e * d) - a / f * h;
+}
+
+__attribute__((target("arch=icelake-server")))
+void caller (int n, float *a,
+ float c1, float c2, float c3,
+ float c4, float c5, float c6,
+ float c7)
+{
+ for (int i = 0; i < n; i++)
+ {
+ a[i] = callee (a[i], c1, c2, c3, c4, c5, c6, c7);
+ }
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O3 -march=x86-64" } */
+/* { dg-final { scan-assembler-not "call\[ \t\]+callee" } } */
+
+float callee (float a, float b, float c, float d,
+ float e, float f, float g, float h)
+{
+ return a * b + c * d + e * f + g + h + a * c + b * c
+ + a * d + b * e + a * f + c * h +
+ b * (a - 0.4f) * (c + h) * (b + e * d) - a / f * h;
+}
+
+__attribute__((target_clones("default","arch=icelake-server")))
+void caller (int n, float *a,
+ float c1, float c2, float c3,
+ float c4, float c5, float c6,
+ float c7)
+{
+ for (int i = 0; i < n; i++)
+ {
+ a[i] = callee (a[i], c1, c2, c3, c4, c5, c6, c7);
+ }
+}