1 // RUN: %clang_cc1 -w -fblocks -ffreestanding -triple i386-pc-linux-gnu -emit-llvm -o - %s | FileCheck %s
2 // RUN: %clang_cc1 -w -fblocks -ffreestanding -triple i386-pc-linux-gnu -target-feature +avx -emit-llvm -o - %s | FileCheck %s
3 // RUN: %clang_cc1 -w -fblocks -ffreestanding -triple i386-pc-linux-gnu -target-feature +avx512f -emit-llvm -o - %s | FileCheck %s
4 
5 #include <immintrin.h>
6 
7 // CHECK-LABEL: define dso_local void @testm128
8 // CHECK-LABEL: %argp.cur = load i8*, i8** %args, align 4
9 // CHECK-NEXT:  %0 = ptrtoint i8* %argp.cur to i32
10 // CHECK-NEXT:  %1 = add i32 %0, 15
11 // CHECK-NEXT:  %2 = and i32 %1, -16
12 // CHECK-NEXT:  %argp.cur.aligned = inttoptr i32 %2 to i8*
13 void testm128(int argCount, ...) {
14   __m128 res;
15   __builtin_va_list args;
16   __builtin_va_start(args, argCount);
17   res = __builtin_va_arg(args, __m128);
18   __builtin_va_end(args);
19 }
20 
21 // CHECK-LABEL: define dso_local void @testm256
22 // CHECK-LABEL: %argp.cur = load i8*, i8** %args, align 4
23 // CHECK-NEXT:  %0 = ptrtoint i8* %argp.cur to i32
24 // CHECK-NEXT:  %1 = add i32 %0, 31
25 // CHECK-NEXT:  %2 = and i32 %1, -32
26 // CHECK-NEXT:  %argp.cur.aligned = inttoptr i32 %2 to i8*
27 void testm256(int argCount, ...) {
28   __m256 res;
29   __builtin_va_list args;
30   __builtin_va_start(args, argCount);
31   res = __builtin_va_arg(args, __m256);
32   __builtin_va_end(args);
33 }
34 
35 // CHECK-LABEL: define dso_local void @testm512
36 // CHECK-LABEL: %argp.cur = load i8*, i8** %args, align 4
37 // CHECK-NEXT:  %0 = ptrtoint i8* %argp.cur to i32
38 // CHECK-NEXT:  %1 = add i32 %0, 63
39 // CHECK-NEXT:  %2 = and i32 %1, -64
40 // CHECK-NEXT:  %argp.cur.aligned = inttoptr i32 %2 to i8*
41 void testm512(int argCount, ...) {
42   __m512 res;
43   __builtin_va_list args;
44   __builtin_va_start(args, argCount);
45   res = __builtin_va_arg(args, __m512);
46   __builtin_va_end(args);
47 }
48 
49 // CHECK-LABEL: define dso_local void @testPastArguments
50 // CHECK: call void (i32, ...) @testm128(i32 1, <4 x float> %0)
51 // CHECK: call void (i32, ...) @testm256(i32 1, <8 x float> %1)
52 // CHECK: call void (i32, ...) @testm512(i32 1, <16 x float> %2)
53 void testPastArguments(void) {
54   __m128 a;
55   __m256 b;
56   __m512 c;
57   testm128(1, a);
58   testm256(1, b);
59   testm512(1, c);
60 }
61