1e8519c31a6ef853b627d557702ac1890f18ce2c9Charles Davis// RUN: %clang_cc1 -triple x86_64-unknown-freebsd10.0 -emit-llvm < %s | FileCheck -check-prefix=FREEBSD %s 2e8519c31a6ef853b627d557702ac1890f18ce2c9Charles Davis// RUN: %clang_cc1 -triple x86_64-pc-win32 -emit-llvm < %s | FileCheck -check-prefix=WIN64 %s 3e8519c31a6ef853b627d557702ac1890f18ce2c9Charles Davis 487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarstruct foo { 587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar int x; 687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar float y; 787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar char z; 887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}; 987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar// FREEBSD: %[[STRUCT_FOO:.*]] = type { i32, float, i8 } 1087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar// WIN64: %[[STRUCT_FOO:.*]] = type { i32, float, i8 } 1187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 12e8519c31a6ef853b627d557702ac1890f18ce2c9Charles Davisvoid __attribute__((ms_abi)) f1(void); 13e8519c31a6ef853b627d557702ac1890f18ce2c9Charles Davisvoid __attribute__((sysv_abi)) f2(void); 14e8519c31a6ef853b627d557702ac1890f18ce2c9Charles Davisvoid f3(void) { 1587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD-LABEL: define void @f3() 1687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-LABEL: define void @f3() 17e8519c31a6ef853b627d557702ac1890f18ce2c9Charles Davis f1(); 1887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD: call x86_64_win64cc void @f1() 1987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64: call void @f1() 20e8519c31a6ef853b627d557702ac1890f18ce2c9Charles Davis f2(); 2187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD: call void @f2() 2287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64: call x86_64_sysvcc void @f2() 23e8519c31a6ef853b627d557702ac1890f18ce2c9Charles Davis} 24e8519c31a6ef853b627d557702ac1890f18ce2c9Charles Davis// FREEBSD: declare x86_64_win64cc void @f1() 25e8519c31a6ef853b627d557702ac1890f18ce2c9Charles Davis// FREEBSD: declare void @f2() 26e8519c31a6ef853b627d557702ac1890f18ce2c9Charles Davis// WIN64: declare void @f1() 27e8519c31a6ef853b627d557702ac1890f18ce2c9Charles Davis// WIN64: declare x86_64_sysvcc void @f2() 28e8519c31a6ef853b627d557702ac1890f18ce2c9Charles Davis 2987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar// Win64 ABI varargs 3087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarvoid __attribute__((ms_abi)) f4(int a, ...) { 3187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD-LABEL: define x86_64_win64cc void @f4 3287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-LABEL: define void @f4 3387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar __builtin_ms_va_list ap; 3487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar __builtin_ms_va_start(ap, a); 3587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD: %[[AP:.*]] = alloca i8* 3687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD: call void @llvm.va_start 3787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64: %[[AP:.*]] = alloca i8* 3887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64: call void @llvm.va_start 3987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar int b = __builtin_va_arg(ap, int); 4087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD: %[[AP_CUR:.*]] = load i8*, i8** %[[AP]] 4187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD-NEXT: %[[AP_NEXT:.*]] = getelementptr inbounds i8, i8* %[[AP_CUR]], i64 8 4287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD-NEXT: store i8* %[[AP_NEXT]], i8** %[[AP]] 4387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD-NEXT: bitcast i8* %[[AP_CUR]] to i32* 4487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64: %[[AP_CUR:.*]] = load i8*, i8** %[[AP]] 4587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: %[[AP_NEXT:.*]] = getelementptr inbounds i8, i8* %[[AP_CUR]], i64 8 4687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: store i8* %[[AP_NEXT]], i8** %[[AP]] 4787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: bitcast i8* %[[AP_CUR]] to i32* 4887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar double _Complex c = __builtin_va_arg(ap, double _Complex); 4987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD: %[[AP_CUR2:.*]] = load i8*, i8** %[[AP]] 5087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD-NEXT: %[[AP_NEXT2:.*]] = getelementptr inbounds i8, i8* %[[AP_CUR2]], i64 16 5187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD-NEXT: store i8* %[[AP_NEXT2]], i8** %[[AP]] 5287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD-NEXT: bitcast i8* %[[AP_CUR2]] to { double, double }* 5387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64: %[[AP_CUR2:.*]] = load i8*, i8** %[[AP]] 5487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: %[[AP_NEXT2:.*]] = getelementptr inbounds i8, i8* %[[AP_CUR2]], i64 16 5587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: store i8* %[[AP_NEXT2]], i8** %[[AP]] 5687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: bitcast i8* %[[AP_CUR2]] to { double, double }* 5787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar struct foo d = __builtin_va_arg(ap, struct foo); 5887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD: %[[AP_CUR3:.*]] = load i8*, i8** %[[AP]] 5987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD-NEXT: %[[AP_NEXT3:.*]] = getelementptr inbounds i8, i8* %[[AP_CUR3]], i64 16 6087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD-NEXT: store i8* %[[AP_NEXT3]], i8** %[[AP]] 6187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD-NEXT: bitcast i8* %[[AP_CUR3]] to %[[STRUCT_FOO]]* 6287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64: %[[AP_CUR3:.*]] = load i8*, i8** %[[AP]] 6387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: %[[AP_NEXT3:.*]] = getelementptr inbounds i8, i8* %[[AP_CUR3]], i64 16 6487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: store i8* %[[AP_NEXT3]], i8** %[[AP]] 6587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: bitcast i8* %[[AP_CUR3]] to %[[STRUCT_FOO]]* 6687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar __builtin_ms_va_list ap2; 6787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar __builtin_ms_va_copy(ap2, ap); 6887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD: %[[AP_VAL:.*]] = load i8*, i8** %[[AP]] 6987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD-NEXT: store i8* %[[AP_VAL]], i8** %[[AP2:.*]] 7087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64: %[[AP_VAL:.*]] = load i8*, i8** %[[AP]] 7187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: store i8* %[[AP_VAL]], i8** %[[AP2:.*]] 7287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar __builtin_ms_va_end(ap); 7387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD: call void @llvm.va_end 7487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64: call void @llvm.va_end 7587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} 7687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 7787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar// Let's verify that normal va_lists work right on Win64, too. 7887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarvoid f5(int a, ...) { 7987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-LABEL: define void @f5 8087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar __builtin_va_list ap; 8187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar __builtin_va_start(ap, a); 8287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64: %[[AP:.*]] = alloca i8* 8387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64: call void @llvm.va_start 8487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar int b = __builtin_va_arg(ap, int); 8587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64: %[[AP_CUR:.*]] = load i8*, i8** %[[AP]] 8687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: %[[AP_NEXT:.*]] = getelementptr inbounds i8, i8* %[[AP_CUR]], i64 8 8787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: store i8* %[[AP_NEXT]], i8** %[[AP]] 8887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: bitcast i8* %[[AP_CUR]] to i32* 8987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar double _Complex c = __builtin_va_arg(ap, double _Complex); 9087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64: %[[AP_CUR2:.*]] = load i8*, i8** %[[AP]] 9187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: %[[AP_NEXT2:.*]] = getelementptr inbounds i8, i8* %[[AP_CUR2]], i64 16 9287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: store i8* %[[AP_NEXT2]], i8** %[[AP]] 9387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: bitcast i8* %[[AP_CUR2]] to { double, double }* 9487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar struct foo d = __builtin_va_arg(ap, struct foo); 9587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64: %[[AP_CUR3:.*]] = load i8*, i8** %[[AP]] 9687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: %[[AP_NEXT3:.*]] = getelementptr inbounds i8, i8* %[[AP_CUR3]], i64 16 9787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: store i8* %[[AP_NEXT3]], i8** %[[AP]] 9887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: bitcast i8* %[[AP_CUR3]] to %[[STRUCT_FOO]]* 9987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar __builtin_va_list ap2; 10087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar __builtin_va_copy(ap2, ap); 10187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64: call void @llvm.va_copy 10287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar __builtin_va_end(ap); 10387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64: call void @llvm.va_end 10487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} 10587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 10687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar// Verify that using a Win64 va_list from a System V function works. 10787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarvoid __attribute__((sysv_abi)) f6(__builtin_ms_va_list ap) { 10887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD-LABEL: define void @f6 10987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD: store i8* %ap, i8** %[[AP:.*]] 11087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-LABEL: define x86_64_sysvcc void @f6 11187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64: store i8* %ap, i8** %[[AP:.*]] 11287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar int b = __builtin_va_arg(ap, int); 11387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD: %[[AP_CUR:.*]] = load i8*, i8** %[[AP]] 11487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD-NEXT: %[[AP_NEXT:.*]] = getelementptr inbounds i8, i8* %[[AP_CUR]], i64 8 11587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD-NEXT: store i8* %[[AP_NEXT]], i8** %[[AP]] 11687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD-NEXT: bitcast i8* %[[AP_CUR]] to i32* 11787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64: %[[AP_CUR:.*]] = load i8*, i8** %[[AP]] 11887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: %[[AP_NEXT:.*]] = getelementptr inbounds i8, i8* %[[AP_CUR]], i64 8 11987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: store i8* %[[AP_NEXT]], i8** %[[AP]] 12087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: bitcast i8* %[[AP_CUR]] to i32* 12187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar double _Complex c = __builtin_va_arg(ap, double _Complex); 12287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD: %[[AP_CUR2:.*]] = load i8*, i8** %[[AP]] 12387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD-NEXT: %[[AP_NEXT2:.*]] = getelementptr inbounds i8, i8* %[[AP_CUR2]], i64 16 12487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD-NEXT: store i8* %[[AP_NEXT2]], i8** %[[AP]] 12587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD-NEXT: bitcast i8* %[[AP_CUR2]] to { double, double }* 12687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64: %[[AP_CUR2:.*]] = load i8*, i8** %[[AP]] 12787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: %[[AP_NEXT2:.*]] = getelementptr inbounds i8, i8* %[[AP_CUR2]], i64 16 12887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: store i8* %[[AP_NEXT2]], i8** %[[AP]] 12987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: bitcast i8* %[[AP_CUR2]] to { double, double }* 13087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar struct foo d = __builtin_va_arg(ap, struct foo); 13187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD: %[[AP_CUR3:.*]] = load i8*, i8** %[[AP]] 13287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD-NEXT: %[[AP_NEXT3:.*]] = getelementptr inbounds i8, i8* %[[AP_CUR3]], i64 16 13387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD-NEXT: store i8* %[[AP_NEXT3]], i8** %[[AP]] 13487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD-NEXT: bitcast i8* %[[AP_CUR3]] to %[[STRUCT_FOO]]* 13587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64: %[[AP_CUR3:.*]] = load i8*, i8** %[[AP]] 13687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: %[[AP_NEXT3:.*]] = getelementptr inbounds i8, i8* %[[AP_CUR3]], i64 16 13787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: store i8* %[[AP_NEXT3]], i8** %[[AP]] 13887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: bitcast i8* %[[AP_CUR3]] to %[[STRUCT_FOO]]* 13987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar __builtin_ms_va_list ap2; 14087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar __builtin_ms_va_copy(ap2, ap); 14187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD: %[[AP_VAL:.*]] = load i8*, i8** %[[AP]] 14287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FREEBSD-NEXT: store i8* %[[AP_VAL]], i8** %[[AP2:.*]] 14387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64: %[[AP_VAL:.*]] = load i8*, i8** %[[AP]] 14487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // WIN64-NEXT: store i8* %[[AP_VAL]], i8** %[[AP2:.*]] 14587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} 146