1 // RUN: %clang_cc1 -emit-llvm %s -triple x86_64-unknown-linux-gnu -o - | FileCheck %s 2 3 bool bar(); 4 void f(bool, bool); 5 void g(bool); 6 7 static int baz(int x) { 8 return x * 10; 9 } 10 11 [[clang::noinline]] bool noi() { return true; } 12 [[msvc::noinline]] bool ms_noi() { return true; } 13 14 void foo(int i) { 15 [[clang::noinline]] bar(); 16 // CHECK: call noundef zeroext i1 @_Z3barv() #[[NOINLINEATTR:[0-9]+]] 17 [[clang::noinline]] i = baz(i); 18 // CHECK: call noundef i32 @_ZL3bazi({{.*}}) #[[NOINLINEATTR]] 19 [[clang::noinline]] (i = 4, bar()); 20 // CHECK: call noundef zeroext i1 @_Z3barv() #[[NOINLINEATTR]] 21 [[clang::noinline]] (void)(bar()); 22 // CHECK: call noundef zeroext i1 @_Z3barv() #[[NOINLINEATTR]] 23 [[clang::noinline]] f(bar(), bar()); 24 // CHECK: call noundef zeroext i1 @_Z3barv() #[[NOINLINEATTR]] 25 // CHECK: call noundef zeroext i1 @_Z3barv() #[[NOINLINEATTR]] 26 // CHECK: call void @_Z1fbb({{.*}}) #[[NOINLINEATTR]] 27 [[clang::noinline]] [] { bar(); bar(); }(); // noinline only applies to the anonymous function call 28 // CHECK: call void @"_ZZ3fooiENK3$_0clEv"(ptr {{[^,]*}} %ref.tmp) #[[NOINLINEATTR]] 29 [[clang::noinline]] for (bar(); bar(); bar()) {} 30 // CHECK: call noundef zeroext i1 @_Z3barv() #[[NOINLINEATTR]] 31 // CHECK: call noundef zeroext i1 @_Z3barv() #[[NOINLINEATTR]] 32 // CHECK: call noundef zeroext i1 @_Z3barv() #[[NOINLINEATTR]] 33 bar(); 34 // CHECK: call noundef zeroext i1 @_Z3barv() 35 [[clang::noinline]] noi(); 36 // CHECK: call noundef zeroext i1 @_Z3noiv() 37 noi(); 38 // CHECK: call noundef zeroext i1 @_Z3noiv() 39 [[gnu::noinline]] bar(); 40 // CHECK: call noundef zeroext i1 @_Z3barv() 41 } 42 43 void ms_noi_check(int i) { 44 [[msvc::noinline]] bar(); 45 // CHECK: call noundef zeroext i1 @_Z3barv() #[[NOINLINEATTR:[0-9]+]] 46 [[msvc::noinline]] i = baz(i); 47 // CHECK: call noundef i32 @_ZL3bazi({{.*}}) #[[NOINLINEATTR]] 48 [[msvc::noinline]] (i = 4, bar()); 49 // CHECK: call noundef zeroext i1 @_Z3barv() #[[NOINLINEATTR]] 50 [[msvc::noinline]] (void)(bar()); 51 // CHECK: call noundef zeroext i1 @_Z3barv() #[[NOINLINEATTR]] 52 [[msvc::noinline]] f(bar(), bar()); 53 // CHECK: call noundef zeroext i1 @_Z3barv() #[[NOINLINEATTR]] 54 // CHECK: call noundef zeroext i1 @_Z3barv() #[[NOINLINEATTR]] 55 // CHECK: call void @_Z1fbb({{.*}}) #[[NOINLINEATTR]] 56 [[msvc::noinline]] [] { bar(); bar(); }(); // noinline only applies to the anonymous function call 57 // CHECK: call void @"_ZZ12ms_noi_checkiENK3$_0clEv"(ptr {{[^,]*}} %ref.tmp) #[[NOINLINEATTR]] 58 [[msvc::noinline]] for (bar(); bar(); bar()) {} 59 // CHECK: call noundef zeroext i1 @_Z3barv() #[[NOINLINEATTR]] 60 // CHECK: call noundef zeroext i1 @_Z3barv() #[[NOINLINEATTR]] 61 // CHECK: call noundef zeroext i1 @_Z3barv() #[[NOINLINEATTR]] 62 [[msvc::noinline]] ms_noi(); 63 // CHECK: call noundef zeroext i1 @_Z6ms_noiv() 64 ms_noi(); 65 // CHECK: call noundef zeroext i1 @_Z6ms_noiv() 66 } 67 68 struct S { 69 friend bool operator==(const S &LHS, const S &RHS); 70 }; 71 72 void func(const S &s1, const S &s2) { 73 [[clang::noinline]]g(s1 == s2); 74 // CHECK: call noundef zeroext i1 @_ZeqRK1SS1_({{.*}}) #[[NOINLINEATTR]] 75 // CHECK: call void @_Z1gb({{.*}}) #[[NOINLINEATTR]] 76 bool b; 77 [[clang::noinline]] b = s1 == s2; 78 // CHECK: call noundef zeroext i1 @_ZeqRK1SS1_({{.*}}) #[[NOINLINEATTR]] 79 80 [[msvc::noinline]]g(s1 == s2); 81 // CHECK: call noundef zeroext i1 @_ZeqRK1SS1_({{.*}}) #[[NOINLINEATTR]] 82 // CHECK: call void @_Z1gb({{.*}}) #[[NOINLINEATTR]] 83 [[msvc::noinline]] b = s1 == s2; 84 // CHECK: call noundef zeroext i1 @_ZeqRK1SS1_({{.*}}) #[[NOINLINEATTR]] 85 } 86 87 // CHECK: attributes #[[NOINLINEATTR]] = { noinline } 88