1 | // RUN: %clang_cc1 -std=c++11 -triple i686-windows-msvc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS |
2 | // RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-msvc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS64 |
3 | |
4 | struct Foo { |
5 | Foo(); |
6 | Foo(const Foo &o); |
7 | ~Foo(); |
8 | int x; |
9 | }; |
10 | int __attribute__((target("default"))) bar(Foo o) { return o.x; } |
11 | int __attribute__((target("sse4.2"))) bar(Foo o) { return o.x + 1; } |
12 | int __attribute__((target("arch=ivybridge"))) bar(Foo o) { return o.x + 2; } |
13 | |
14 | void usage() { |
15 | Foo f; |
16 | bar(f); |
17 | } |
18 | |
19 | // WINDOWS: define dso_local i32 @"?bar@@YAHUFoo@@@Z"(<{ %struct.Foo }>* inalloca) |
20 | // WINDOWS: %[[O:[0-9a-zA-Z]+]] = getelementptr inbounds <{ %struct.Foo }>, <{ %struct.Foo }>* %0, i32 0, i32 0 |
21 | // WINDOWS: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds %struct.Foo, %struct.Foo* %[[O]], i32 0, i32 0 |
22 | // WINDOWS: %[[LOAD:[0-9a-zA-Z]+]] = load i32, i32* %[[X]] |
23 | // WINDOWS: ret i32 %[[LOAD]] |
24 | |
25 | // WINDOWS: define dso_local i32 @"?bar@@YAHUFoo@@@Z.sse4.2"(<{ %struct.Foo }>* inalloca) |
26 | // WINDOWS: %[[O:[0-9a-zA-Z]+]] = getelementptr inbounds <{ %struct.Foo }>, <{ %struct.Foo }>* %0, i32 0, i32 0 |
27 | // WINDOWS: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds %struct.Foo, %struct.Foo* %[[O]], i32 0, i32 0 |
28 | // WINDOWS: %[[LOAD:[0-9a-zA-Z]+]] = load i32, i32* %[[X]] |
29 | // WINDOWS: %[[ADD:[0-9a-zA-Z]+]] = add nsw i32 %[[LOAD]], 1 |
30 | // WINDOWS: ret i32 %[[ADD]] |
31 | |
32 | // WINDOWS: define dso_local i32 @"?bar@@YAHUFoo@@@Z.arch_ivybridge"(<{ %struct.Foo }>* inalloca) |
33 | // WINDOWS: %[[O:[0-9a-zA-Z]+]] = getelementptr inbounds <{ %struct.Foo }>, <{ %struct.Foo }>* %0, i32 0, i32 0 |
34 | // WINDOWS: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds %struct.Foo, %struct.Foo* %[[O]], i32 0, i32 0 |
35 | // WINDOWS: %[[LOAD:[0-9a-zA-Z]+]] = load i32, i32* %[[X]] |
36 | // WINDOWS: %[[ADD:[0-9a-zA-Z]+]] = add nsw i32 %[[LOAD]], 2 |
37 | // WINDOWS: ret i32 %[[ADD]] |
38 | |
39 | // WINDOWS: define dso_local void @"?usage@@YAXXZ"() |
40 | // WINDOWS: %[[F:[0-9a-zA-Z]+]] = alloca %struct.Foo |
41 | // WINDOWS: %[[ARGMEM:[0-9a-zA-Z]+]] = alloca inalloca <{ %struct.Foo }> |
42 | // WINDOWS: %[[CALL:[0-9a-zA-Z]+]] = call i32 @"?bar@@YAHUFoo@@@Z.resolver"(<{ %struct.Foo }>* inalloca %[[ARGMEM]]) |
43 | |
44 | // WINDOWS: define dso_local i32 @"?bar@@YAHUFoo@@@Z.resolver"(<{ %struct.Foo }>*) |
45 | // WINDOWS: %[[RET:[0-9a-zA-Z]+]] = musttail call i32 @"?bar@@YAHUFoo@@@Z.arch_ivybridge"(<{ %struct.Foo }>* %0) |
46 | // WINDOWS-NEXT: ret i32 %[[RET]] |
47 | // WINDOWS: %[[RET:[0-9a-zA-Z]+]] = musttail call i32 @"?bar@@YAHUFoo@@@Z.sse4.2"(<{ %struct.Foo }>* %0) |
48 | // WINDOWS-NEXT: ret i32 %[[RET]] |
49 | // WINDOWS: %[[RET:[0-9a-zA-Z]+]] = musttail call i32 @"?bar@@YAHUFoo@@@Z"(<{ %struct.Foo }>* %0) |
50 | // WINDOWS-NEXT: ret i32 %[[RET]] |
51 | |
52 | |
53 | // WINDOWS64: define dso_local i32 @"?bar@@YAHUFoo@@@Z"(%struct.Foo* %[[O:[0-9a-zA-Z]+]]) |
54 | // WINDOWS64: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds %struct.Foo, %struct.Foo* %[[O]], i32 0, i32 0 |
55 | // WINDOWS64: %[[LOAD:[0-9a-zA-Z]+]] = load i32, i32* %[[X]] |
56 | // WINDOWS64: ret i32 %[[LOAD]] |
57 | |
58 | // WINDOWS64: define dso_local i32 @"?bar@@YAHUFoo@@@Z.sse4.2"(%struct.Foo* %[[O:[0-9a-zA-Z]+]]) |
59 | // WINDOWS64: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds %struct.Foo, %struct.Foo* %[[O]], i32 0, i32 0 |
60 | // WINDOWS64: %[[LOAD:[0-9a-zA-Z]+]] = load i32, i32* %[[X]] |
61 | // WINDOWS64: %[[ADD:[0-9a-zA-Z]+]] = add nsw i32 %[[LOAD]], 1 |
62 | // WINDOWS64: ret i32 %[[ADD]] |
63 | |
64 | // WINDOWS64: define dso_local i32 @"?bar@@YAHUFoo@@@Z.arch_ivybridge"(%struct.Foo* %[[O:[0-9a-zA-Z]+]]) |
65 | // WINDOWS64: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds %struct.Foo, %struct.Foo* %[[O]], i32 0, i32 0 |
66 | // WINDOWS64: %[[LOAD:[0-9a-zA-Z]+]] = load i32, i32* %[[X]] |
67 | // WINDOWS64: %[[ADD:[0-9a-zA-Z]+]] = add nsw i32 %[[LOAD]], 2 |
68 | // WINDOWS64: ret i32 %[[ADD]] |
69 | |
70 | // WINDOWS64: define dso_local void @"?usage@@YAXXZ"() |
71 | // WINDOWS64: %[[F:[0-9a-zA-Z]+]] = alloca %struct.Foo |
72 | // WINDOWS64: %[[ARG:[0-9a-zA-Z.]+]] = alloca %struct.Foo |
73 | // WINDOWS64: %[[CALL:[0-9a-zA-Z]+]] = call i32 @"?bar@@YAHUFoo@@@Z.resolver"(%struct.Foo* %[[ARG]]) |
74 | |
75 | // WINDOWS64: define dso_local i32 @"?bar@@YAHUFoo@@@Z.resolver"(%struct.Foo*) |
76 | // WINDOWS64: %[[RET:[0-9a-zA-Z]+]] = musttail call i32 @"?bar@@YAHUFoo@@@Z.arch_ivybridge"(%struct.Foo* %0) |
77 | // WINDOWS64-NEXT: ret i32 %[[RET]] |
78 | // WINDOWS64: %[[RET:[0-9a-zA-Z]+]] = musttail call i32 @"?bar@@YAHUFoo@@@Z.sse4.2"(%struct.Foo* %0) |
79 | // WINDOWS64-NEXT: ret i32 %[[RET]] |
80 | // WINDOWS64: %[[RET:[0-9a-zA-Z]+]] = musttail call i32 @"?bar@@YAHUFoo@@@Z"(%struct.Foo* %0) |
81 | // WINDOWS64-NEXT: ret i32 %[[RET]] |
82 | |