1 // RUN: %clang_cc1 -no-opaque-pointers -triple sparcv9-unknown-unknown -emit-llvm %s -o - | FileCheck %s
4 // CHECK-LABEL: define{{.*}} void @f_void()
7 // Arguments and return values smaller than the word size are extended.
9 // CHECK-LABEL: define{{.*}} signext i32 @f_int_1(i32 noundef signext %x)
10 int f_int_1(int x
) { return x
; }
12 // CHECK-LABEL: define{{.*}} zeroext i32 @f_int_2(i32 noundef zeroext %x)
13 unsigned f_int_2(unsigned x
) { return x
; }
15 // CHECK-LABEL: define{{.*}} i64 @f_int_3(i64 noundef %x)
16 long long f_int_3(long long x
) { return x
; }
18 // CHECK-LABEL: define{{.*}} signext i8 @f_int_4(i8 noundef signext %x)
19 char f_int_4(char x
) { return x
; }
21 // CHECK-LABEL: define{{.*}} fp128 @f_ld(fp128 noundef %x)
22 long double f_ld(long double x
) { return x
; }
24 // Small structs are passed in registers.
29 // CHECK-LABEL: define{{.*}} %struct.small @f_small(i32* %x.coerce0, i32* %x.coerce1)
30 struct small
f_small(struct small x
) {
36 // Medium-sized structs are passed indirectly, but can be returned in registers.
42 // CHECK-LABEL: define{{.*}} %struct.medium @f_medium(%struct.medium* noundef %x)
43 struct medium
f_medium(struct medium x
) {
49 // Large structs are also returned indirectly.
56 // CHECK-LABEL: define{{.*}} void @f_large(%struct.large* noalias sret(%struct.large) align 8 %agg.result, %struct.large* noundef %x)
57 struct large
f_large(struct large x
) {
63 // A 64-bit struct fits in a register.
68 // CHECK-LABEL: define{{.*}} i64 @f_reg(i64 %x.coerce)
69 struct reg
f_reg(struct reg x
) {
74 // Structs with mixed int and float parts require the inreg attribute.
80 // CHECK-LABEL: define{{.*}} inreg %struct.mixed @f_mixed(i32 inreg %x.coerce0, float inreg %x.coerce1)
81 struct mixed
f_mixed(struct mixed x
) {
86 // Struct with padding.
92 // CHECK: define{{.*}} { i64, double } @f_mixed2(i64 %x.coerce0, double %x.coerce1)
93 // CHECK: store i64 %x.coerce0
94 // CHECK: store double %x.coerce1
95 struct mixed2
f_mixed2(struct mixed2 x
) {
100 // Struct with single element and padding in passed in the high bits of a
106 // CHECK-LABEL: define{{.*}} i64 @f_tiny(i64 %x.coerce)
107 // CHECK: %[[HB:[^ ]+]] = lshr i64 %x.coerce, 56
108 // CHECK: = trunc i64 %[[HB]] to i8
109 struct tiny
f_tiny(struct tiny x
) {
114 // CHECK-LABEL: define{{.*}} void @call_tiny()
115 // CHECK: %[[XV:[^ ]+]] = zext i8 %{{[^ ]+}} to i64
116 // CHECK: %[[HB:[^ ]+]] = shl i64 %[[XV]], 56
117 // CHECK: = call i64 @f_tiny(i64 %[[HB]])
118 void call_tiny(void) {
119 struct tiny x
= { 1 };
123 // CHECK-LABEL: define{{.*}} signext i32 @f_variable(i8* noundef %f, ...)
124 // CHECK: %ap = alloca i8*
125 // CHECK: call void @llvm.va_start
127 int f_variable(char *f
, ...) {
132 while ((c
= *f
++)) switch (c
) {
134 // CHECK: %[[CUR:[^ ]+]] = load i8*, i8** %ap
135 // CHECK-DAG: %[[NXT:[^ ]+]] = getelementptr inbounds i8, i8* %[[CUR]], i64 8
136 // CHECK-DAG: store i8* %[[NXT]], i8** %ap
137 // CHECK-DAG: %[[EXT:[^ ]+]] = getelementptr inbounds i8, i8* %[[CUR]], i64 4
138 // CHECK-DAG: %[[ADR:[^ ]+]] = bitcast i8* %[[EXT]] to i32*
139 // CHECK-DAG: load i32, i32* %[[ADR]]
142 s
+= va_arg(ap
, int);
145 // CHECK: %[[CUR:[^ ]+]] = load i8*, i8** %ap
146 // CHECK-DAG: %[[NXT:[^ ]+]] = getelementptr inbounds i8, i8* %[[CUR]], i64 8
147 // CHECK-DAG: store i8* %[[NXT]], i8** %ap
148 // CHECK-DAG: %[[ADR:[^ ]+]] = bitcast i8* %[[CUR]] to i64*
149 // CHECK-DAG: load i64, i64* %[[ADR]]
152 s
+= va_arg(ap
, long);
155 // CHECK: %[[CUR:[^ ]+]] = load i8*, i8** %ap
156 // CHECK-DAG: %[[NXT:[^ ]+]] = getelementptr inbounds i8, i8* %[[CUR]], i64 8
157 // CHECK-DAG: store i8* %[[NXT]], i8** %ap
158 // CHECK-DAG: %[[ADR:[^ ]+]] = bitcast i8* %[[CUR]] to %struct.tiny*
161 s
+= va_arg(ap
, struct tiny
).a
;
164 // CHECK: %[[CUR:[^ ]+]] = load i8*, i8** %ap
165 // CHECK-DAG: %[[NXT:[^ ]+]] = getelementptr inbounds i8, i8* %[[CUR]], i64 16
166 // CHECK-DAG: store i8* %[[NXT]], i8** %ap
167 // CHECK-DAG: %[[ADR:[^ ]+]] = bitcast i8* %[[CUR]] to %struct.small*
170 s
+= *va_arg(ap
, struct small
).a
;
173 // CHECK: %[[CUR:[^ ]+]] = load i8*, i8** %ap
174 // CHECK-DAG: %[[NXT:[^ ]+]] = getelementptr inbounds i8, i8* %[[CUR]], i64 8
175 // CHECK-DAG: store i8* %[[NXT]], i8** %ap
176 // CHECK-DAG: %[[IND:[^ ]+]] = bitcast i8* %[[CUR]] to %struct.medium**
177 // CHECK-DAG: %[[ADR:[^ ]+]] = load %struct.medium*, %struct.medium** %[[IND]]
180 s
+= *va_arg(ap
, struct medium
).a
;