libcxx

libcxx mirror with random patches
git clone https://git.neptards.moe/neptards/libcxx.git
Log | Files | Refs

donotoptimize_assembly_test.cc (4308B)


      1 #include <benchmark/benchmark.h>
      2 
      3 #ifdef __clang__
      4 #pragma clang diagnostic ignored "-Wreturn-type"
      5 #endif
      6 
      7 extern "C" {
      8 
      9 extern int ExternInt;
     10 extern int ExternInt2;
     11 extern int ExternInt3;
     12 
     13 inline int Add42(int x) { return x + 42; }
     14 
     15 struct NotTriviallyCopyable {
     16   NotTriviallyCopyable();
     17   explicit NotTriviallyCopyable(int x) : value(x) {}
     18   NotTriviallyCopyable(NotTriviallyCopyable const&);
     19   int value;
     20 };
     21 
     22 struct Large {
     23   int value;
     24   int data[2];
     25 };
     26 
     27 }
     28 // CHECK-LABEL: test_with_rvalue:
     29 extern "C" void test_with_rvalue() {
     30   benchmark::DoNotOptimize(Add42(0));
     31   // CHECK: movl $42, %eax
     32   // CHECK: ret
     33 }
     34 
     35 // CHECK-LABEL: test_with_large_rvalue:
     36 extern "C" void test_with_large_rvalue() {
     37   benchmark::DoNotOptimize(Large{ExternInt, {ExternInt, ExternInt}});
     38   // CHECK: ExternInt(%rip)
     39   // CHECK: movl %eax, -{{[0-9]+}}(%[[REG:[a-z]+]]
     40   // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]])
     41   // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]])
     42   // CHECK: ret
     43 }
     44 
     45 // CHECK-LABEL: test_with_non_trivial_rvalue:
     46 extern "C" void test_with_non_trivial_rvalue() {
     47   benchmark::DoNotOptimize(NotTriviallyCopyable(ExternInt));
     48   // CHECK: mov{{l|q}} ExternInt(%rip)
     49   // CHECK: ret
     50 }
     51 
     52 // CHECK-LABEL: test_with_lvalue:
     53 extern "C" void test_with_lvalue() {
     54   int x = 101;
     55   benchmark::DoNotOptimize(x);
     56   // CHECK-GNU: movl $101, %eax
     57   // CHECK-CLANG: movl $101, -{{[0-9]+}}(%[[REG:[a-z]+]])
     58   // CHECK: ret
     59 }
     60 
     61 // CHECK-LABEL: test_with_large_lvalue:
     62 extern "C" void test_with_large_lvalue() {
     63   Large L{ExternInt, {ExternInt, ExternInt}};
     64   benchmark::DoNotOptimize(L);
     65   // CHECK: ExternInt(%rip)
     66   // CHECK: movl %eax, -{{[0-9]+}}(%[[REG:[a-z]+]])
     67   // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]])
     68   // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]])
     69   // CHECK: ret
     70 }
     71 
     72 // CHECK-LABEL: test_with_non_trivial_lvalue:
     73 extern "C" void test_with_non_trivial_lvalue() {
     74   NotTriviallyCopyable NTC(ExternInt);
     75   benchmark::DoNotOptimize(NTC);
     76   // CHECK: ExternInt(%rip)
     77   // CHECK: movl %eax, -{{[0-9]+}}(%[[REG:[a-z]+]])
     78   // CHECK: ret
     79 }
     80 
     81 // CHECK-LABEL: test_with_const_lvalue:
     82 extern "C" void test_with_const_lvalue() {
     83   const int x = 123;
     84   benchmark::DoNotOptimize(x);
     85   // CHECK: movl $123, %eax
     86   // CHECK: ret
     87 }
     88 
     89 // CHECK-LABEL: test_with_large_const_lvalue:
     90 extern "C" void test_with_large_const_lvalue() {
     91   const Large L{ExternInt, {ExternInt, ExternInt}};
     92   benchmark::DoNotOptimize(L);
     93   // CHECK: ExternInt(%rip)
     94   // CHECK: movl %eax, -{{[0-9]+}}(%[[REG:[a-z]+]])
     95   // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]])
     96   // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]])
     97   // CHECK: ret
     98 }
     99 
    100 // CHECK-LABEL: test_with_non_trivial_const_lvalue:
    101 extern "C" void test_with_non_trivial_const_lvalue() {
    102   const NotTriviallyCopyable Obj(ExternInt);
    103   benchmark::DoNotOptimize(Obj);
    104   // CHECK: mov{{q|l}} ExternInt(%rip)
    105   // CHECK: ret
    106 }
    107 
    108 // CHECK-LABEL: test_div_by_two:
    109 extern "C" int test_div_by_two(int input) {
    110   int divisor = 2;
    111   benchmark::DoNotOptimize(divisor);
    112   return input / divisor;
    113   // CHECK: movl $2, [[DEST:.*]]
    114   // CHECK: idivl [[DEST]]
    115   // CHECK: ret
    116 }
    117 
    118 // CHECK-LABEL: test_inc_integer:
    119 extern "C" int test_inc_integer() {
    120   int x = 0;
    121   for (int i=0; i < 5; ++i)
    122     benchmark::DoNotOptimize(++x);
    123   // CHECK: movl $1, [[DEST:.*]]
    124   // CHECK: {{(addl \$1,|incl)}} [[DEST]]
    125   // CHECK: {{(addl \$1,|incl)}} [[DEST]]
    126   // CHECK: {{(addl \$1,|incl)}} [[DEST]]
    127   // CHECK: {{(addl \$1,|incl)}} [[DEST]]
    128   // CHECK-CLANG: movl [[DEST]], %eax
    129   // CHECK: ret
    130   return x;
    131 }
    132 
    133 // CHECK-LABEL: test_pointer_rvalue
    134 extern "C" void test_pointer_rvalue() {
    135   // CHECK: movl $42, [[DEST:.*]]
    136   // CHECK: leaq [[DEST]], %rax
    137   // CHECK-CLANG: movq %rax, -{{[0-9]+}}(%[[REG:[a-z]+]])
    138   // CHECK: ret
    139   int x = 42;
    140   benchmark::DoNotOptimize(&x);
    141 }
    142 
    143 // CHECK-LABEL: test_pointer_const_lvalue:
    144 extern "C" void test_pointer_const_lvalue() {
    145   // CHECK: movl $42, [[DEST:.*]]
    146   // CHECK: leaq [[DEST]], %rax
    147   // CHECK-CLANG: movq %rax, -{{[0-9]+}}(%[[REG:[a-z]+]])
    148   // CHECK: ret
    149   int x = 42;
    150   int * const xp = &x;
    151   benchmark::DoNotOptimize(xp);
    152 }
    153 
    154 // CHECK-LABEL: test_pointer_lvalue:
    155 extern "C" void test_pointer_lvalue() {
    156   // CHECK: movl $42, [[DEST:.*]]
    157   // CHECK: leaq [[DEST]], %rax
    158   // CHECK-CLANG: movq %rax, -{{[0-9]+}}(%[[REG:[a-z+]+]])
    159   // CHECK: ret
    160   int x = 42;
    161   int *xp = &x;
    162   benchmark::DoNotOptimize(xp);
    163 }