xref: /llvm-project/clang/test/CodeGen/hexagon-linux-vararg.c (revision ab7dba233a058cc8310ef829929238b5d8440b30)
1 // REQUIRES: hexagon-registered-target
2 // RUN: %clang_cc1 -emit-llvm -triple hexagon-unknown-linux-musl %s -o - | FileCheck %s
3 #include <stdarg.h>
4 
5 struct AAA {
6   int x;
7   int y;
8   int z;
9   int d;
10 };
11 
12 // CHECK:   call void @llvm.va_start.p0(ptr %arraydecay)
13 // CHECK:   %arraydecay1 = getelementptr inbounds [1 x %struct.__va_list_tag],
14 // ptr %ap, i32 0, i32 0
15 // CHECK:   br label %vaarg.maybe_reg
16 
17 // CHECK: vaarg.maybe_reg:                                  ; preds = %entry
18 // CHECK:   %__current_saved_reg_area_pointer_p = getelementptr inbounds
19 // %struct.__va_list_tag, ptr %arraydecay2, i32 0, i32 0
20 // CHECK:   %__current_saved_reg_area_pointer = load ptr, ptr
21 // %__current_saved_reg_area_pointer_p
22 // CHECK:   %__saved_reg_area_end_pointer_p = getelementptr inbounds
23 // %struct.__va_list_tag, ptr %arraydecay2, i32 0, i32 1
24 // CHECK:   %__saved_reg_area_end_pointer = load ptr, ptr
25 // %__saved_reg_area_end_pointer_p
26 // CHECK:   %__new_saved_reg_area_pointer = getelementptr i8, ptr
27 // %__current_saved_reg_area_pointer, i32 4
28 // CHECK:   %0 = icmp sgt ptr %__new_saved_reg_area_pointer,
29 // %__saved_reg_area_end_pointer
30 // CHECK:   br i1 %0, label %vaarg.on_stack, label %vaarg.in_reg
31 
32 // CHECK: vaarg.in_reg:                                     ; preds =
33 // %vaarg.maybe_reg
34 // CHECK:   store ptr %__new_saved_reg_area_pointer, ptr
35 // %__current_saved_reg_area_pointer_p
36 // CHECK:   br label %vaarg.end
37 
38 // CHECK: vaarg.on_stack:                                   ; preds =
39 // %vaarg.maybe_reg
40 // CHECK:   %__overflow_area_pointer_p = getelementptr inbounds
41 // %struct.__va_list_tag, ptr %arraydecay2, i32 0, i32 2
42 // CHECK:   %__overflow_area_pointer = load ptr, ptr %__overflow_area_pointer_p
43 // CHECK:   %__overflow_area_pointer.next = getelementptr i8, ptr
44 // %__overflow_area_pointer, i32 4
45 // CHECK:   store ptr %__overflow_area_pointer.next, ptr
46 // %__overflow_area_pointer_p
47 // CHECK:   store ptr %__overflow_area_pointer.next, ptr
48 // %__current_saved_reg_area_pointer_p
49 // CHECK:   br label %vaarg.end
50 
51 // CHECK: vaarg.end:                                        ; preds =
52 // %vaarg.on_stack, %vaarg.in_reg
53 // CHECK:   %vaarg.addr = phi ptr [ %__current_saved_reg_area_pointer, %vaarg.in_reg ], [ %__overflow_area_pointer, %vaarg.on_stack
54 // ]
55 // CHECK:   %1 = load i32, ptr %vaarg.addr
56 
57 struct AAA aaa = {100, 200, 300, 400};
58 
foo(int xx,...)59 int foo(int xx, ...) {
60   va_list ap;
61   int d;
62   int ret = 0;
63   struct AAA bbb;
64   va_start(ap, xx);
65   d = va_arg(ap, int);
66   ret += d;
67   bbb = va_arg(ap, struct AAA);
68   ret += bbb.d;
69   d = va_arg(ap, int);
70   ret += d;
71   va_end(ap);
72   return ret;
73 }
74 
main(void)75 int main(void) {
76   int x;
77   x = foo(1, 2, aaa, 4);
78   return x;
79 }
80