| // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6 |
| // RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=ITANIUM,LINUX |
| // RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-macos -emit-llvm %s -o - | FileCheck %s --check-prefixes=ITANIUM,DARWIN |
| // RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS |
| |
| |
| // Aliases for ifuncs |
| |
| // Overloaded ifuncs |
| // struct 'C' ifuncs, note the 'float, U' one doesn't get one. |
| |
| // |
| int __attribute__((target_clones("sse4.2", "default"))) overloaded(int) { return 1; } |
| |
| |
| // |
| int __attribute__((target_clones("arch=ivybridge", "default"))) overloaded(const char *) { return 2; } |
| |
| |
| // LINUX-LABEL: define dso_local void @_Z14use_overloadedv( |
| // LINUX-SAME: ) #[[ATTR1:[0-9]+]] { |
| // LINUX-NEXT: [[ENTRY:.*:]] |
| // LINUX-NEXT: [[CALL:%.*]] = call noundef i32 @_Z10overloadedi(i32 noundef 1) |
| // LINUX-NEXT: [[CALL1:%.*]] = call noundef i32 @_Z10overloadedPKc(ptr noundef null) |
| // LINUX-NEXT: ret void |
| // |
| // DARWIN-LABEL: define void @_Z14use_overloadedv( |
| // DARWIN-SAME: ) #[[ATTR1:[0-9]+]] { |
| // DARWIN-NEXT: [[ENTRY:.*:]] |
| // DARWIN-NEXT: [[CALL:%.*]] = call noundef i32 @_Z10overloadedi(i32 noundef 1) |
| // DARWIN-NEXT: [[CALL1:%.*]] = call noundef i32 @_Z10overloadedPKc(ptr noundef null) |
| // DARWIN-NEXT: ret void |
| // |
| void use_overloaded() { |
| overloaded(1); |
| overloaded(nullptr); |
| } |
| |
| template<typename T, typename U> |
| struct C { |
| int __attribute__((target_clones("sse4.2", "default"))) foo(){ return 1;} |
| }; |
| template<typename U> |
| struct C<int, U> { |
| int __attribute__((target_clones("sse4.2", "default"))) foo(){ return 2;} |
| }; |
| template<typename U> |
| struct C<float, U> { |
| int foo(){ return 2;} |
| }; |
| template<> |
| // |
| struct C<double, float> { |
| int __attribute__((target_clones("sse4.2", "default"))) foo(){ return 3;} |
| }; |
| |
| // LINUX-LABEL: define dso_local void @_Z16uses_specializedv( |
| // LINUX-SAME: ) #[[ATTR1]] { |
| // LINUX-NEXT: [[ENTRY:.*:]] |
| // LINUX-NEXT: [[C:%.*]] = alloca [[STRUCT_C:%.*]], align 1 |
| // LINUX-NEXT: [[C2:%.*]] = alloca [[STRUCT_C_0:%.*]], align 1 |
| // LINUX-NEXT: [[C3:%.*]] = alloca [[STRUCT_C_1:%.*]], align 1 |
| // LINUX-NEXT: [[C4:%.*]] = alloca [[STRUCT_C_2:%.*]], align 1 |
| // LINUX-NEXT: [[CALL:%.*]] = call noundef i32 @_ZN1CIssE3fooEv(ptr noundef nonnull align 1 dereferenceable(1) [[C]]) |
| // LINUX-NEXT: [[CALL1:%.*]] = call noundef i32 @_ZN1CIisE3fooEv(ptr noundef nonnull align 1 dereferenceable(1) [[C2]]) |
| // LINUX-NEXT: [[CALL2:%.*]] = call noundef i32 @_ZN1CIfsE3fooEv(ptr noundef nonnull align 1 dereferenceable(1) [[C3]]) |
| // LINUX-NEXT: [[CALL3:%.*]] = call noundef i32 @_ZN1CIdfE3fooEv(ptr noundef nonnull align 1 dereferenceable(1) [[C4]]) |
| // LINUX-NEXT: ret void |
| // |
| // DARWIN-LABEL: define void @_Z16uses_specializedv( |
| // DARWIN-SAME: ) #[[ATTR1]] { |
| // DARWIN-NEXT: [[ENTRY:.*:]] |
| // DARWIN-NEXT: [[C:%.*]] = alloca [[STRUCT_C:%.*]], align 1 |
| // DARWIN-NEXT: [[C2:%.*]] = alloca [[STRUCT_C_0:%.*]], align 1 |
| // DARWIN-NEXT: [[C3:%.*]] = alloca [[STRUCT_C_1:%.*]], align 1 |
| // DARWIN-NEXT: [[C4:%.*]] = alloca [[STRUCT_C_2:%.*]], align 1 |
| // DARWIN-NEXT: [[CALL:%.*]] = call noundef i32 @_ZN1CIssE3fooEv(ptr noundef nonnull align 1 dereferenceable(1) [[C]]) |
| // DARWIN-NEXT: [[CALL1:%.*]] = call noundef i32 @_ZN1CIisE3fooEv(ptr noundef nonnull align 1 dereferenceable(1) [[C2]]) |
| // DARWIN-NEXT: [[CALL2:%.*]] = call noundef i32 @_ZN1CIfsE3fooEv(ptr noundef nonnull align 1 dereferenceable(1) [[C3]]) |
| // DARWIN-NEXT: [[CALL3:%.*]] = call noundef i32 @_ZN1CIdfE3fooEv(ptr noundef nonnull align 1 dereferenceable(1) [[C4]]) |
| // DARWIN-NEXT: ret void |
| // |
| void uses_specialized() { |
| C<short, short> c; |
| c.foo(); |
| C<int, short> c2; |
| c2.foo(); |
| C<float, short> c3; |
| c3.foo(); |
| // Note this is not an ifunc/mv |
| C<double, float> c4; |
| c4.foo(); |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| //// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: |
| // ITANIUM: {{.*}} |
| // WINDOWS: {{.*}} |