1176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// RUN: %clang_cc1 -triple mips-unknown-linux -o - -O1 -emit-llvm %s | FileCheck %s -check-prefix=ALL -check-prefix=O32
2176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// RUN: %clang_cc1 -triple mipsel-unknown-linux -o - -O1 -emit-llvm %s | FileCheck %s -check-prefix=ALL -check-prefix=O32
3176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// RUN: %clang_cc1 -triple mips64-unknown-linux -o - -O1 -emit-llvm  -target-abi n32 %s | FileCheck %s -check-prefix=ALL -check-prefix=N32 -check-prefix=NEW
4176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// RUN: %clang_cc1 -triple mips64-unknown-linux -o - -O1 -emit-llvm  -target-abi n32 %s | FileCheck %s -check-prefix=ALL -check-prefix=N32 -check-prefix=NEW
5176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// RUN: %clang_cc1 -triple mips64-unknown-linux -o - -O1 -emit-llvm %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NEW
6176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// RUN: %clang_cc1 -triple mips64el-unknown-linux -o - -O1 -emit-llvm %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NEW
7176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
8176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#include <stdarg.h>
9176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
10176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinestypedef int v4i32 __attribute__ ((__vector_size__ (16)));
11176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
12176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesint test_i32(char *fmt, ...) {
13176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  va_list va;
14176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
15176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  va_start(va, fmt);
16176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  int v = va_arg(va, int);
17176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  va_end(va);
18176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
19176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  return v;
20176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
21176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
22176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL-LABEL: define i32 @test_i32(i8*{{.*}} %fmt, ...)
23176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
24176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// O32:   %va = alloca i8*, align [[PTRALIGN:4]]
25176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// N32:   %va = alloca i8*, align [[PTRALIGN:4]]
26176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// N64:   %va = alloca i8*, align [[PTRALIGN:8]]
27176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
28176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL:   [[VA1:%.+]] = bitcast i8** %va to i8*
29176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL:   call void @llvm.va_start(i8* [[VA1]])
30176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
31176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// O32:   [[TMP0:%.+]] = bitcast i8** %va to i32**
323ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// O32:   [[AP_CUR:%.+]] = load i32*, i32** [[TMP0]], align [[PTRALIGN]]
33176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// NEW:   [[TMP0:%.+]] = bitcast i8** %va to i64**
343ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// NEW:   [[AP_CUR:%.+]] = load i64*, i64** [[TMP0]], align [[PTRALIGN]]
35176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
363ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// O32:   [[AP_NEXT:%.+]] = getelementptr i32, i32* [[AP_CUR]], i32 1
373ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// NEW:   [[AP_NEXT:%.+]] = getelementptr i64, i64* [[AP_CUR]], {{i32|i64}} 1
38176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
390e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// O32:   store i32* [[AP_NEXT]], i32** [[TMP0]], align [[PTRALIGN]]
400e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// NEW:   store i64* [[AP_NEXT]], i64** [[TMP0]], align [[PTRALIGN]]
41176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
423ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// O32:   [[ARG1:%.+]] = load i32, i32* [[AP_CUR]], align 4
433ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// NEW:   [[TMP2:%.+]] = load i64, i64* [[AP_CUR]], align 8
44176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// NEW:   [[ARG1:%.+]] = trunc i64 [[TMP2]] to i32
45176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
46176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL:   call void @llvm.va_end(i8* [[VA1]])
47176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL:   ret i32 [[ARG1]]
48176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL: }
49176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
50176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesint test_i32_2args(char *fmt, ...) {
51176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  va_list va;
52176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
53176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  va_start(va, fmt);
54176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  int v1 = va_arg(va, int);
55176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  int v2 = va_arg(va, int);
56176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  va_end(va);
57176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
58176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  return v1 + v2;
59176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
60176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
61176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL-LABEL: define i32 @test_i32_2args(i8*{{.*}} %fmt, ...)
62176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
63176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL:   %va = alloca i8*, align [[PTRALIGN]]
64176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL:   [[VA1:%.+]] = bitcast i8** %va to i8*
65176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL:   call void @llvm.va_start(i8* [[VA1]])
66176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
67176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// O32:   [[TMP0:%.+]] = bitcast i8** %va to i32**
683ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// O32:   [[AP_CUR:%.+]] = load i32*, i32** [[TMP0]], align [[PTRALIGN]]
69176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// NEW:   [[TMP0:%.+]] = bitcast i8** %va to i64**
703ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// NEW:   [[AP_CUR:%.+]] = load i64*, i64** [[TMP0]], align [[PTRALIGN]]
71176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
723ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// O32:   [[AP_NEXT1:%.+]] = getelementptr i32, i32* [[AP_CUR]], i32 1
733ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// NEW:   [[AP_NEXT1:%.+]] = getelementptr i64, i64* [[AP_CUR]], [[INTPTR_T:i32|i64]] 1
74176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
750e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// O32:   store i32* [[AP_NEXT1]], i32** [[TMP0]], align [[PTRALIGN]]
76176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// FIXME: N32 optimised this store out. Why only for this ABI?
770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// N64:   store i64* [[AP_NEXT1]], i64** [[TMP0]], align [[PTRALIGN]]
78176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
793ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// O32:   [[ARG1:%.+]] = load i32, i32* [[AP_CUR]], align 4
803ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// NEW:   [[TMP3:%.+]] = load i64, i64* [[AP_CUR]], align 8
81176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// NEW:   [[ARG1:%.+]] = trunc i64 [[TMP3]] to i32
82176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
833ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// O32:   [[AP_NEXT2:%.+]] = getelementptr i32, i32* [[AP_CUR]], i32 2
843ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// NEW:   [[AP_NEXT2:%.+]] = getelementptr i64, i64* [[AP_CUR]], [[INTPTR_T]] 2
85176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
860e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// O32:   store i32* [[AP_NEXT2]], i32** [[TMP0]], align [[PTRALIGN]]
870e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// NEW:   store i64* [[AP_NEXT2]], i64** [[TMP0]], align [[PTRALIGN]]
88176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
893ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// O32:   [[ARG2:%.+]] = load i32, i32* [[AP_NEXT1]], align 4
903ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// NEW:   [[TMP4:%.+]] = load i64, i64* [[AP_NEXT1]], align 8
91176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// NEW:   [[ARG2:%.+]] = trunc i64 [[TMP4]] to i32
92176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
93176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL:   call void @llvm.va_end(i8* [[VA1]])
94176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL:   [[ADD:%.+]] = add nsw i32 [[ARG2]], [[ARG1]]
95176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL:   ret i32 [[ADD]]
96176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL: }
97176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
98176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hineslong long test_i64(char *fmt, ...) {
99176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  va_list va;
100176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
101176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  va_start(va, fmt);
102176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  long long v = va_arg(va, long long);
103176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  va_end(va);
104176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
105176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  return v;
106176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
107176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
108176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL-LABEL: define i64 @test_i64(i8*{{.*}} %fmt, ...)
109176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
110176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL:   %va = alloca i8*, align [[PTRALIGN]]
111176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL:   [[VA1:%.+]] = bitcast i8** %va to i8*
112176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL:   call void @llvm.va_start(i8* [[VA1]])
113176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
1143ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// O32:   [[AP_CUR:%.+]] = load i8*, i8** %va, align [[PTRALIGN]]
115176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// NEW:   [[TMP0:%.+]] = bitcast i8** %va to i64**
1163ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// NEW:   [[AP_CUR:%.+]] = load i64*, i64** [[TMP0]], align [[PTRALIGN]]
117176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
118176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// i64 is 8-byte aligned, while this is within O32's stack alignment there's no
119176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// guarantee that the offset is still 8-byte aligned after earlier reads.
120176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// O32:   [[PTR0:%.+]] = ptrtoint i8* [[AP_CUR]] to [[INTPTR_T:i32]]
121176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// O32:   [[PTR1:%.+]] = add i32 [[PTR0]], 7
122176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// O32:   [[PTR2:%.+]] = and i32 [[PTR1]], -8
123176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// O32:   [[PTR3:%.+]] = inttoptr [[INTPTR_T]] [[PTR2]] to i64*
124176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// O32:   [[PTR4:%.+]] = inttoptr [[INTPTR_T]] [[PTR2]] to i8*
125176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
1263ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// O32:   [[AP_NEXT:%.+]] = getelementptr i8, i8* [[PTR4]], [[INTPTR_T]] 8
1273ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// NEW:   [[AP_NEXT:%.+]] = getelementptr i64, i64* [[AP_CUR]], [[INTPTR_T:i32|i64]] 1
128176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
1290e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// O32:   store i8* [[AP_NEXT]], i8** %va, align [[PTRALIGN]]
1300e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// NEW:   store i64* [[AP_NEXT]], i64** [[TMP0]], align [[PTRALIGN]]
131176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
1323ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// O32:   [[ARG1:%.+]] = load i64, i64* [[PTR3]], align 8
1333ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// NEW:   [[ARG1:%.+]] = load i64, i64* [[AP_CUR]], align 8
134176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
135176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL:   call void @llvm.va_end(i8* [[VA1]])
136176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL:   ret i64 [[ARG1]]
137176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL: }
138176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1390e2c34f92f00628d48968dfea096d36381f494cbStephen Hineschar *test_ptr(char *fmt, ...) {
1400e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  va_list va;
1410e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
1420e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  va_start(va, fmt);
1430e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  char *v = va_arg(va, char *);
1440e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  va_end(va);
1450e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
1460e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  return v;
1470e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
1480e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
1490e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// ALL-LABEL: define i8* @test_ptr(i8*{{.*}} %fmt, ...)
1500e2c34f92f00628d48968dfea096d36381f494cbStephen Hines//
1510e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// O32:   %va = alloca i8*, align [[PTRALIGN:4]]
1520e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// N32:   %va = alloca i8*, align [[PTRALIGN:4]]
1530e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// N64:   %va = alloca i8*, align [[PTRALIGN:8]]
1540e2c34f92f00628d48968dfea096d36381f494cbStephen Hines//
1550e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// ALL:   [[VA1:%.+]] = bitcast i8** %va to i8*
1560e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// ALL:   call void @llvm.va_start(i8* [[VA1]])
1570e2c34f92f00628d48968dfea096d36381f494cbStephen Hines//
1580e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// O32:   [[TMP0:%.+]] = bitcast i8** %va to i8***
1593ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// O32:   [[AP_CUR:%.+]] = load i8**, i8*** [[TMP0]], align [[PTRALIGN]]
1600e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// N32 differs because the vararg is not a N32 pointer. It's been promoted to 64-bit.
1610e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// N32:   [[TMP0:%.+]] = bitcast i8** %va to i64**
1623ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// N32:   [[AP_CUR:%.+]] = load i64*, i64** [[TMP0]], align [[PTRALIGN]]
1630e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// N64:   [[TMP0:%.+]] = bitcast i8** %va to i8***
1643ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// N64:   [[AP_CUR:%.+]] = load i8**, i8*** [[TMP0]], align [[PTRALIGN]]
1650e2c34f92f00628d48968dfea096d36381f494cbStephen Hines//
1663ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// O32:   [[AP_NEXT:%.+]] = getelementptr i8*, i8** [[AP_CUR]], i32 1
1670e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// N32 differs because the vararg is not a N32 pointer. It's been promoted to 64-bit.
1683ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// N32:   [[AP_NEXT:%.+]] = getelementptr i64, i64* [[AP_CUR]], {{i32|i64}} 1
1693ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// N64:   [[AP_NEXT:%.+]] = getelementptr i8*, i8** [[AP_CUR]], {{i32|i64}} 1
1700e2c34f92f00628d48968dfea096d36381f494cbStephen Hines//
1710e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// O32:   store i8** [[AP_NEXT]], i8*** [[TMP0]], align [[PTRALIGN]]
1720e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// N32 differs because the vararg is not a N32 pointer. It's been promoted to 64-bit.
1730e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// N32:   store i64* [[AP_NEXT]], i64** [[TMP0]], align [[PTRALIGN]]
1740e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// N64:   store i8** [[AP_NEXT]], i8*** [[TMP0]], align [[PTRALIGN]]
1750e2c34f92f00628d48968dfea096d36381f494cbStephen Hines//
1763ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// O32:   [[ARG1:%.+]] = load i8*, i8** [[AP_CUR]], align 4
1770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// N32 differs because the vararg is not a N32 pointer. It's been promoted to
1780e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// 64-bit so we must truncate the excess and bitcast to a N32 pointer.
1793ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// N32:   [[TMP2:%.+]] = load i64, i64* [[AP_CUR]], align 8
1800e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// N32:   [[TMP3:%.+]] = trunc i64 [[TMP2]] to i32
1810e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// N32:   [[ARG1:%.+]] = inttoptr i32 [[TMP3]] to i8*
1823ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// N64:   [[ARG1:%.+]] = load i8*, i8** [[AP_CUR]], align 8
1830e2c34f92f00628d48968dfea096d36381f494cbStephen Hines//
1840e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// ALL:   call void @llvm.va_end(i8* [[VA1]])
1850e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// ALL:   ret i8* [[ARG1]]
1860e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// ALL: }
1870e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
188176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesint test_v4i32(char *fmt, ...) {
189176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  va_list va;
190176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
191176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  va_start(va, fmt);
192176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  v4i32 v = va_arg(va, v4i32);
193176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  va_end(va);
194176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
195176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  return v[0];
196176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
197176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
198176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL-LABEL: define i32 @test_v4i32(i8*{{.*}} %fmt, ...)
199176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
200176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL:   %va = alloca i8*, align [[PTRALIGN]]
201176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL:   [[VA1:%.+]] = bitcast i8** %va to i8*
202176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL:   call void @llvm.va_start(i8* [[VA1]])
2033ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// ALL:   [[AP_CUR:%.+]] = load i8*, i8** %va, align [[PTRALIGN]]
204176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
205176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// O32:   [[PTR0:%.+]] = ptrtoint i8* [[AP_CUR]] to [[INTPTR_T:i32]]
206176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// N32:   [[PTR0:%.+]] = ptrtoint i8* [[AP_CUR]] to [[INTPTR_T:i32]]
207176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// N64:   [[PTR0:%.+]] = ptrtoint i8* [[AP_CUR]] to [[INTPTR_T:i64]]
208176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
209176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// Vectors are 16-byte aligned, however the O32 ABI has a maximum alignment of
210176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// 8-bytes since the base of the stack is 8-byte aligned.
211176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// O32:   [[PTR1:%.+]] = add i32 [[PTR0]], 7
212176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// O32:   [[PTR2:%.+]] = and i32 [[PTR1]], -8
213176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
214176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// NEW:   [[PTR1:%.+]] = add [[INTPTR_T]] [[PTR0]], 15
215176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// NEW:   [[PTR2:%.+]] = and [[INTPTR_T]] [[PTR1]], -16
216176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//
217176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL:   [[PTR3:%.+]] = inttoptr [[INTPTR_T]] [[PTR2]] to <4 x i32>*
218176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL:   [[PTR4:%.+]] = inttoptr [[INTPTR_T]] [[PTR2]] to i8*
2193ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// ALL:   [[AP_NEXT:%.+]] = getelementptr i8, i8* [[PTR4]], [[INTPTR_T]] 16
220176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL:   store i8* [[AP_NEXT]], i8** %va, align [[PTRALIGN]]
2213ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// ALL:   [[PTR5:%.+]] = load <4 x i32>, <4 x i32>* [[PTR3]], align 16
222176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL:   call void @llvm.va_end(i8* [[VA1]])
223176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL:   [[VECEXT:%.+]] = extractelement <4 x i32> [[PTR5]], i32 0
224176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL:   ret i32 [[VECEXT]]
225176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// ALL: }
226