summaryrefslogtreecommitdiffstats
path: root/clang/test/CodeGenCXX/temp-order.cpp
blob: 9f3dde7c5d9e230cdec69b121d910cf0e8d7a89b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Output file should have no calls to error() with folding.
// RUN: clang-cc -triple i386-unknown-unknown -O3 -emit-llvm -o %t %s
// RUN: FileCheck %s < %t

static unsigned pow(unsigned Base, unsigned Power) {
  unsigned Val = 1;
  while (Power--)
    Val *= Base;
  return Val;
}

struct TempTracker {
  unsigned Product, Index;

  TempTracker() : Product(1), Index(0) {}

};

// FIXME: This can be used to check elision as well, if P = 0 hacks are removed.
struct A {
  TempTracker &TT;
  mutable unsigned P;
  bool Truth;

  A(TempTracker &_TT, unsigned _P, bool _Truth = true)
    : TT(_TT), P(_P), Truth(_Truth) {}
  A(const A &RHS) : TT(RHS.TT), P(RHS.P), Truth(RHS.Truth) { RHS.P = 0; }
  ~A() {
    if (P)
      TT.Product *= pow(P, ++TT.Index);
  }

  operator bool () { return Truth; }
};

// 3, 7, 2
static unsigned f0(bool val = false) {
  TempTracker tt;
  {
    A a(tt, 2);
    if ((A(tt, 3), val))
      A b(tt, 5);
    A c(tt, 7);
  }
  return tt.Product;
}

// 3, 5, 7, 2
static unsigned f1(bool val = true) {
  TempTracker tt;
  {
    A a(tt, 2);
    if ((A(tt, 3), val))
      A b(tt, 5);
    A c(tt, 7);
  }
  return tt.Product;
}

// 5, 3, 7, 2
static unsigned f2() {
  TempTracker tt;
  {
    A a(tt, 2);
    if (A b = A(tt, 3))
      A c(tt, 5);
    A d(tt, 7);
  }
  return tt.Product;
}

// 7, 3, 11, 2
static unsigned f3() {
  TempTracker tt;
  {
    A a(tt, 2);
    if (A b = A(tt, 3, false))
      A c(tt, 5);
    else
      A c(tt, 7);
    A d(tt, 11);
  }
  return tt.Product;
}

extern "C" void error();
extern "C" void print(const char *Name, unsigned N);

#define ORDER3(a, b, c) (pow(a, 1) * pow(b, 2) * pow(c, 3))
#define ORDER4(a, b, c, d) (ORDER3(a, b, c) * pow(d, 4))
void test() {
// CHECK: call void @print(i8* {{.*}}, i32 1176)
  print("f0", f0());
  if (f0() != ORDER3(3, 7, 2))
    error();

// CHECK: call void @print(i8* {{.*}}, i32 411600)
  print("f1", f1());
  if (f1() != ORDER4(3, 5, 7, 2))
    error();

// CHECK: call void @print(i8* {{.*}}, i32 246960)
  print("f2", f2());
  if (f2() != ORDER4(5, 3, 7, 2))
    error();

// CHECK: call void @print(i8* {{.*}}, i32 1341648)
  print("f3", f3());
  if (f3() != ORDER4(7, 3, 11, 2))
    error();
}



#ifdef HARNESS

#include <cstdlib>
#include <cstdio>

extern "C" void error() {
  abort();
}

extern "C" void print(const char *name, unsigned N) {
  printf("%s: %d\n", name, N);
}

int main() {
  test();
  return 0;
}

#endif
OpenPOWER on IntegriCloud