summaryrefslogtreecommitdiff
path: root/test/CodeGen/attr-target-mv.c
diff options
context:
space:
mode:
authorErich Keane <erich.keane@intel.com>2018-11-28 20:58:43 +0000
committerErich Keane <erich.keane@intel.com>2018-11-28 20:58:43 +0000
commit517d5ea128541f868946990e21071ec00b31b3e1 (patch)
treea9aa37874ad17019bc74115ecbdc15bbfd4f12b5 /test/CodeGen/attr-target-mv.c
parent5c8a5adf223266707b1c8f8d1d32baf9ef3797db (diff)
downloadclang-517d5ea128541f868946990e21071ec00b31b3e1.tar.gz
Correct 'target' default behavior on redecl, allow forward declaration.
Declarations without the attribute were disallowed because it would be ambiguous which 'target' it was supposed to be on. For example: void ___attribute__((target("v1"))) foo(); void foo(); // Redecl of above, or fwd decl of below? void ___attribute__((target("v2"))) foo(); However, a first declaration doesn't have that problem, and erroring prevents it from working in cases where the forward declaration is useful. Additionally, a forward declaration of target==default wouldn't properly cause multiversioning, so this patch fixes that. The patch was not split since the 'default' fix would require implementing the same check for that case, followed by undoing the same change for the fwd-decl implementation. Change-Id: I66f2c5bc2477bcd3f7544b9c16c83ece257077b0 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@347805 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGen/attr-target-mv.c')
-rw-r--r--test/CodeGen/attr-target-mv.c53
1 files changed, 52 insertions, 1 deletions
diff --git a/test/CodeGen/attr-target-mv.c b/test/CodeGen/attr-target-mv.c
index f9fbbbd5f0..e22499e292 100644
--- a/test/CodeGen/attr-target-mv.c
+++ b/test/CodeGen/attr-target-mv.c
@@ -35,10 +35,24 @@ void bar4() {
foo_multi(1, 5.0);
}
+int fwd_decl_default(void);
+int __attribute__((target("default"))) fwd_decl_default(void) { return 2; }
+
+int fwd_decl_avx(void);
+int __attribute__((target("avx"))) fwd_decl_avx(void) { return 2; }
+int __attribute__((target("default"))) fwd_decl_avx(void) { return 2; }
+
+void bar5() {
+ fwd_decl_default();
+ fwd_decl_avx();
+}
+
// LINUX: @foo.ifunc = ifunc i32 (), i32 ()* ()* @foo.resolver
// LINUX: @foo_inline.ifunc = ifunc i32 (), i32 ()* ()* @foo_inline.resolver
// LINUX: @foo_decls.ifunc = ifunc void (), void ()* ()* @foo_decls.resolver
// LINUX: @foo_multi.ifunc = ifunc void (i32, double), void (i32, double)* ()* @foo_multi.resolver
+// LINUX: @fwd_decl_default.ifunc = ifunc i32 (), i32 ()* ()* @fwd_decl_default.resolver
+// LINUX: @fwd_decl_avx.ifunc = ifunc i32 (), i32 ()* ()* @fwd_decl_avx.resolver
// LINUX: define i32 @foo.sse4.2()
// LINUX: ret i32 0
@@ -168,8 +182,45 @@ void bar4() {
// WINDOWS: call void @foo_multi(i32 %0, double %1)
// WINDOWS-NEXT: ret void
-// LINUX: declare i32 @foo.arch_sandybridge()
+// LINUX: define i32 @fwd_decl_default()
+// LINUX: ret i32 2
+// LINUX: define i32 @fwd_decl_avx.avx()
+// LINUX: ret i32 2
+// LINUX: define i32 @fwd_decl_avx()
+// LINUX: ret i32 2
+// WINDOWS: define dso_local i32 @fwd_decl_default()
+// WINDOWS: ret i32 2
+// WINDOWS: define dso_local i32 @fwd_decl_avx.avx()
+// WINDOWS: ret i32 2
+// WINDOWS: define dso_local i32 @fwd_decl_avx()
+// WINDOWS: ret i32 2
+
+// LINUX: define void @bar5()
+// LINUX: call i32 @fwd_decl_default.ifunc()
+// LINUX: call i32 @fwd_decl_avx.ifunc()
+
+// WINDOWS: define dso_local void @bar5()
+// WINDOWS: call i32 @fwd_decl_default.resolver()
+// WINDOWS: call i32 @fwd_decl_avx.resolver()
+
+// LINUX: define i32 ()* @fwd_decl_default.resolver() comdat
+// LINUX: call void @__cpu_indicator_init()
+// LINUX: ret i32 ()* @fwd_decl_default
+// LINUX: define i32 ()* @fwd_decl_avx.resolver() comdat
+// LINUX: call void @__cpu_indicator_init()
+// LINUX: ret i32 ()* @fwd_decl_avx.avx
+// LINUX: ret i32 ()* @fwd_decl_avx
+
+// WINDOWS: define dso_local i32 @fwd_decl_default.resolver() comdat
+// WINDOWS: call void @__cpu_indicator_init()
+// WINDOWS: call i32 @fwd_decl_default
+// WINDOWS: define dso_local i32 @fwd_decl_avx.resolver() comdat
+// WINDOWS: call void @__cpu_indicator_init()
+// WINDOWS: call i32 @fwd_decl_avx.avx
+// WINDOWS: call i32 @fwd_decl_avx
+
+// LINUX: declare i32 @foo.arch_sandybridge()
// WINDOWS: declare dso_local i32 @foo.arch_sandybridge()
// LINUX: define linkonce i32 @foo_inline.sse4.2()