File: const_cond_labels.d

package info (click to toggle)
ldc 1%3A1.30.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 59,248 kB
  • sloc: cpp: 61,598; ansic: 14,545; sh: 1,014; makefile: 972; asm: 510; objc: 135; exp: 48; python: 12
file content (164 lines) | stat: -rw-r--r-- 3,325 bytes parent folder | download
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
// Make sure that the dead code of an `if` (and `else if`) is elminated when the condition is constant
// _only_ if the block does not contain any labels.
// For example,
// int a = 1;
// if (false) {
// L1:
//   a = 2;
// } else {
//   goto L1;
// }
// assert(a == 2);

// Note that a label is conssidered anything that lets us jump inside the body
// of the statement _apart from_ the actual statement (e.g. the `if).
// That generally is a normal label, but also specific cases for switch
// statements (see last tests).

// RUN: %ldc -O0 -output-ll -of=%t.ll %s && FileCheck %s < %t.ll

extern(C):  //to avoid name mangling.
// CHECK-LABEL: @foo
void foo()
{
    // CHECK: %a = alloca
    // CHECK: br
    int a;
    if (0)
    {
L1:
        a = 1;
    }
    else
    {
        goto L1;
    }
}

// CHECK-LABEL: @bar
void bar(int a, int b)
{
    int c;
    if (0)
    {
        switch (a) {
        case 10:
            while (b) {
            L2:
                // CHECK: store i32 10, i32* %c
                c = 10;
            }
        default: assert(0);
        }
    }
    else
    {
        goto L2;
    }
}

// CHECK-LABEL: @without_goto
void without_goto(int a, int b)
{
    int c;
    if (0)
    {
        switch (a) {
        case 10:
            while (b) {
            L2:
                // CHECK: store i32 10, i32* %c
                c = 10;
            }
        default: assert(0);
        }
    }
    else
    {
        a = 2;
    }
}

// CHECK-LABEL: @fourth
void fourth(int a, int b, int c)
{
    int j, d;
    if (a)
    {
        goto L3;
    }
    else if (false)
    {
        for (j = 0; j <= c; ++j)
        {
            // Can't `goto` in a foreach because
            // it always declares a variable.
            L3:
            foreach (i; 0..b)
            {
                // CHECK: store i32 10, i32* %d
                d = 10;
            }
        }
    }
}

// If a switch is outside the body of a statement "to-be-elided"
// but a case statement of it is inside that body, then that
// case acts as a label because we can jump inside the body without
// using the statement (i.e. using the switch to jump to the case).

// CHECK-LABEL: @case_as_label
void case_as_label(int a, int b)
{
    // Note the `CHECK-NOT` trickery.
    // CHECK-NOT: store i32 2, i32* %c
    // CHECK: store i32 3, i32* %c
    // CHECK-NOT: store i32 2, i32* %c
    // CHECK: store i32 4, i32* %c
    // CHECK-NOT: store i32 2, i32* %c
    int c;
    switch (a) {
    case 1:
        // Can elide
        if (false) {
            final switch (b) {
            case 2:
                c = 2;   
            }
        }
        goto case;
    case 2:
        // Can't elide
        if (false) {
    case 3:
            c = 3;
        }
        // Can't elide
        if (false) {
    default:
            c = 4;
        }
    }
}

// CHECK-LABEL: @case_as_label2
void case_as_label2(int a, int b)
{
    // CHECK: store i32 2, i32* %c
    // CHECK: store i32 3, i32* %c
    int c;
    final switch (a) {
        // Can't elide
        if (false) {
            final switch (b) {
            case 2:
                c = 2;   
            }
    // Test that `switch` in higher or equal nesting level
    // with a `case` does not impact the handling of `case`s.
    case 1:
        c = 3;
        }
    }
}