1 // RUN: %clang_cc1 -triple arc-unknown-unknown %s -emit-llvm -o - \ 2 // RUN: | FileCheck %s 3 4 // Basic argument tests for ARC. 5 6 // CHECK: define void @f0(i32 inreg %i, i32 inreg %j, i64 inreg %k) 7 void f0(int i, long j, long long k) {} 8 9 typedef struct { 10 int aa; 11 int bb; 12 } s1; 13 // CHECK: define void @f1(i32 inreg %i.coerce0, i32 inreg %i.coerce1) 14 void f1(s1 i) {} 15 16 typedef struct { 17 char aa; char bb; char cc; char dd; 18 } cs1; 19 // CHECK: define void @cf1(i32 inreg %i.coerce) 20 void cf1(cs1 i) {} 21 22 typedef struct { 23 int cc; 24 } s2; 25 // CHECK: define void @f2(%struct.s2* noalias sret %agg.result) 26 s2 f2() { 27 s2 foo; 28 return foo; 29 } 30 31 typedef struct { 32 int cc; 33 int dd; 34 } s3; 35 // CHECK: define void @f3(%struct.s3* noalias sret %agg.result) 36 s3 f3() { 37 s3 foo; 38 return foo; 39 } 40 41 // CHECK: define void @f4(i64 inreg %i) 42 void f4(long long i) {} 43 44 // CHECK: define void @f5(i8 inreg signext %a, i16 inreg signext %b) 45 void f5(signed char a, short b) {} 46 47 // CHECK: define void @f6(i8 inreg zeroext %a, i16 inreg zeroext %b) 48 void f6(unsigned char a, unsigned short b) {} 49 50 enum my_enum { 51 ENUM1, 52 ENUM2, 53 ENUM3, 54 }; 55 // Enums should be treated as the underlying i32. 56 // CHECK: define void @f7(i32 inreg %a) 57 void f7(enum my_enum a) {} 58 59 enum my_big_enum { 60 ENUM4 = 0xFFFFFFFFFFFFFFFF, 61 }; 62 // Big enums should be treated as the underlying i64. 63 // CHECK: define void @f8(i64 inreg %a) 64 void f8(enum my_big_enum a) {} 65 66 union simple_union { 67 int a; 68 char b; 69 }; 70 // Unions should be passed inreg. 71 // CHECK: define void @f9(i32 inreg %s.coerce) 72 void f9(union simple_union s) {} 73 74 typedef struct { 75 int b4 : 4; 76 int b3 : 3; 77 int b8 : 8; 78 } bitfield1; 79 // Bitfields should be passed inreg. 80 // CHECK: define void @f10(i32 inreg %bf1.coerce) 81 void f10(bitfield1 bf1) {} 82 83 // CHECK: define inreg { float, float } @cplx1(float inreg %r) 84 _Complex float cplx1(float r) { 85 return r + 2.0fi; 86 } 87 88 // CHECK: define inreg { double, double } @cplx2(double inreg %r) 89 _Complex double cplx2(double r) { 90 return r + 2.0i; 91 } 92 93 // CHECK: define inreg { i32, i32 } @cplx3(i32 inreg %r) 94 _Complex int cplx3(int r) { 95 return r + 2i; 96 } 97 98 // CHECK: define inreg { i64, i64 } @cplx4(i64 inreg %r) 99 _Complex long long cplx4(long long r) { 100 return r + 2i; 101 } 102 103 // CHECK: define inreg { i8, i8 } @cplx6(i8 inreg signext %r) 104 _Complex signed char cplx6(signed char r) { 105 return r + 2i; 106 } 107 108 // CHECK: define inreg { i16, i16 } @cplx7(i16 inreg signext %r) 109 _Complex short cplx7(short r) { 110 return r + 2i; 111 } 112 113 typedef struct { 114 int aa; int bb; 115 } s8; 116 117 typedef struct { 118 int aa; int bb; int cc; int dd; 119 } s16; 120 121 // Use 16-byte struct 2 times, gets 8 registers. 122 void st2(s16 a, s16 b) {} 123 // CHECK: define void @st2(i32 inreg %a.coerce0, i32 inreg %a.coerce1, i32 inreg %a.coerce2, i32 inreg %a.coerce3, i32 inreg %b.coerce0, i32 inreg %b.coerce1, i32 inreg %b.coerce2, i32 inreg %b.coerce3) 124 125 // Use 8-byte struct 3 times, gets 8 registers, 1 byval struct argument. 126 void st3(s16 a, s16 b, s16 c) {} 127 // CHECK: define void @st3(i32 inreg %a.coerce0, i32 inreg %a.coerce1, i32 inreg %a.coerce2, i32 inreg %a.coerce3, i32 inreg %b.coerce0, i32 inreg %b.coerce1, i32 inreg %b.coerce2, i32 inreg %b.coerce3, { i32, i32, i32, i32 } %c.coerce) 128 129 // 1 sret + 1 i32 + 2*(i32 coerce) + 4*(i32 coerce) + 1 byval 130 s16 st4(int x, s8 a, s16 b, s16 c) { return b; } 131 // CHECK: define void @st4(%struct.s16* noalias sret %agg.result, i32 inreg %x, i32 inreg %a.coerce0, i32 inreg %a.coerce1, i32 inreg %b.coerce0, i32 inreg %b.coerce1, i32 inreg %b.coerce2, i32 inreg %b.coerce3, { i32, i32, i32, i32 } %c.coerce) 132 133 // 1 sret + 2*(i32 coerce) + 4*(i32 coerce) + 4*(i32 coerce) 134 s16 st5(s8 a, s16 b, s16 c) { return b; } 135 // CHECK: define void @st5(%struct.s16* noalias sret %agg.result, i32 inreg %a.coerce0, i32 inreg %a.coerce1, i32 inreg %b.coerce0, i32 inreg %b.coerce1, i32 inreg %b.coerce2, i32 inreg %b.coerce3, { i32, i32, i32, i32 } %c.coerce) 136