1
- // skip-filecheck
2
1
// unit-test: ReferencePropagation
3
2
// needs-unwind
4
3
9
8
fn opaque ( _: impl Sized ) { }
10
9
11
10
fn reference_propagation < ' a , T : Copy > ( single : & ' a T , mut multiple : & ' a T ) {
11
+ // CHECK-LABEL: fn reference_propagation(
12
+
12
13
// Propagation through a reference.
13
14
{
15
+ // CHECK: bb0: {
16
+ // CHECK: [[a:_.*]] = const 5_usize;
17
+ // CHECK: [[b:_.*]] = &[[a]];
18
+ // CHECK: [[c:_.*]] = [[a]];
19
+
14
20
let a = 5_usize ;
15
21
let b = & a; // This borrow is only used once.
16
22
let c = * b; // This should be optimized.
17
23
opaque ( ( ) ) ; // We use opaque to separate cases into basic blocks in the MIR.
18
24
}
19
25
20
- // Propagation through a two references.
26
+ // Propagation through two references.
21
27
{
28
+ // CHECK: bb1: {
29
+ // CHECK: [[a:_.*]] = const 5_usize;
30
+ // CHECK: [[a2:_.*]] = const 7_usize;
31
+ // CHECK: [[b:_.*]] = &[[a]];
32
+ // CHECK: [[btmp:_.*]] = &[[a2]];
33
+ // CHECK: [[b]] = move [[btmp]];
34
+ // CHECK: [[c:_.*]] = (*[[b]]);
35
+
22
36
let a = 5_usize ;
23
37
let a2 = 7_usize ;
24
38
let mut b = & a;
@@ -30,15 +44,27 @@ fn reference_propagation<'a, T: Copy>(single: &'a T, mut multiple: &'a T) {
30
44
31
45
// Propagation through a borrowed reference.
32
46
{
47
+ // CHECK: bb2: {
48
+ // CHECK: [[a:_.*]] = const 5_usize;
49
+ // CHECK: [[b:_.*]] = &[[a]];
50
+ // CHECK: [[d:_.*]] = &[[b]];
51
+ // CHECK: [[c:_.*]] = (*[[b]]);
52
+
33
53
let a = 5_usize ;
34
54
let b = & a;
35
55
let d = & b;
36
56
let c = * b; // `b` is immutably borrowed, we know its value, but do not propagate it
37
57
opaque ( d) ; // prevent `d` from being removed.
38
58
}
39
59
40
- // Propagation through a borrowed reference.
60
+ // Propagation through a mutably borrowed reference.
41
61
{
62
+ // CHECK: bb3: {
63
+ // CHECK: [[a:_.*]] = const 5_usize;
64
+ // CHECK: [[b:_.*]] = &[[a]];
65
+ // CHECK: [[d:_.*]] = &raw mut [[b]];
66
+ // CHECK: [[c:_.*]] = (*[[b]]);
67
+
42
68
let a = 5_usize ;
43
69
let mut b = & a;
44
70
let d = & raw mut b;
@@ -48,6 +74,11 @@ fn reference_propagation<'a, T: Copy>(single: &'a T, mut multiple: &'a T) {
48
74
49
75
// Propagation through an escaping borrow.
50
76
{
77
+ // CHECK: bb4: {
78
+ // CHECK: [[a:_.*]] = const 7_usize;
79
+ // CHECK: [[b:_.*]] = &[[a]];
80
+ // CHECK: [[c:_.*]] = [[a]];
81
+
51
82
let a = 7_usize ;
52
83
let b = & a;
53
84
let c = * b;
@@ -56,6 +87,14 @@ fn reference_propagation<'a, T: Copy>(single: &'a T, mut multiple: &'a T) {
56
87
57
88
// Propagation through a transitively escaping borrow.
58
89
{
90
+ // CHECK: bb5: {
91
+ // CHECK: [[a:_.*]] = const 7_usize;
92
+ // CHECK: [[b1:_.*]] = &[[a]];
93
+ // CHECK: [[c:_.*]] = [[a]];
94
+ // CHECK: [[b2:_.*]] = [[b1]];
95
+ // CHECK: [[c2:_.*]] = [[a]];
96
+ // CHECK: [[b3:_.*]] = [[b2]];
97
+
59
98
let a = 7_usize ;
60
99
let b1 = & a;
61
100
let c = * b1;
@@ -69,13 +108,23 @@ fn reference_propagation<'a, T: Copy>(single: &'a T, mut multiple: &'a T) {
69
108
70
109
// Propagation a reborrow of an argument.
71
110
{
111
+ // CHECK: bb6: {
112
+ // CHECK-NOT: {{_.*}} = &(*_1);
113
+ // CHECK: [[b:_.*]] = (*_1);
114
+
72
115
let a = & * single;
73
116
let b = * a; // This should be optimized as `*single`.
74
117
opaque ( ( ) ) ;
75
118
}
76
119
77
120
// Propagation a reborrow of a mutated argument.
78
121
{
122
+ // CHECK: bb7: {
123
+ // CHECK: [[a:_.*]] = &(*_2);
124
+ // CHECK: [[tmp:_.*]] = &(*_1);
125
+ // CHECK: _2 = move [[tmp]];
126
+ // CHECK: [[b:_.*]] = (*[[a]]);
127
+
79
128
let a = & * multiple;
80
129
multiple = & * single;
81
130
let b = * a; // This should not be optimized.
@@ -84,15 +133,29 @@ fn reference_propagation<'a, T: Copy>(single: &'a T, mut multiple: &'a T) {
84
133
85
134
// Fixed-point propagation through a borrowed reference.
86
135
{
136
+ // CHECK: bb8: {
137
+ // CHECK: [[a:_.*]] = const 5_usize;
138
+ // CHECK: [[b:_.*]] = &[[a]];
139
+ // CHECK: [[d:_.*]] = &[[b]];
140
+ // FIXME this could be [[a]]
141
+ // CHECK: [[c:_.*]] = (*[[b]]);
142
+
87
143
let a = 5_usize ;
88
144
let b = & a;
89
145
let d = & b; // first round promotes debuginfo for `d`
90
146
let c = * b; // second round propagates this dereference
91
147
opaque ( ( ) ) ;
92
148
}
93
149
94
- // Fixed-point propagation through a borrowed reference.
150
+ // Fixed-point propagation through a mutably borrowed reference.
95
151
{
152
+ // CHECK: bb9: {
153
+ // CHECK: [[a:_.*]] = const 5_usize;
154
+ // CHECK: [[b:_.*]] = &[[a]];
155
+ // CHECK: [[d:_.*]] = &mut [[b]];
156
+ // FIXME this could be [[a]]
157
+ // CHECK: [[c:_.*]] = (*[[b]]);
158
+
96
159
let a = 5_usize ;
97
160
let mut b = & a;
98
161
let d = & mut b; // first round promotes debuginfo for `d`
@@ -102,16 +165,31 @@ fn reference_propagation<'a, T: Copy>(single: &'a T, mut multiple: &'a T) {
102
165
}
103
166
104
167
fn reference_propagation_mut < ' a , T : Copy > ( single : & ' a mut T , mut multiple : & ' a mut T ) {
168
+ // CHECK-LABEL: fn reference_propagation_mut(
169
+
105
170
// Propagation through a reference.
106
171
{
172
+ // CHECK: bb0: {
173
+ // CHECK: [[a:_.*]] = const 5_usize;
174
+ // CHECK: [[b:_.*]] = &mut [[a]];
175
+ // CHECK: [[c:_.*]] = [[a]];
176
+
107
177
let mut a = 5_usize ;
108
178
let b = & mut a; // This borrow is only used once.
109
179
let c = * b; // This should be optimized.
110
180
opaque ( ( ) ) ;
111
181
}
112
182
113
- // Propagation through a two references.
183
+ // Propagation through two references.
114
184
{
185
+ // CHECK: bb1: {
186
+ // CHECK: [[a:_.*]] = const 5_usize;
187
+ // CHECK: [[a2:_.*]] = const 7_usize;
188
+ // CHECK: [[b:_.*]] = &mut [[a]];
189
+ // CHECK: [[btmp:_.*]] = &mut [[a2]];
190
+ // CHECK: [[b]] = move [[btmp]];
191
+ // CHECK: [[c:_.*]] = (*[[b]]);
192
+
115
193
let mut a = 5_usize ;
116
194
let mut a2 = 7_usize ;
117
195
let mut b = & mut a;
@@ -123,15 +201,27 @@ fn reference_propagation_mut<'a, T: Copy>(single: &'a mut T, mut multiple: &'a m
123
201
124
202
// Propagation through a borrowed reference.
125
203
{
204
+ // CHECK: bb2: {
205
+ // CHECK: [[a:_.*]] = const 5_usize;
206
+ // CHECK: [[b:_.*]] = &mut [[a]];
207
+ // CHECK: [[d:_.*]] = &[[b]];
208
+ // CHECK: [[c:_.*]] = (*[[b]]);
209
+
126
210
let mut a = 5_usize ;
127
211
let b = & mut a;
128
212
let d = & b;
129
213
let c = * b; // `b` is immutably borrowed, we know its value, but cannot be removed.
130
214
opaque ( d) ; // prevent `d` from being removed.
131
215
}
132
216
133
- // Propagation through a borrowed reference.
217
+ // Propagation through a mutably borrowed reference.
134
218
{
219
+ // CHECK: bb3: {
220
+ // CHECK: [[a:_.*]] = const 5_usize;
221
+ // CHECK: [[b:_.*]] = &mut [[a]];
222
+ // CHECK: [[d:_.*]] = &raw mut [[b]];
223
+ // CHECK: [[c:_.*]] = (*[[b]]);
224
+
135
225
let mut a = 5_usize ;
136
226
let mut b = & mut a;
137
227
let d = & raw mut b;
@@ -141,6 +231,11 @@ fn reference_propagation_mut<'a, T: Copy>(single: &'a mut T, mut multiple: &'a m
141
231
142
232
// Propagation through an escaping borrow.
143
233
{
234
+ // CHECK: bb4: {
235
+ // CHECK: [[a:_.*]] = const 7_usize;
236
+ // CHECK: [[b:_.*]] = &mut [[a]];
237
+ // CHECK: [[c:_.*]] = (*[[b]]);
238
+
144
239
let mut a = 7_usize ;
145
240
let b = & mut a;
146
241
let c = * b;
@@ -149,6 +244,14 @@ fn reference_propagation_mut<'a, T: Copy>(single: &'a mut T, mut multiple: &'a m
149
244
150
245
// Propagation through a transitively escaping borrow.
151
246
{
247
+ // CHECK: bb5: {
248
+ // CHECK: [[a:_.*]] = const 7_usize;
249
+ // CHECK: [[b1:_.*]] = &mut [[a]];
250
+ // CHECK: [[c:_.*]] = (*[[b1]]);
251
+ // CHECK: [[b2:_.*]] = move [[b1]];
252
+ // CHECK: [[c2:_.*]] = (*[[b2]]);
253
+ // CHECK: [[b3:_.*]] = move [[b2]];
254
+
152
255
let mut a = 7_usize ;
153
256
let b1 = & mut a;
154
257
let c = * b1;
@@ -162,13 +265,23 @@ fn reference_propagation_mut<'a, T: Copy>(single: &'a mut T, mut multiple: &'a m
162
265
163
266
// Propagation a reborrow of an argument.
164
267
{
268
+ // CHECK: bb6: {
269
+ // CHECK-NOT: {{_.*}} = &(*_1);
270
+ // CHECK: [[b:_.*]] = (*_1);
271
+
165
272
let a = & mut * single;
166
273
let b = * a; // This should be optimized as `*single`.
167
274
opaque ( ( ) ) ;
168
275
}
169
276
170
277
// Propagation a reborrow of a mutated argument.
171
278
{
279
+ // CHECK: bb7: {
280
+ // CHECK: [[a:_.*]] = &mut (*_2);
281
+ // CHECK: [[tmp:_.*]] = &mut (*_1);
282
+ // CHECK: _2 = move [[tmp]];
283
+ // CHECK: [[b:_.*]] = (*[[a]]);
284
+
172
285
let a = & mut * multiple;
173
286
multiple = & mut * single;
174
287
let b = * a; // This should not be optimized.
@@ -177,15 +290,29 @@ fn reference_propagation_mut<'a, T: Copy>(single: &'a mut T, mut multiple: &'a m
177
290
178
291
// Fixed-point propagation through a borrowed reference.
179
292
{
293
+ // CHECK: bb8: {
294
+ // CHECK: [[a:_.*]] = const 5_usize;
295
+ // CHECK: [[b:_.*]] = &mut [[a]];
296
+ // CHECK: [[d:_.*]] = &[[b]];
297
+ // FIXME this could be [[a]]
298
+ // CHECK: [[c:_.*]] = (*[[b]]);
299
+
180
300
let mut a = 5_usize ;
181
301
let b = & mut a;
182
302
let d = & b; // first round promotes debuginfo for `d`
183
303
let c = * b; // second round propagates this dereference
184
304
opaque ( ( ) ) ;
185
305
}
186
306
187
- // Fixed-point propagation through a borrowed reference.
307
+ // Fixed-point propagation through a mutably borrowed reference.
188
308
{
309
+ // CHECK: bb9: {
310
+ // CHECK: [[a:_.*]] = const 5_usize;
311
+ // CHECK: [[b:_.*]] = &mut [[a]];
312
+ // CHECK: [[d:_.*]] = &mut [[b]];
313
+ // FIXME this could be [[a]]
314
+ // CHECK: [[c:_.*]] = (*[[b]]);
315
+
189
316
let mut a = 5_usize ;
190
317
let mut b = & mut a;
191
318
let d = & mut b; // first round promotes debuginfo for `d`
@@ -195,16 +322,31 @@ fn reference_propagation_mut<'a, T: Copy>(single: &'a mut T, mut multiple: &'a m
195
322
}
196
323
197
324
fn reference_propagation_const_ptr < T : Copy > ( single : * const T , mut multiple : * const T ) {
325
+ // CHECK-LABEL: fn reference_propagation_const_ptr(
326
+
198
327
// Propagation through a reference.
199
328
unsafe {
329
+ // CHECK: bb0: {
330
+ // CHECK: [[a:_.*]] = const 5_usize;
331
+ // CHECK: [[b:_.*]] = &raw const [[a]];
332
+ // CHECK: [[c:_.*]] = [[a]];
333
+
200
334
let a = 5_usize ;
201
335
let b = & raw const a; // This borrow is only used once.
202
336
let c = * b; // This should be optimized.
203
337
opaque ( ( ) ) ;
204
338
}
205
339
206
- // Propagation through a two references.
340
+ // Propagation through two references.
207
341
unsafe {
342
+ // CHECK: bb1: {
343
+ // CHECK: [[a:_.*]] = const 5_usize;
344
+ // CHECK: [[a2:_.*]] = const 7_usize;
345
+ // CHECK: [[b:_.*]] = &raw const [[a]];
346
+ // CHECK: [[btmp:_.*]] = &raw const [[a2]];
347
+ // CHECK: [[b]] = move [[btmp]];
348
+ // CHECK: [[c:_.*]] = (*[[b]]);
349
+
208
350
let a = 5_usize ;
209
351
let a2 = 7_usize ;
210
352
let mut b = & raw const a;
@@ -216,15 +358,27 @@ fn reference_propagation_const_ptr<T: Copy>(single: *const T, mut multiple: *con
216
358
217
359
// Propagation through a borrowed reference.
218
360
unsafe {
361
+ // CHECK: bb2: {
362
+ // CHECK: [[a:_.*]] = const 5_usize;
363
+ // CHECK: [[b:_.*]] = &raw const [[a]];
364
+ // CHECK: [[d:_.*]] = &[[b]];
365
+ // CHECK: [[c:_.*]] = (*[[b]]);
366
+
219
367
let a = 5_usize ;
220
368
let b = & raw const a;
221
369
let d = & b;
222
370
let c = * b; // `b` is immutably borrowed, we know its value, but cannot be removed.
223
371
opaque ( d) ; // prevent `d` from being removed.
224
372
}
225
373
226
- // Propagation through a borrowed reference.
374
+ // Propagation through a mutably borrowed reference.
227
375
unsafe {
376
+ // CHECK: bb3: {
377
+ // CHECK: [[a:_.*]] = const 5_usize;
378
+ // CHECK: [[b:_.*]] = &raw const [[a]];
379
+ // CHECK: [[d:_.*]] = &raw mut [[b]];
380
+ // CHECK: [[c:_.*]] = (*[[b]]);
381
+
228
382
let a = 5_usize ;
229
383
let mut b = & raw const a;
230
384
let d = & raw mut b;
@@ -234,6 +388,11 @@ fn reference_propagation_const_ptr<T: Copy>(single: *const T, mut multiple: *con
234
388
235
389
// Propagation through an escaping borrow.
236
390
unsafe {
391
+ // CHECK: bb4: {
392
+ // CHECK: [[a:_.*]] = const 7_usize;
393
+ // CHECK: [[b:_.*]] = &raw const [[a]];
394
+ // CHECK: [[c:_.*]] = [[a]];
395
+
237
396
let a = 7_usize ;
238
397
let b = & raw const a;
239
398
let c = * b;
@@ -242,6 +401,14 @@ fn reference_propagation_const_ptr<T: Copy>(single: *const T, mut multiple: *con
242
401
243
402
// Propagation through a transitively escaping borrow.
244
403
unsafe {
404
+ // CHECK: bb5: {
405
+ // CHECK: [[a:_.*]] = const 7_usize;
406
+ // CHECK: [[b1:_.*]] = &raw const [[a]];
407
+ // CHECK: [[c:_.*]] = [[a]];
408
+ // CHECK: [[b2:_.*]] = [[b1]];
409
+ // CHECK: [[c2:_.*]] = [[a]];
410
+ // CHECK: [[b3:_.*]] = [[b2]];
411
+
245
412
let a = 7_usize ;
246
413
let b1 = & raw const a;
247
414
let c = * b1;
@@ -255,13 +422,23 @@ fn reference_propagation_const_ptr<T: Copy>(single: *const T, mut multiple: *con
255
422
256
423
// Propagation a reborrow of an argument.
257
424
unsafe {
425
+ // CHECK: bb6: {
426
+ // CHECK-NOT: {{_.*}} = &(*_1);
427
+ // CHECK: [[b:_.*]] = (*_1);
428
+
258
429
let a = & raw const * single;
259
430
let b = * a; // This should be optimized as `*single`.
260
431
opaque ( ( ) ) ;
261
432
}
262
433
263
434
// Propagation a reborrow of a mutated argument.
264
435
unsafe {
436
+ // CHECK: bb7: {
437
+ // CHECK: [[a:_.*]] = &raw const (*_2);
438
+ // CHECK: [[tmp:_.*]] = &raw const (*_1);
439
+ // CHECK: _2 = move [[tmp]];
440
+ // CHECK: [[b:_.*]] = (*[[a]]);
441
+
265
442
let a = & raw const * multiple;
266
443
multiple = & raw const * single;
267
444
let b = * a; // This should not be optimized.
@@ -270,6 +447,12 @@ fn reference_propagation_const_ptr<T: Copy>(single: *const T, mut multiple: *con
270
447
271
448
// Propagation through a reborrow.
272
449
unsafe {
450
+ // CHECK: bb8: {
451
+ // CHECK: [[a:_.*]] = const 13_usize;
452
+ // CHECK: [[b:_.*]] = &raw const [[a]];
453
+ // CHECK: [[d:_.*]] = &raw const [[a]];
454
+ // CHECK: [[c:_.*]] = [[a]];
455
+
273
456
let a = 13_usize ;
274
457
let b = & raw const a;
275
458
let c = & raw const * b;
@@ -279,6 +462,13 @@ fn reference_propagation_const_ptr<T: Copy>(single: *const T, mut multiple: *con
279
462
280
463
// Fixed-point propagation through a borrowed reference.
281
464
unsafe {
465
+ // CHECK: bb9: {
466
+ // CHECK: [[a:_.*]] = const 5_usize;
467
+ // CHECK: [[b:_.*]] = &raw const [[a]];
468
+ // CHECK: [[d:_.*]] = &[[b]];
469
+ // FIXME this could be [[a]]
470
+ // CHECK: [[c:_.*]] = (*[[b]]);
471
+
282
472
let a = 5_usize ;
283
473
let b = & raw const a;
284
474
let d = & b; // first round promotes debuginfo for `d`
@@ -288,6 +478,13 @@ fn reference_propagation_const_ptr<T: Copy>(single: *const T, mut multiple: *con
288
478
289
479
// Fixed-point propagation through a borrowed reference.
290
480
unsafe {
481
+ // CHECK: bb10: {
482
+ // CHECK: [[a:_.*]] = const 5_usize;
483
+ // CHECK: [[b:_.*]] = &raw const [[a]];
484
+ // CHECK: [[d:_.*]] = &mut [[b]];
485
+ // FIXME this could be [[a]]
486
+ // CHECK: [[c:_.*]] = (*[[b]]);
487
+
291
488
let a = 5_usize ;
292
489
let mut b = & raw const a;
293
490
let d = & mut b; // first round promotes debuginfo for `d`
@@ -297,16 +494,31 @@ fn reference_propagation_const_ptr<T: Copy>(single: *const T, mut multiple: *con
297
494
}
298
495
299
496
fn reference_propagation_mut_ptr < T : Copy > ( single : * mut T , mut multiple : * mut T ) {
497
+ // CHECK-LABEL: fn reference_propagation_mut_ptr(
498
+
300
499
// Propagation through a reference.
301
500
unsafe {
501
+ // CHECK: bb0: {
502
+ // CHECK: [[a:_.*]] = const 5_usize;
503
+ // CHECK: [[b:_.*]] = &raw mut [[a]];
504
+ // CHECK: [[c:_.*]] = [[a]];
505
+
302
506
let mut a = 5_usize ;
303
507
let b = & raw mut a; // This borrow is only used once.
304
508
let c = * b; // This should be optimized.
305
509
opaque ( ( ) ) ;
306
510
}
307
511
308
- // Propagation through a two references.
512
+ // Propagation through two references.
309
513
unsafe {
514
+ // CHECK: bb1: {
515
+ // CHECK: [[a:_.*]] = const 5_usize;
516
+ // CHECK: [[a2:_.*]] = const 7_usize;
517
+ // CHECK: [[b:_.*]] = &raw mut [[a]];
518
+ // CHECK: [[btmp:_.*]] = &raw mut [[a2]];
519
+ // CHECK: [[b]] = move [[btmp]];
520
+ // CHECK: [[c:_.*]] = (*[[b]]);
521
+
310
522
let mut a = 5_usize ;
311
523
let mut a2 = 7_usize ;
312
524
let mut b = & raw mut a;
@@ -318,15 +530,27 @@ fn reference_propagation_mut_ptr<T: Copy>(single: *mut T, mut multiple: *mut T)
318
530
319
531
// Propagation through a borrowed reference.
320
532
unsafe {
533
+ // CHECK: bb2: {
534
+ // CHECK: [[a:_.*]] = const 5_usize;
535
+ // CHECK: [[b:_.*]] = &raw mut [[a]];
536
+ // CHECK: [[d:_.*]] = &[[b]];
537
+ // CHECK: [[c:_.*]] = (*[[b]]);
538
+
321
539
let mut a = 5_usize ;
322
540
let b = & raw mut a;
323
541
let d = & b;
324
542
let c = * b; // `b` is immutably borrowed, we know its value, but cannot be removed.
325
543
opaque ( d) ; // prevent `d` from being removed.
326
544
}
327
545
328
- // Propagation through a borrowed reference.
546
+ // Propagation through a mutably borrowed reference.
329
547
unsafe {
548
+ // CHECK: bb3: {
549
+ // CHECK: [[a:_.*]] = const 5_usize;
550
+ // CHECK: [[b:_.*]] = &raw mut [[a]];
551
+ // CHECK: [[d:_.*]] = &raw mut [[b]];
552
+ // CHECK: [[c:_.*]] = (*[[b]]);
553
+
330
554
let mut a = 5_usize ;
331
555
let mut b = & raw mut a;
332
556
let d = & raw mut b;
@@ -336,6 +560,11 @@ fn reference_propagation_mut_ptr<T: Copy>(single: *mut T, mut multiple: *mut T)
336
560
337
561
// Propagation through an escaping borrow.
338
562
unsafe {
563
+ // CHECK: bb4: {
564
+ // CHECK: [[a:_.*]] = const 7_usize;
565
+ // CHECK: [[b:_.*]] = &raw mut [[a]];
566
+ // CHECK: [[c:_.*]] = (*[[b]]);
567
+
339
568
let mut a = 7_usize ;
340
569
let b = & raw mut a;
341
570
let c = * b;
@@ -344,6 +573,14 @@ fn reference_propagation_mut_ptr<T: Copy>(single: *mut T, mut multiple: *mut T)
344
573
345
574
// Propagation through a transitively escaping borrow.
346
575
unsafe {
576
+ // CHECK: bb5: {
577
+ // CHECK: [[a:_.*]] = const 7_usize;
578
+ // CHECK: [[b1:_.*]] = &raw mut [[a]];
579
+ // CHECK: [[c:_.*]] = (*[[b1]]);
580
+ // CHECK: [[b2:_.*]] = [[b1]];
581
+ // CHECK: [[c2:_.*]] = (*[[b2]]);
582
+ // CHECK: [[b3:_.*]] = [[b2]];
583
+
347
584
let mut a = 7_usize ;
348
585
let b1 = & raw mut a;
349
586
let c = * b1;
@@ -357,13 +594,23 @@ fn reference_propagation_mut_ptr<T: Copy>(single: *mut T, mut multiple: *mut T)
357
594
358
595
// Propagation a reborrow of an argument.
359
596
unsafe {
597
+ // CHECK: bb6: {
598
+ // CHECK-NOT: {{_.*}} = &(*_1);
599
+ // CHECK: [[b:_.*]] = (*_1);
600
+
360
601
let a = & raw mut * single;
361
602
let b = * a; // This should be optimized as `*single`.
362
603
opaque ( ( ) ) ;
363
604
}
364
605
365
606
// Propagation a reborrow of a mutated argument.
366
607
unsafe {
608
+ // CHECK: bb7: {
609
+ // CHECK: [[a:_.*]] = &raw mut (*_2);
610
+ // CHECK: [[tmp:_.*]] = &raw mut (*_1);
611
+ // CHECK: _2 = move [[tmp]];
612
+ // CHECK: [[b:_.*]] = (*[[a]]);
613
+
367
614
let a = & raw mut * multiple;
368
615
multiple = & raw mut * single;
369
616
let b = * a; // This should not be optimized.
@@ -372,15 +619,29 @@ fn reference_propagation_mut_ptr<T: Copy>(single: *mut T, mut multiple: *mut T)
372
619
373
620
// Fixed-point propagation through a borrowed reference.
374
621
unsafe {
622
+ // CHECK: bb8: {
623
+ // CHECK: [[a:_.*]] = const 5_usize;
624
+ // CHECK: [[b:_.*]] = &raw mut [[a]];
625
+ // CHECK: [[d:_.*]] = &[[b]];
626
+ // FIXME this could be [[a]]
627
+ // CHECK: [[c:_.*]] = (*[[b]]);
628
+
375
629
let mut a = 5_usize ;
376
630
let b = & raw mut a;
377
631
let d = & b; // first round promotes debuginfo for `d`
378
632
let c = * b; // second round propagates this dereference
379
633
opaque ( ( ) ) ;
380
634
}
381
635
382
- // Fixed-point propagation through a borrowed reference.
636
+ // Fixed-point propagation through a mutably borrowed reference.
383
637
unsafe {
638
+ // CHECK: bb9: {
639
+ // CHECK: [[a:_.*]] = const 5_usize;
640
+ // CHECK: [[b:_.*]] = &raw mut [[a]];
641
+ // CHECK: [[d:_.*]] = &mut [[b]];
642
+ // FIXME this could be [[a]]
643
+ // CHECK: [[c:_.*]] = (*[[b]]);
644
+
384
645
let mut a = 5_usize ;
385
646
let mut b = & raw mut a;
386
647
let d = & mut b; // first round promotes debuginfo for `d`
@@ -391,8 +652,13 @@ fn reference_propagation_mut_ptr<T: Copy>(single: *mut T, mut multiple: *mut T)
391
652
392
653
#[ custom_mir( dialect = "runtime" , phase = "post-cleanup" ) ]
393
654
fn read_through_raw ( x : & mut usize ) -> usize {
394
- use std:: intrinsics:: mir:: * ;
655
+ // CHECK-LABEL: read_through_raw
656
+ // CHECK: bb0: {
657
+ // CHECK-NEXT: _0 = (*_1);
658
+ // CHECK-NEXT: _0 = (*_1);
659
+ // CHECK-NEXT: return;
395
660
661
+ use std:: intrinsics:: mir:: * ;
396
662
mir ! (
397
663
let r1: & mut usize ;
398
664
let r2: & mut usize ;
@@ -414,8 +680,10 @@ fn read_through_raw(x: &mut usize) -> usize {
414
680
415
681
#[ custom_mir( dialect = "runtime" , phase = "post-cleanup" ) ]
416
682
fn multiple_storage ( ) {
417
- use std:: intrinsics:: mir:: * ;
683
+ // CHECK-LABEL: multiple_storage
684
+ // CHECK: _3 = (*_2);
418
685
686
+ use std:: intrinsics:: mir:: * ;
419
687
mir ! (
420
688
let x: i32 ;
421
689
{
@@ -438,8 +706,10 @@ fn multiple_storage() {
438
706
439
707
#[ custom_mir( dialect = "runtime" , phase = "post-cleanup" ) ]
440
708
fn dominate_storage ( ) {
441
- use std:: intrinsics:: mir:: * ;
709
+ // CHECK-LABEL: dominate_storage
710
+ // CHECK: _5 = (*_2);
442
711
712
+ use std:: intrinsics:: mir:: * ;
443
713
mir ! (
444
714
let x: i32 ;
445
715
let r: & i32 ;
@@ -466,8 +736,10 @@ fn dominate_storage() {
466
736
467
737
#[ custom_mir( dialect = "runtime" , phase = "post-cleanup" ) ]
468
738
fn maybe_dead ( m : bool ) {
469
- use std:: intrinsics:: mir:: * ;
739
+ // CHECK-LABEL: fn maybe_dead(
740
+ // CHECK: (*_5) = const 7_i32;
470
741
742
+ use std:: intrinsics:: mir:: * ;
471
743
mir ! (
472
744
let x: i32 ;
473
745
let y: i32 ;
@@ -507,6 +779,9 @@ fn maybe_dead(m: bool) {
507
779
}
508
780
509
781
fn mut_raw_then_mut_shr ( ) -> ( i32 , i32 ) {
782
+ // CHECK-LABEL: fn mut_raw_then_mut_shr(
783
+ // CHECK-NOT: (*{{_.*}})
784
+
510
785
let mut x = 2 ;
511
786
let xref = & mut x;
512
787
let xraw = & mut * xref as * mut _ ;
@@ -518,6 +793,18 @@ fn mut_raw_then_mut_shr() -> (i32, i32) {
518
793
}
519
794
520
795
fn unique_with_copies ( ) {
796
+ // CHECK-LABEL: fn unique_with_copies(
797
+ // CHECK: [[a:_.*]] = const 0_i32;
798
+ // CHECK: [[x:_.*]] = &raw mut [[a]];
799
+ // CHECK-NOT: [[a]]
800
+ // CHECK: [[tmp:_.*]] = (*[[x]]);
801
+ // CHECK-NEXT: opaque::<i32>(move [[tmp]])
802
+ // CHECK-NOT: [[a]]
803
+ // CHECK: StorageDead([[a]]);
804
+ // CHECK-NOT: [[a]]
805
+ // CHECK: [[tmp:_.*]] = (*[[x]]);
806
+ // CHECK-NEXT: opaque::<i32>(move [[tmp]])
807
+
521
808
let y = {
522
809
let mut a = 0 ;
523
810
let x = & raw mut a;
@@ -530,6 +817,17 @@ fn unique_with_copies() {
530
817
}
531
818
532
819
fn debuginfo ( ) {
820
+ // CHECK-LABEL: fn debuginfo(
821
+ // FIXME: This features waits for DWARF implicit pointers in LLVM.
822
+ // CHECK: debug ref_mut_u8 => _{{.*}};
823
+ // CHECK: debug field => _{{.*}};
824
+ // CHECK: debug reborrow => _{{.*}};
825
+ // CHECK: debug variant_field => _{{.*}};
826
+ // CHECK: debug constant_index => _{{.*}};
827
+ // CHECK: debug subslice => _{{.*}};
828
+ // CHECK: debug constant_index_from_end => _{{.*}};
829
+ // CHECK: debug multiple_borrow => _{{.*}};
830
+
533
831
struct T ( u8 ) ;
534
832
535
833
let ref_mut_u8 = & mut 5_u8 ;
@@ -552,6 +850,10 @@ fn debuginfo() {
552
850
}
553
851
554
852
fn many_debuginfo ( ) {
853
+ // CHECK-LABEL: fn many_debuginfo(
854
+ // FIXME: This features waits for DWARF implicit pointers in LLVM.
855
+ // CHECK: debug many_borrow => _{{.*}};
856
+
555
857
let a = 0 ;
556
858
557
859
// Verify that we do not ICE on deeply nested borrows.
@@ -591,3 +893,4 @@ fn main() {
591
893
// EMIT_MIR reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff
592
894
// EMIT_MIR reference_prop.unique_with_copies.ReferencePropagation.diff
593
895
// EMIT_MIR reference_prop.debuginfo.ReferencePropagation.diff
896
+ // CHECK-LABEL: fn main(
0 commit comments