• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | \
2 // RUN:   FileCheck %s -check-prefix=CHECK -check-prefix=SSE -check-prefix=NO-AVX512
3 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -target-feature +avx | \
4 // RUN:   FileCheck %s -check-prefix=CHECK -check-prefix=AVX -check-prefix=NO-AVX512
5 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -target-feature +avx512f | \
6 // RUN:   FileCheck %s -check-prefix=CHECK -check-prefix=AVX -check-prefix=AVX512
7 #include <stdarg.h>
8 
9 // CHECK-LABEL: define signext i8 @f0()
f0(void)10 char f0(void) {
11   return 0;
12 }
13 
14 // CHECK-LABEL: define signext i16 @f1()
f1(void)15 short f1(void) {
16   return 0;
17 }
18 
19 // CHECK-LABEL: define i32 @f2()
f2(void)20 int f2(void) {
21   return 0;
22 }
23 
24 // CHECK-LABEL: define float @f3()
f3(void)25 float f3(void) {
26   return 0;
27 }
28 
29 // CHECK-LABEL: define double @f4()
f4(void)30 double f4(void) {
31   return 0;
32 }
33 
34 // CHECK-LABEL: define x86_fp80 @f5()
f5(void)35 long double f5(void) {
36   return 0;
37 }
38 
39 // CHECK-LABEL: define void @f6(i8 signext %a0, i16 signext %a1, i32 %a2, i64 %a3, i8* %a4)
f6(char a0,short a1,int a2,long long a3,void * a4)40 void f6(char a0, short a1, int a2, long long a3, void *a4) {
41 }
42 
43 // CHECK-LABEL: define void @f7(i32 %a0)
44 typedef enum { A, B, C } e7;
f7(e7 a0)45 void f7(e7 a0) {
46 }
47 
48 // Test merging/passing of upper eightbyte with X87 class.
49 //
50 // CHECK-LABEL: define void @f8_1(%union.u8* noalias sret %agg.result)
51 // CHECK-LABEL: define void @f8_2(%union.u8* byval align 16 %a0)
52 union u8 {
53   long double a;
54   int b;
55 };
f8_1()56 union u8 f8_1() { while (1) {} }
f8_2(union u8 a0)57 void f8_2(union u8 a0) {}
58 
59 // CHECK-LABEL: define i64 @f9()
f9(void)60 struct s9 { int a; int b; int : 0; } f9(void) { while (1) {} }
61 
62 // CHECK-LABEL: define void @f10(i64 %a0.coerce)
63 struct s10 { int a; int b; int : 0; };
f10(struct s10 a0)64 void f10(struct s10 a0) {}
65 
66 // CHECK-LABEL: define void @f11(%union.anon* noalias sret %agg.result)
f11()67 union { long double a; float b; } f11() { while (1) {} }
68 
69 // CHECK-LABEL: define i32 @f12_0()
70 // CHECK-LABEL: define void @f12_1(i32 %a0.coerce)
71 struct s12 { int a __attribute__((aligned(16))); };
f12_0(void)72 struct s12 f12_0(void) { while (1) {} }
f12_1(struct s12 a0)73 void f12_1(struct s12 a0) {}
74 
75 // Check that sret parameter is accounted for when checking available integer
76 // registers.
77 // CHECK: define void @f13(%struct.s13_0* noalias sret %agg.result, i32 %a, i32 %b, i32 %c, i32 %d, {{.*}}* byval align 8 %e, i32 %f)
78 
79 struct s13_0 { long long f0[3]; };
80 struct s13_1 { long long f0[2]; };
f13(int a,int b,int c,int d,struct s13_1 e,int f)81 struct s13_0 f13(int a, int b, int c, int d,
82                  struct s13_1 e, int f) { while (1) {} }
83 
84 // CHECK: define void @f14({{.*}}, i8 signext %X)
f14(int a,int b,int c,int d,int e,int f,char X)85 void f14(int a, int b, int c, int d, int e, int f, char X) {}
86 
87 // CHECK: define void @f15({{.*}}, i8* %X)
f15(int a,int b,int c,int d,int e,int f,void * X)88 void f15(int a, int b, int c, int d, int e, int f, void *X) {}
89 
90 // CHECK: define void @f16({{.*}}, float %X)
f16(float a,float b,float c,float d,float e,float f,float g,float h,float X)91 void f16(float a, float b, float c, float d, float e, float f, float g, float h,
92          float X) {}
93 
94 // CHECK: define void @f17({{.*}}, x86_fp80 %X)
f17(float a,float b,float c,float d,float e,float f,float g,float h,long double X)95 void f17(float a, float b, float c, float d, float e, float f, float g, float h,
96          long double X) {}
97 
98 // Check for valid coercion.  The struct should be passed/returned as i32, not
99 // as i64 for better code quality.
100 // rdar://8135035
101 // CHECK-LABEL: define void @f18(i32 %a, i32 %f18_arg1.coerce)
102 struct f18_s0 { int f0; };
f18(int a,struct f18_s0 f18_arg1)103 void f18(int a, struct f18_s0 f18_arg1) { while (1) {} }
104 
105 // Check byval alignment.
106 
107 // CHECK-LABEL: define void @f19(%struct.s19* byval align 16 %x)
108 struct s19 {
109   long double a;
110 };
f19(struct s19 x)111 void f19(struct s19 x) {}
112 
113 // CHECK-LABEL: define void @f20(%struct.s20* byval align 32 %x)
114 struct __attribute__((aligned(32))) s20 {
115   int x;
116   int y;
117 };
f20(struct s20 x)118 void f20(struct s20 x) {}
119 
120 struct StringRef {
121   long x;
122   const char *Ptr;
123 };
124 
125 // rdar://7375902
126 // CHECK-LABEL: define i8* @f21(i64 %S.coerce0, i8* %S.coerce1)
f21(struct StringRef S)127 const char *f21(struct StringRef S) { return S.x+S.Ptr; }
128 
129 // PR7567
130 typedef __attribute__ ((aligned(16))) struct f22s { unsigned long long x[2]; } L;
f22(L x,L y)131 void f22(L x, L y) { }
132 // CHECK: @f22
133 // CHECK: %x = alloca{{.*}}, align 16
134 // CHECK: %y = alloca{{.*}}, align 16
135 
136 
137 
138 // PR7714
139 struct f23S {
140   short f0;
141   unsigned f1;
142   int f2;
143 };
144 
145 
f23(int A,struct f23S B)146 void f23(int A, struct f23S B) {
147   // CHECK-LABEL: define void @f23(i32 %A, i64 %B.coerce0, i32 %B.coerce1)
148 }
149 
150 struct f24s { long a; int b; };
151 
f24(struct f23S * X,struct f24s * P2)152 struct f23S f24(struct f23S *X, struct f24s *P2) {
153   return *X;
154 
155   // CHECK: define { i64, i32 } @f24(%struct.f23S* %X, %struct.f24s* %P2)
156 }
157 
158 // rdar://8248065
159 typedef float v4f32 __attribute__((__vector_size__(16)));
f25(v4f32 X)160 v4f32 f25(v4f32 X) {
161   // CHECK-LABEL: define <4 x float> @f25(<4 x float> %X)
162   // CHECK-NOT: alloca
163   // CHECK: alloca <4 x float>
164   // CHECK-NOT: alloca
165   // CHECK: store <4 x float> %X, <4 x float>*
166   // CHECK-NOT: store
167   // CHECK: ret <4 x float>
168   return X+X;
169 }
170 
171 struct foo26 {
172   int *X;
173   float *Y;
174 };
175 
f26(struct foo26 * P)176 struct foo26 f26(struct foo26 *P) {
177   // CHECK: define { i32*, float* } @f26(%struct.foo26* %P)
178   return *P;
179 }
180 
181 
182 struct v4f32wrapper {
183   v4f32 v;
184 };
185 
f27(struct v4f32wrapper X)186 struct v4f32wrapper f27(struct v4f32wrapper X) {
187   // CHECK-LABEL: define <4 x float> @f27(<4 x float> %X.coerce)
188   return X;
189 }
190 
191 // PR22563 - We should unwrap simple structs and arrays to pass
192 // and return them in the appropriate vector registers if possible.
193 
194 typedef float v8f32 __attribute__((__vector_size__(32)));
195 struct v8f32wrapper {
196   v8f32 v;
197 };
198 
f27a(struct v8f32wrapper X)199 struct v8f32wrapper f27a(struct v8f32wrapper X) {
200   // AVX-LABEL: define <8 x float> @f27a(<8 x float> %X.coerce)
201   return X;
202 }
203 
204 struct v8f32wrapper_wrapper {
205   v8f32 v[1];
206 };
207 
f27b(struct v8f32wrapper_wrapper X)208 struct v8f32wrapper_wrapper f27b(struct v8f32wrapper_wrapper X) {
209   // AVX-LABEL: define <8 x float> @f27b(<8 x float> %X.coerce)
210   return X;
211 }
212 
213 // rdar://5711709
214 struct f28c {
215   double x;
216   int y;
217 };
f28(struct f28c C)218 void f28(struct f28c C) {
219   // CHECK-LABEL: define void @f28(double %C.coerce0, i32 %C.coerce1)
220 }
221 
222 struct f29a {
223   struct c {
224     double x;
225     int y;
226   } x[1];
227 };
228 
f29a(struct f29a A)229 void f29a(struct f29a A) {
230   // CHECK-LABEL: define void @f29a(double %A.coerce0, i32 %A.coerce1)
231 }
232 
233 // rdar://8249586
234 struct S0 { char f0[8]; char f2; char f3; char f4; };
f30(struct S0 p_4)235 void f30(struct S0 p_4) {
236   // CHECK-LABEL: define void @f30(i64 %p_4.coerce0, i24 %p_4.coerce1)
237 }
238 
239 // Pass the third element as a float when followed by tail padding.
240 // rdar://8251384
241 struct f31foo { float a, b, c; };
f31(struct f31foo X)242 float f31(struct f31foo X) {
243   // CHECK-LABEL: define float @f31(<2 x float> %X.coerce0, float %X.coerce1)
244   return X.c;
245 }
246 
f32(_Complex float A,_Complex float B)247 _Complex float f32(_Complex float A, _Complex float B) {
248   // rdar://6379669
249   // CHECK-LABEL: define <2 x float> @f32(<2 x float> %A.coerce, <2 x float> %B.coerce)
250   return A+B;
251 }
252 
253 
254 // rdar://8357396
255 struct f33s { long x; float c,d; };
256 
f33(va_list X)257 void f33(va_list X) {
258   va_arg(X, struct f33s);
259 }
260 
261 typedef unsigned long long v1i64 __attribute__((__vector_size__(8)));
262 
263 // rdar://8359248
264 // CHECK-LABEL: define double @f34(double %arg.coerce)
f34(v1i64 arg)265 v1i64 f34(v1i64 arg) { return arg; }
266 
267 
268 // rdar://8358475
269 // CHECK-LABEL: define double @f35(double %arg.coerce)
270 typedef unsigned long v1i64_2 __attribute__((__vector_size__(8)));
f35(v1i64_2 arg)271 v1i64_2 f35(v1i64_2 arg) { return arg+arg; }
272 
273 // rdar://9122143
274 // CHECK: declare void @func(%struct._str* byval align 16)
275 typedef struct _str {
276   union {
277     long double a;
278     long c;
279   };
280 } str;
281 
282 void func(str s);
283 str ss;
f9122143()284 void f9122143()
285 {
286   func(ss);
287 }
288 
289 // CHECK-LABEL: define double @f36(double %arg.coerce)
290 typedef unsigned v2i32 __attribute((__vector_size__(8)));
f36(v2i32 arg)291 v2i32 f36(v2i32 arg) { return arg; }
292 
293 // AVX: declare void @f38(<8 x float>)
294 // AVX: declare void @f37(<8 x float>)
295 // SSE: declare void @f38(%struct.s256* byval align 32)
296 // SSE: declare void @f37(<8 x float>* byval align 32)
297 typedef float __m256 __attribute__ ((__vector_size__ (32)));
298 typedef struct {
299   __m256 m;
300 } s256;
301 
302 s256 x38;
303 __m256 x37;
304 
305 void f38(s256 x);
306 void f37(__m256 x);
f39()307 void f39() { f38(x38); f37(x37); }
308 
309 // The two next tests make sure that the struct below is passed
310 // in the same way regardless of avx being used
311 
312 // CHECK: declare void @func40(%struct.t128* byval align 16)
313 typedef float __m128 __attribute__ ((__vector_size__ (16)));
314 typedef struct t128 {
315   __m128 m;
316   __m128 n;
317 } two128;
318 
319 extern void func40(two128 s);
func41(two128 s)320 void func41(two128 s) {
321   func40(s);
322 }
323 
324 // CHECK: declare void @func42(%struct.t128_2* byval align 16)
325 typedef struct xxx {
326   __m128 array[2];
327 } Atwo128;
328 typedef struct t128_2 {
329   Atwo128 x;
330 } SA;
331 
332 extern void func42(SA s);
func43(SA s)333 void func43(SA s) {
334   func42(s);
335 }
336 
337 // CHECK-LABEL: define i32 @f44
338 // CHECK: ptrtoint
339 // CHECK-NEXT: add i64 %{{[0-9]+}}, 31
340 // CHECK-NEXT: and i64 %{{[0-9]+}}, -32
341 // CHECK-NEXT: inttoptr
342 typedef int T44 __attribute((vector_size(32)));
343 struct s44 { T44 x; int y; };
f44(int i,...)344 int f44(int i, ...) {
345   __builtin_va_list ap;
346   __builtin_va_start(ap, i);
347   struct s44 s = __builtin_va_arg(ap, struct s44);
348   __builtin_va_end(ap);
349   return s.y;
350 }
351 
352 // Text that vec3 returns the correct LLVM IR type.
353 // AVX-LABEL: define i32 @foo(<3 x i64> %X)
354 typedef long long3 __attribute((ext_vector_type(3)));
foo(long3 X)355 int foo(long3 X)
356 {
357   return 0;
358 }
359 
360 // Make sure we don't use a varargs convention for a function without a
361 // prototype where AVX types are involved.
362 // AVX: @test45
363 // AVX: call i32 bitcast (i32 (...)* @f45 to i32 (<8 x float>)*)
364 int f45();
365 __m256 x45;
test45()366 void test45() { f45(x45); }
367 
368 // Make sure we use byval to pass 64-bit vectors in memory; the LLVM call
369 // lowering can't handle this case correctly because it runs after legalization.
370 // CHECK: @test46
371 // CHECK: call void @f46({{.*}}<2 x float>* byval align 8 {{.*}}, <2 x float>* byval align 8 {{.*}})
372 typedef float v46 __attribute((vector_size(8)));
373 void f46(v46,v46,v46,v46,v46,v46,v46,v46,v46,v46);
test46()374 void test46() { v46 x = {1,2}; f46(x,x,x,x,x,x,x,x,x,x); }
375 
376 // Check that we pass the struct below without using byval, which helps out
377 // codegen.
378 //
379 // CHECK: @test47
380 // CHECK: call void @f47(i32 {{.*}}, i32 {{.*}}, i32 {{.*}}, i32 {{.*}}, i32 {{.*}}, i32 {{.*}}, i32 {{.*}})
381 struct s47 { unsigned a; };
382 void f47(int,int,int,int,int,int,struct s47);
test47(int a,struct s47 b)383 void test47(int a, struct s47 b) { f47(a, a, a, a, a, a, b); }
384 
385 // rdar://12723368
386 // In the following example, there are holes in T4 at the 3rd byte and the 4th
387 // byte, however, T2 does not have those holes. T4 is chosen to be the
388 // representing type for union T1, but we can't use load or store of T4 since
389 // it will skip the 3rd byte and the 4th byte.
390 // In general, Since we don't accurately represent the data fields of a union,
391 // do not use load or store of the representing llvm type for the union.
392 typedef _Complex int T2;
393 typedef _Complex char T5;
394 typedef _Complex int T7;
395 typedef struct T4 { T5 field0; T7 field1; } T4;
396 typedef union T1 { T2 field0; T4 field1; } T1;
397 extern T1 T1_retval;
test48(void)398 T1 test48(void) {
399 // CHECK: @test48
400 // CHECK: memcpy
401 // CHECK: memcpy
402   return T1_retval;
403 }
404 
405 void test49_helper(double, ...);
test49(double d,double e)406 void test49(double d, double e) {
407   test49_helper(d, e);
408 }
409 // CHECK-LABEL:    define void @test49(
410 // CHECK:      [[T0:%.*]] = load double, double*
411 // CHECK-NEXT: [[T1:%.*]] = load double, double*
412 // CHECK-NEXT: call void (double, ...) @test49_helper(double [[T0]], double [[T1]])
413 
414 void test50_helper();
test50(double d,double e)415 void test50(double d, double e) {
416   test50_helper(d, e);
417 }
418 // CHECK-LABEL:    define void @test50(
419 // CHECK:      [[T0:%.*]] = load double, double*
420 // CHECK-NEXT: [[T1:%.*]] = load double, double*
421 // CHECK-NEXT: call void (double, double, ...) bitcast (void (...)* @test50_helper to void (double, double, ...)*)(double [[T0]], double [[T1]])
422 
423 struct test51_s { __uint128_t intval; };
test51(struct test51_s * s,__builtin_va_list argList)424 void test51(struct test51_s *s, __builtin_va_list argList) {
425     *s = __builtin_va_arg(argList, struct test51_s);
426 }
427 
428 // CHECK-LABEL: define void @test51
429 // CHECK: [[TMP_ADDR:%.*]] = alloca [[STRUCT_TEST51:%.*]], align 16
430 // CHECK: br i1
431 // CHECK: [[REG_SAVE_AREA_PTR:%.*]] = getelementptr inbounds {{.*}}, i32 0, i32 3
432 // CHECK-NEXT: [[REG_SAVE_AREA:%.*]] = load i8*, i8** [[REG_SAVE_AREA_PTR]]
433 // CHECK-NEXT: [[VALUE_ADDR:%.*]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i32 {{.*}}
434 // CHECK-NEXT: [[CASTED_VALUE_ADDR:%.*]] = bitcast i8* [[VALUE_ADDR]] to [[STRUCT_TEST51]]
435 // CHECK-NEXT: [[CASTED_TMP_ADDR:%.*]] = bitcast [[STRUCT_TEST51]]* [[TMP_ADDR]] to i8*
436 // CHECK-NEXT: [[RECASTED_VALUE_ADDR:%.*]] = bitcast [[STRUCT_TEST51]]* [[CASTED_VALUE_ADDR]] to i8*
437 // CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[CASTED_TMP_ADDR]], i8* [[RECASTED_VALUE_ADDR]], i64 16, i32 8, i1 false)
438 // CHECK-NEXT: add i32 {{.*}}, 16
439 // CHECK-NEXT: store i32 {{.*}}, i32* {{.*}}
440 // CHECK-NEXT: br label
441 
442 void test52_helper(int, ...);
443 __m256 x52;
test52()444 void test52() {
445   test52_helper(0, x52, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0i);
446 }
447 // AVX: @test52_helper(i32 0, <8 x float> {{%[a-zA-Z0-9]+}}, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double {{%[a-zA-Z0-9]+}}, double {{%[a-zA-Z0-9]+}})
448 
test53(__m256 * m,__builtin_va_list argList)449 void test53(__m256 *m, __builtin_va_list argList) {
450   *m = __builtin_va_arg(argList, __m256);
451 }
452 // AVX-LABEL: define void @test53
453 // AVX-NOT: br i1
454 // AVX: ret void
455 
456 void test54_helper(__m256, ...);
457 __m256 x54;
test54()458 void test54() {
459   test54_helper(x54, x54, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0i);
460   test54_helper(x54, x54, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0i);
461 }
462 // AVX: @test54_helper(<8 x float> {{%[a-zA-Z0-9]+}}, <8 x float> {{%[a-zA-Z0-9]+}}, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double {{%[a-zA-Z0-9]+}}, double {{%[a-zA-Z0-9]+}})
463 // AVX: @test54_helper(<8 x float> {{%[a-zA-Z0-9]+}}, <8 x float> {{%[a-zA-Z0-9]+}}, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, { double, double }* byval align 8 {{%[a-zA-Z0-9]+}})
464 
465 typedef float __m512 __attribute__ ((__vector_size__ (64)));
466 typedef struct {
467   __m512 m;
468 } s512;
469 
470 s512 x55;
471 __m512 x56;
472 
473 // Even on AVX512, aggregates of size larger than four eightbytes have class
474 // MEMORY (AVX512 draft 0.3 3.2.3p2 Rule 1).
475 //
476 // CHECK: declare void @f55(%struct.s512* byval align 64)
477 void f55(s512 x);
478 
479 // However, __m512 has type SSE/SSEUP on AVX512.
480 //
481 // AVX512: declare void @f56(<16 x float>)
482 // NO-AVX512: declare void @f56(<16 x float>* byval align 64)
483 void f56(__m512 x);
f57()484 void f57() { f55(x55); f56(x56); }
485 
486 // Like for __m128 on AVX, check that the struct below is passed
487 // in the same way regardless of AVX512 being used.
488 //
489 // CHECK: declare void @f58(%struct.t256* byval align 32)
490 typedef struct t256 {
491   __m256 m;
492   __m256 n;
493 } two256;
494 
495 extern void f58(two256 s);
f59(two256 s)496 void f59(two256 s) {
497   f58(s);
498 }
499 
500 // CHECK: declare void @f60(%struct.sat256* byval align 32)
501 typedef struct at256 {
502   __m256 array[2];
503 } Atwo256;
504 typedef struct sat256 {
505   Atwo256 x;
506 } SAtwo256;
507 
508 extern void f60(SAtwo256 s);
f61(SAtwo256 s)509 void f61(SAtwo256 s) {
510   f60(s);
511 }
512 
513 // AVX512: @f62_helper(i32 0, <16 x float> {{%[a-zA-Z0-9]+}}, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double {{%[a-zA-Z0-9]+}}, double {{%[a-zA-Z0-9]+}})
514 void f62_helper(int, ...);
515 __m512 x62;
f62()516 void f62() {
517   f62_helper(0, x62, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0i);
518 }
519 
520 // Like for __m256 on AVX, we always pass __m512 in memory, and don't
521 // need to use the register save area.
522 //
523 // AVX512-LABEL: define void @f63
524 // AVX512-NOT: br i1
525 // AVX512: ret void
f63(__m512 * m,__builtin_va_list argList)526 void f63(__m512 *m, __builtin_va_list argList) {
527   *m = __builtin_va_arg(argList, __m512);
528 }
529 
530 // AVX512: @f64_helper(<16 x float> {{%[a-zA-Z0-9]+}}, <16 x float> {{%[a-zA-Z0-9]+}}, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double {{%[a-zA-Z0-9]+}}, double {{%[a-zA-Z0-9]+}})
531 // AVX512: @f64_helper(<16 x float> {{%[a-zA-Z0-9]+}}, <16 x float> {{%[a-zA-Z0-9]+}}, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, { double, double }* byval align 8 {{%[a-zA-Z0-9]+}})
532 void f64_helper(__m512, ...);
533 __m512 x64;
f64()534 void f64() {
535   f64_helper(x64, x64, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0i);
536   f64_helper(x64, x64, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0i);
537 }
538