1// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
2
3// rdar://problem/9246208
4
5// Basic test.
6namespace test0 {
7  struct A {
8    A();
9    int x;
10  };
11
12  typedef A elt;
13
14  // CHECK:    define [[A:%.*]]* @_ZN5test04testEs(i16 signext
15  // CHECK:      [[N:%.*]] = sext i16 {{%.*}} to i32
16  // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 4)
17  // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
18  // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
19  // CHECK-NEXT: [[T3:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
20  // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T3]])
21  // CHECK:      getelementptr inbounds {{.*}}, i32 [[N]]
22  elt *test(short s) {
23    return new elt[s];
24  }
25}
26
27// test0 with a nested array.
28namespace test1 {
29  struct A {
30    A();
31    int x;
32  };
33
34  typedef A elt[100];
35
36  // CHECK:    define [100 x [[A:%.*]]]* @_ZN5test14testEs(i16 signext
37  // CHECK:      [[N:%.*]] = sext i16 {{%.*}} to i32
38  // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 400)
39  // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
40  // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
41  // CHECK-NEXT: [[T3:%.*]] = mul i32 [[N]], 100
42  // CHECK-NEXT: [[T4:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
43  // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T4]])
44  // CHECK:      getelementptr inbounds {{.*}}, i32 [[T3]]
45  elt *test(short s) {
46    return new elt[s];
47  }
48}
49
50// test1 with an array cookie.
51namespace test2 {
52  struct A {
53    A();
54    ~A();
55    int x;
56  };
57
58  typedef A elt[100];
59
60  // CHECK:    define [100 x [[A:%.*]]]* @_ZN5test24testEs(i16 signext
61  // CHECK:      [[N:%.*]] = sext i16 {{%.*}} to i32
62  // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 400)
63  // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
64  // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
65  // CHECK-NEXT: [[T3:%.*]] = mul i32 [[N]], 100
66  // CHECK-NEXT: [[T4:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T2]], i32 4)
67  // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T4]], 1
68  // CHECK-NEXT: [[T6:%.*]] = or i1 [[T1]], [[T5]]
69  // CHECK-NEXT: [[T7:%.*]] = extractvalue { i32, i1 } [[T4]], 0
70  // CHECK-NEXT: [[T8:%.*]] = select i1 [[T6]], i32 -1, i32 [[T7]]
71  // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T8]])
72  // CHECK:      getelementptr inbounds {{.*}}, i32 [[T3]]
73  elt *test(short s) {
74    return new elt[s];
75  }
76}
77
78// test0 with a 1-byte element.
79namespace test4 {
80  struct A {
81    A();
82  };
83
84  typedef A elt;
85
86  // CHECK:    define [[A:%.*]]* @_ZN5test44testEs(i16 signext
87  // CHECK:      [[N:%.*]] = sext i16 {{%.*}} to i32
88  // CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[N]], 0
89  // CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 -1, i32 [[N]]
90  // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T1]])
91  // CHECK:      getelementptr inbounds {{.*}}, i32 [[N]]
92  elt *test(short s) {
93    return new elt[s];
94  }
95}
96
97// test4 with no sext required.
98namespace test5 {
99  struct A {
100    A();
101  };
102
103  typedef A elt;
104
105  // CHECK:    define [[A:%.*]]* @_ZN5test54testEi(i32
106  // CHECK:      [[N:%.*]] = load i32*
107  // CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[N]], 0
108  // CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 -1, i32 [[N]]
109  // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T1]])
110  // CHECK:      getelementptr inbounds {{.*}}, i32 [[N]]
111  elt *test(int s) {
112    return new elt[s];
113  }
114}
115
116// test0 with an unsigned size.
117namespace test6 {
118  struct A {
119    A();
120    int x;
121  };
122
123  typedef A elt;
124
125  // CHECK:    define [[A:%.*]]* @_ZN5test64testEt(i16 zeroext
126  // CHECK:      [[N:%.*]] = zext i16 {{%.*}} to i32
127  // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 4)
128  // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
129  // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
130  // CHECK-NEXT: [[T3:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
131  // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T3]])
132  // CHECK:      getelementptr inbounds {{.*}}, i32 [[N]]
133  elt *test(unsigned short s) {
134    return new elt[s];
135  }
136}
137
138// test1 with an unsigned size.
139namespace test7 {
140  struct A {
141    A();
142    int x;
143  };
144
145  typedef A elt[100];
146
147  // CHECK:    define [100 x [[A:%.*]]]* @_ZN5test74testEt(i16 zeroext
148  // CHECK:      [[N:%.*]] = zext i16 {{%.*}} to i32
149  // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 400)
150  // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
151  // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
152  // CHECK-NEXT: [[T3:%.*]] = mul i32 [[N]], 100
153  // CHECK-NEXT: [[T4:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
154  // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T4]])
155  // CHECK:      getelementptr inbounds {{.*}}, i32 [[T3]]
156  elt *test(unsigned short s) {
157    return new elt[s];
158  }
159}
160
161// test0 with a signed type larger than size_t.
162namespace test8 {
163  struct A {
164    A();
165    int x;
166  };
167
168  typedef A elt;
169
170  // CHECK:    define [[A:%.*]]* @_ZN5test84testEx(i64
171  // CHECK:      [[N:%.*]] = load i64*
172  // CHECK-NEXT: [[T0:%.*]] = icmp uge i64 [[N]], 4294967296
173  // CHECK-NEXT: [[T1:%.*]] = trunc i64 [[N]] to i32
174  // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[T1]], i32 4)
175  // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 1
176  // CHECK-NEXT: [[T4:%.*]] = or i1 [[T0]], [[T3]]
177  // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T2]], 0
178  // CHECK-NEXT: [[T6:%.*]] = select i1 [[T4]], i32 -1, i32 [[T5]]
179  // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T6]])
180  // CHECK:      getelementptr inbounds {{.*}}, i32 [[T1]]
181  elt *test(long long s) {
182    return new elt[s];
183  }
184}
185
186// test8 with an unsigned type.
187namespace test9 {
188  struct A {
189    A();
190    int x;
191  };
192
193  typedef A elt;
194
195  // CHECK:    define [[A:%.*]]* @_ZN5test94testEy(i64
196  // CHECK:      [[N:%.*]] = load i64*
197  // CHECK-NEXT: [[T0:%.*]] = icmp uge i64 [[N]], 4294967296
198  // CHECK-NEXT: [[T1:%.*]] = trunc i64 [[N]] to i32
199  // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[T1]], i32 4)
200  // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 1
201  // CHECK-NEXT: [[T4:%.*]] = or i1 [[T0]], [[T3]]
202  // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T2]], 0
203  // CHECK-NEXT: [[T6:%.*]] = select i1 [[T4]], i32 -1, i32 [[T5]]
204  // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T6]])
205  // CHECK:      getelementptr inbounds {{.*}}, i32 [[T1]]
206  elt *test(unsigned long long s) {
207    return new elt[s];
208  }
209}
210