1 // RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
2 
3 // rdar://problem/9246208
4 
5 // Basic test.
6 namespace 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 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.
28 namespace 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 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.
51 namespace 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 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.
79 namespace 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 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.
98 namespace test5 {
99   struct A {
100     A();
101   };
102 
103   typedef A elt;
104 
105   // CHECK:    define [[A:%.*]]* @_ZN5test54testEi(i32
106   // CHECK:      [[N:%.*]] = load i32, 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 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.
117 namespace 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 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.
139 namespace 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 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.
162 namespace 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, 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 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.
187 namespace 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, 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 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