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
// RUN: llvm-tblgen %s | FileCheck %s
// XFAIL: vg_leak

// Support for an `!if' operator as part of a `let' statement.
// CHECK:      class C
// CHECK-NEXT: bits<16> n = { ?, ?, ?, ?, !if({ C:y{3} }, 1, !if({ C:y{2} }, { C:x{0} }, !if({ C:y{1} }, { C:x{1} }, !if({ C:y{0} }, { C:x{2} }, ?)))){0}, !if({ C:x{2} }, { C:y{3}, C:y{2} }, !if({ C:x{1} }, { C:y{2}, C:y{1} }, !if({ C:x{0} }, { C:y{1}, C:y{0} }, ?))){1}, !if({ C:x{2} }, { C:y{3}, C:y{2} }, !if({ C:x{1} }, { C:y{2}, C:y{1} }, !if({ C:x{0} }, { C:y{1}, C:y{0} }, ?))){0}, !if({ C:x{2} }, { 0, 1, 0 }, { 1, 1, 0 }){2}, !if({ C:x{2} }, { 0, 1, 0 }, { 1, 1, 0 }){1}, !if({ C:x{2} }, { 0, 1, 0 }, { 1, 1, 0 }){0}, !if({ C:x{1} }, { C:y{3}, C:y{2} }, { 0, 1 }){1}, !if({ C:x{1} }, { C:y{3}, C:y{2} }, { 0, 1 }){0}, !if({ C:x{0} }, { C:y{3}, C:y{2}, C:y{1}, C:y{0} }, { C:z, C:y{2}, C:y{1}, C:y{0} }){3}, !if({ C:x{0} }, { C:y{3}, C:y{2}, C:y{1}, C:y{0} }, { C:z, C:y{2}, C:y{1}, C:y{0} }){2}, !if({ C:x{0} }, { C:y{3}, C:y{2}, C:y{1}, C:y{0} }, { C:z, C:y{2}, C:y{1}, C:y{0} }){1}, !if({ C:x{0} }, { C:y{3}, C:y{2}, C:y{1}, C:y{0} }, { C:z, C:y{2}, C:y{1}, C:y{0} }){0} };
class C<bits<3> x, bits<4> y, bit z> {
  bits<16> n;

  let n{11}  = !if(y{3}, 1,
               !if(y{2}, x{0},
               !if(y{1}, x{1},
               !if(y{0}, x{2}, ?))));
  let n{10-9}= !if(x{2}, y{3-2},
               !if(x{1}, y{2-1},
               !if(x{0}, y{1-0}, ?)));
  let n{8-6} = !if(x{2}, 0b010, 0b110);
  let n{5-4} = !if(x{1}, y{3-2}, {0, 1});
  let n{3-0} = !if(x{0}, y{3-0}, {z, y{2}, y{1}, y{0}});
}

def C1 : C<{1, 0, 1}, {0, 1, 0, 1}, 0>;
def C2 : C<{0, 1, 0}, {1, 0, 1, 0}, 1>;
def C3 : C<{0, 0, 0}, {1, 0, 1, 0}, 0>;
def C4 : C<{0, 0, 0}, {0, 0, 0, 0}, 0>;

// CHECK: def C1
// CHECK-NEXT: bits<16> n = { ?, ?, ?, ?, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 };
// CHECK: def C2
// CHECK-NEXT: bits<16> n = { ?, ?, ?, ?, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0 };
// CHECK: def C3
// CHECK-NEXT: bits<16> n = { ?, ?, ?, ?, 1, ?, ?, 1, 1, 0, 0, 1, 0, 0, 1, 0 };
// CHECK: def C4
// CHECK-NEXT: bits<16> n = { ?, ?, ?, ?, ?, ?, ?, 1, 1, 0, 0, 1, 0, 0, 0, 0 };

class S<int s> {
  bits<2> val = !if(!eq(s, 8),  {0, 0},
                !if(!eq(s, 16), 0b01,
                !if(!eq(s, 32), 2,
                !if(!eq(s, 64), {1, 1}, ?))));
}

def D8  : S<8>;
def D16 : S<16>;
def D32 : S<32>;
def D64 : S<64>;
def D128: S<128>;
// CHECK: def D128
// CHECK-NEXT: bits<2> val = { ?, ? };
// CHECK: def D16
// CHECK-NEXT: bits<2> val = { 0, 1 };
// CHECK: def D32
// CHECK-NEXT: bits<2> val = { 1, 0 };
// CHECK: def D64
// CHECK-NEXT: bits<2> val = { 1, 1 };
// CHECK: def D8
// CHECK-NEXT: bits<2> val = { 0, 0 };

// Make sure !if gets propagated across multiple layers of inheritance.
class getInt<int c> {
  int ret = !if(c, 0, 1);
}
class I1<int c> {
  int i = getInt<c>.ret;
}
class I2<int c> : I1<c>;

// CHECK: def DI1 {     // I1
// CHECK-NEXT: int i = 0;
def DI1: I1<1>;

// CHECK: def DI2 {     // I1 I2
// CHECK-NEXT: int i = 0;
def DI2: I2<1>;

// Check that !if with operands of different subtypes can initialize a
// supertype variable.
//
// CHECK: def EXd1 {
// CHECK:   E x = E1d;
// CHECK: }
//
// CHECK: def EXd2 {
// CHECK:   E x = E2d;
// CHECK: }
class E<int dummy> {}
class E1<int dummy> : E<dummy> {}
class E2<int dummy> : E<dummy> {}

class EX<int cc, E1 b, E2 c> {
  E x = !if(cc, b, c);
}

def E1d : E1<0>;
def E2d : E2<0>;

def EXd1 : EX<1, E1d, E2d>;
def EXd2 : EX<0, E1d, E2d>;

// CHECK:      def One
// CHECK-NEXT: list<int> first = [1, 2, 3];
// CHECK-NEXT: list<int> rest = [1, 2, 3];

// CHECK:      def OneB
// CHECK-NEXT: list<int> vals = [1, 2, 3];

// CHECK:      def Two
// CHECK-NEXT: list<int> first = [1, 2, 3];
// CHECK-NEXT: list<int> rest = [4, 5, 6];

// CHECK:      def TwoB
// CHECK-NEXT: list<int> vals = [4, 5, 6];

class A<list<list<int>> vals> {
  list<int> first = vals[0];
  list<int> rest  = !if(!empty(!tail(vals)), vals[0], vals[1]);
}

def One : A<[[1,2,3]]>;
def Two : A<[[1,2,3], [4,5,6]]>;

class B<list<int> v> {
  list<int> vals = v;
}

class BB<list<list<int>> vals> : B<!if(!empty(!tail(vals)), vals[0], vals[1])>;
class BBB<list<list<int>> vals> : BB<vals>;

def OneB : BBB<[[1,2,3]]>;
def TwoB : BBB<[[1,2,3],[4,5,6]]>;