1a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// RUN: %clang_cc1 -triple sparcv9-unknown-unknown -emit-llvm %s -o - | FileCheck %s 2a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen#include <stdarg.h> 3107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen 493ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin// CHECK-LABEL: define void @f_void() 5107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesenvoid f_void(void) {} 6107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen 7107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen// Arguments and return values smaller than the word size are extended. 8107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen 993ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin// CHECK-LABEL: define signext i32 @f_int_1(i32 signext %x) 10107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesenint f_int_1(int x) { return x; } 11107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen 1293ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin// CHECK-LABEL: define zeroext i32 @f_int_2(i32 zeroext %x) 13107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesenunsigned f_int_2(unsigned x) { return x; } 14107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen 1593ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin// CHECK-LABEL: define i64 @f_int_3(i64 %x) 16107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesenlong long f_int_3(long long x) { return x; } 17107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen 1893ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin// CHECK-LABEL: define signext i8 @f_int_4(i8 signext %x) 19107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesenchar f_int_4(char x) { return x; } 20107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen 21651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-LABEL: define fp128 @f_ld(fp128 %x) 22651f13cea278ec967336033dd032faef0e9fc2ecStephen Hineslong double f_ld(long double x) { return x; } 23651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 24107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen// Small structs are passed in registers. 25107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesenstruct small { 26107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen int *a, *b; 27107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen}; 28107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen 2993ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin// CHECK-LABEL: define %struct.small @f_small(i32* %x.coerce0, i32* %x.coerce1) 30107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesenstruct small f_small(struct small x) { 31107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen x.a += *x.b; 32107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen x.b = 0; 33107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen return x; 34107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen} 35107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen 36107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen// Medium-sized structs are passed indirectly, but can be returned in registers. 37107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesenstruct medium { 38107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen int *a, *b; 39107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen int *c, *d; 40107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen}; 41107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen 4293ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin// CHECK-LABEL: define %struct.medium @f_medium(%struct.medium* %x) 43107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesenstruct medium f_medium(struct medium x) { 44107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen x.a += *x.b; 45107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen x.b = 0; 46107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen return x; 47107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen} 48107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen 49107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen// Large structs are also returned indirectly. 50107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesenstruct large { 51107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen int *a, *b; 52107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen int *c, *d; 53107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen int x; 54107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen}; 55107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen 5693ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin// CHECK-LABEL: define void @f_large(%struct.large* noalias sret %agg.result, %struct.large* %x) 57107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesenstruct large f_large(struct large x) { 58107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen x.a += *x.b; 59107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen x.b = 0; 60107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen return x; 61107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen} 62107196cb219128bfddde53f4718e5c9aa3a41ba6Jakob Stoklund Olesen 63fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesen// A 64-bit struct fits in a register. 64fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesenstruct reg { 65fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesen int a, b; 66fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesen}; 67fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesen 6893ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin// CHECK-LABEL: define i64 @f_reg(i64 %x.coerce) 69fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesenstruct reg f_reg(struct reg x) { 70fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesen x.a += x.b; 71fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesen return x; 72fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesen} 73fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesen 74fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesen// Structs with mixed int and float parts require the inreg attribute. 75fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesenstruct mixed { 76fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesen int a; 77fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesen float b; 78fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesen}; 79fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesen 8093ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin// CHECK-LABEL: define inreg %struct.mixed @f_mixed(i32 inreg %x.coerce0, float inreg %x.coerce1) 81fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesenstruct mixed f_mixed(struct mixed x) { 82fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesen x.a += 1; 83fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesen return x; 84fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesen} 85fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesen 86fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesen// Struct with padding. 87fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesenstruct mixed2 { 88fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesen int a; 89fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesen double b; 90fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesen}; 91fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesen 927e9f52f1faacf5505476418411127c5b16e07533Jakob Stoklund Olesen// CHECK: define { i64, double } @f_mixed2(i64 %x.coerce0, double %x.coerce1) 937e9f52f1faacf5505476418411127c5b16e07533Jakob Stoklund Olesen// CHECK: store i64 %x.coerce0 947e9f52f1faacf5505476418411127c5b16e07533Jakob Stoklund Olesen// CHECK: store double %x.coerce1 95fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesenstruct mixed2 f_mixed2(struct mixed2 x) { 96fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesen x.a += 1; 97fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesen return x; 98fc782fbeb25ad880ec667f34997bd45d530aef86Jakob Stoklund Olesen} 997e9f52f1faacf5505476418411127c5b16e07533Jakob Stoklund Olesen 1007e9f52f1faacf5505476418411127c5b16e07533Jakob Stoklund Olesen// Struct with single element and padding in passed in the high bits of a 1017e9f52f1faacf5505476418411127c5b16e07533Jakob Stoklund Olesen// register. 1027e9f52f1faacf5505476418411127c5b16e07533Jakob Stoklund Olesenstruct tiny { 1037e9f52f1faacf5505476418411127c5b16e07533Jakob Stoklund Olesen char a; 1047e9f52f1faacf5505476418411127c5b16e07533Jakob Stoklund Olesen}; 1057e9f52f1faacf5505476418411127c5b16e07533Jakob Stoklund Olesen 10693ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin// CHECK-LABEL: define i64 @f_tiny(i64 %x.coerce) 1077e9f52f1faacf5505476418411127c5b16e07533Jakob Stoklund Olesen// CHECK: %[[HB:[^ ]+]] = lshr i64 %x.coerce, 56 1087e9f52f1faacf5505476418411127c5b16e07533Jakob Stoklund Olesen// CHECK: = trunc i64 %[[HB]] to i8 1097e9f52f1faacf5505476418411127c5b16e07533Jakob Stoklund Olesenstruct tiny f_tiny(struct tiny x) { 1107e9f52f1faacf5505476418411127c5b16e07533Jakob Stoklund Olesen x.a += 1; 1117e9f52f1faacf5505476418411127c5b16e07533Jakob Stoklund Olesen return x; 1127e9f52f1faacf5505476418411127c5b16e07533Jakob Stoklund Olesen} 1137e9f52f1faacf5505476418411127c5b16e07533Jakob Stoklund Olesen 11493ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin// CHECK-LABEL: define void @call_tiny() 1157e9f52f1faacf5505476418411127c5b16e07533Jakob Stoklund Olesen// CHECK: %[[XV:[^ ]+]] = zext i8 %{{[^ ]+}} to i64 1167e9f52f1faacf5505476418411127c5b16e07533Jakob Stoklund Olesen// CHECK: %[[HB:[^ ]+]] = shl i64 %[[XV]], 56 1177e9f52f1faacf5505476418411127c5b16e07533Jakob Stoklund Olesen// CHECK: = call i64 @f_tiny(i64 %[[HB]]) 1187e9f52f1faacf5505476418411127c5b16e07533Jakob Stoklund Olesenvoid call_tiny() { 1197e9f52f1faacf5505476418411127c5b16e07533Jakob Stoklund Olesen struct tiny x = { 1 }; 1207e9f52f1faacf5505476418411127c5b16e07533Jakob Stoklund Olesen f_tiny(x); 1217e9f52f1faacf5505476418411127c5b16e07533Jakob Stoklund Olesen} 122a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen 12393ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin// CHECK-LABEL: define signext i32 @f_variable(i8* %f, ...) 124a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK: %ap = alloca i8* 125a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK: call void @llvm.va_start 126a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// 127a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesenint f_variable(char *f, ...) { 128a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen int s = 0; 129a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen char c; 130a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen va_list ap; 131a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen va_start(ap, f); 132a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen while ((c = *f++)) switch (c) { 133a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen 134a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK: %[[CUR:[^ ]+]] = load i8** %ap 135a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK-DAG: %[[NXT:[^ ]+]] = getelementptr i8* %[[CUR]], i32 8 136a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK-DAG: store i8* %[[NXT]], i8** %ap 137a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK-DAG: %[[EXT:[^ ]+]] = getelementptr i8* %[[CUR]], i32 4 138a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK-DAG: %[[ADR:[^ ]+]] = bitcast i8* %[[EXT]] to i32* 139a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK-DAG: load i32* %[[ADR]] 140a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK: br 141a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen case 'i': 142a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen s += va_arg(ap, int); 143a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen break; 144a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen 145a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK: %[[CUR:[^ ]+]] = load i8** %ap 146a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK-DAG: %[[NXT:[^ ]+]] = getelementptr i8* %[[CUR]], i32 8 147a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK-DAG: store i8* %[[NXT]], i8** %ap 148a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK-DAG: %[[ADR:[^ ]+]] = bitcast i8* %[[CUR]] to i64* 149a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK-DAG: load i64* %[[ADR]] 150a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK: br 151a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen case 'l': 152a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen s += va_arg(ap, long); 153a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen break; 154a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen 155a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK: %[[CUR:[^ ]+]] = load i8** %ap 156a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK-DAG: %[[NXT:[^ ]+]] = getelementptr i8* %[[CUR]], i32 8 157a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK-DAG: store i8* %[[NXT]], i8** %ap 158a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK-DAG: %[[ADR:[^ ]+]] = bitcast i8* %[[CUR]] to %struct.tiny* 159a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK: br 160a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen case 't': 161a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen s += va_arg(ap, struct tiny).a; 162a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen break; 163a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen 164a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK: %[[CUR:[^ ]+]] = load i8** %ap 165a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK-DAG: %[[NXT:[^ ]+]] = getelementptr i8* %[[CUR]], i32 16 166a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK-DAG: store i8* %[[NXT]], i8** %ap 167a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK-DAG: %[[ADR:[^ ]+]] = bitcast i8* %[[CUR]] to %struct.small* 168a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK: br 169a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen case 's': 170a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen s += *va_arg(ap, struct small).a; 171a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen break; 172a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen 173a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK: %[[CUR:[^ ]+]] = load i8** %ap 174a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK-DAG: %[[NXT:[^ ]+]] = getelementptr i8* %[[CUR]], i32 8 175a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK-DAG: store i8* %[[NXT]], i8** %ap 176a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK-DAG: %[[IND:[^ ]+]] = bitcast i8* %[[CUR]] to %struct.medium** 177a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK-DAG: %[[ADR:[^ ]+]] = load %struct.medium** %[[IND]] 178a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen// CHECK: br 179a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen case 'm': 180a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen s += *va_arg(ap, struct medium).a; 181a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen break; 182a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen } 183a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen return s; 184a4b56d30389753cbde96ad410e86db4b4b86ac16Jakob Stoklund Olesen} 185