reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
// RUN: %clang_cc1 -triple arc-unknown-unknown %s -emit-llvm -o - \
// RUN:   | FileCheck %s

// Basic argument tests for ARC.

// CHECK: define void @f0(i32 inreg %i, i32 inreg %j, i64 inreg %k)
void f0(int i, long j, long long k) {}

typedef struct {
  int aa;
  int bb;
} s1;
// CHECK: define void @f1(i32 inreg %i.coerce0, i32 inreg %i.coerce1)
void f1(s1 i) {}

typedef struct {
  char aa; char bb; char cc; char dd;
} cs1;
// CHECK: define void @cf1(i32 inreg %i.coerce)
void cf1(cs1 i) {}

typedef struct {
  int cc;
} s2;
// CHECK: define void @f2(%struct.s2* noalias sret %agg.result)
s2 f2() {
  s2 foo;
  return foo;
}

typedef struct {
  int cc;
  int dd;
} s3;
// CHECK: define void @f3(%struct.s3* noalias sret %agg.result)
s3 f3() {
  s3 foo;
  return foo;
}

// CHECK: define void @f4(i64 inreg %i)
void f4(long long i) {}

// CHECK: define void @f5(i8 inreg signext %a, i16 inreg signext %b)
void f5(signed char a, short b) {}

// CHECK: define void @f6(i8 inreg zeroext %a, i16 inreg zeroext %b)
void f6(unsigned char a, unsigned short b) {}

enum my_enum {
  ENUM1,
  ENUM2,
  ENUM3,
};
// Enums should be treated as the underlying i32.
// CHECK: define void @f7(i32 inreg %a)
void f7(enum my_enum a) {}

enum my_big_enum {
  ENUM4 = 0xFFFFFFFFFFFFFFFF,
};
// Big enums should be treated as the underlying i64.
// CHECK: define void @f8(i64 inreg %a)
void f8(enum my_big_enum a) {}

union simple_union {
  int a;
  char b;
};
// Unions should be passed inreg.
// CHECK: define void @f9(i32 inreg %s.coerce)
void f9(union simple_union s) {}

typedef struct {
  int b4 : 4;
  int b3 : 3;
  int b8 : 8;
} bitfield1;
// Bitfields should be passed inreg.
// CHECK: define void @f10(i32 inreg %bf1.coerce)
void f10(bitfield1 bf1) {}

// CHECK: define inreg { float, float } @cplx1(float inreg %r)
_Complex float cplx1(float r) {
  return r + 2.0fi;
}

// CHECK: define inreg { double, double } @cplx2(double inreg %r)
_Complex double cplx2(double r) {
  return r + 2.0i;
}

// CHECK: define inreg { i32, i32 } @cplx3(i32 inreg %r)
_Complex int cplx3(int r) {
  return r + 2i;
}

// CHECK: define inreg { i64, i64 } @cplx4(i64 inreg %r)
_Complex long long cplx4(long long r) {
  return r + 2i;
}

// CHECK: define inreg { i8, i8 } @cplx6(i8 inreg signext %r)
_Complex signed char cplx6(signed char r) {
  return r + 2i;
}

// CHECK: define inreg { i16, i16 } @cplx7(i16 inreg signext %r)
_Complex short cplx7(short r) {
  return r + 2i;
}

typedef struct {
  int aa; int bb;
} s8;

typedef struct {
  int aa; int bb; int cc; int dd;
} s16;

// Use 16-byte struct 2 times, gets 8 registers.
void st2(s16 a, s16 b) {}
// 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)

// Use 8-byte struct 3 times, gets 8 registers, 1 byval struct argument.
void st3(s16 a, s16 b, s16 c) {}
// 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)

// 1 sret + 1 i32 + 2*(i32 coerce) + 4*(i32 coerce) + 1 byval
s16 st4(int x, s8 a, s16 b, s16 c) { return b; }
// 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)

// 1 sret + 2*(i32 coerce) + 4*(i32 coerce) + 4*(i32 coerce)
s16 st5(s8 a, s16 b, s16 c) { return b; }
// 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)