@@ -41,12 +41,32 @@ impl ArgAttributeExt for ArgAttribute {
41
41
}
42
42
43
43
pub trait ArgAttributesExt {
44
- fn apply_attrs_to_llfn ( & self , idx : AttributePlace , llfn : & Value ) ;
45
- fn apply_attrs_to_callsite ( & self , idx : AttributePlace , callsite : & Value ) ;
44
+ fn apply_attrs_to_llfn ( & self , idx : AttributePlace , cx : & CodegenCx < ' _ , ' _ > , llfn : & Value ) ;
45
+ fn apply_attrs_to_callsite (
46
+ & self ,
47
+ idx : AttributePlace ,
48
+ cx : & CodegenCx < ' _ , ' _ > ,
49
+ callsite : & Value ,
50
+ ) ;
51
+ }
52
+
53
+ fn should_use_mutable_noalias ( cx : & CodegenCx < ' _ , ' _ > ) -> bool {
54
+ // Previously we would only emit noalias annotations for LLVM >= 6 or in
55
+ // panic=abort mode. That was deemed right, as prior versions had many bugs
56
+ // in conjunction with unwinding, but later versions didn’t seem to have
57
+ // said issues. See issue #31681.
58
+ //
59
+ // Alas, later on we encountered a case where noalias would generate wrong
60
+ // code altogether even with recent versions of LLVM in *safe* code with no
61
+ // unwinding involved. See #54462.
62
+ //
63
+ // For now, do not enable mutable_noalias by default at all, while the
64
+ // issue is being figured out.
65
+ cx. tcx . sess . opts . debugging_opts . mutable_noalias
46
66
}
47
67
48
68
impl ArgAttributesExt for ArgAttributes {
49
- fn apply_attrs_to_llfn ( & self , idx : AttributePlace , llfn : & Value ) {
69
+ fn apply_attrs_to_llfn ( & self , idx : AttributePlace , cx : & CodegenCx < ' _ , ' _ > , llfn : & Value ) {
50
70
let mut regular = self . regular ;
51
71
unsafe {
52
72
let deref = self . pointee_size . bytes ( ) ;
@@ -62,6 +82,9 @@ impl ArgAttributesExt for ArgAttributes {
62
82
llvm:: LLVMRustAddAlignmentAttr ( llfn, idx. as_uint ( ) , align. bytes ( ) as u32 ) ;
63
83
}
64
84
regular. for_each_kind ( |attr| attr. apply_llfn ( idx, llfn) ) ;
85
+ if regular. contains ( ArgAttribute :: NoAliasMutRef ) && should_use_mutable_noalias ( cx) {
86
+ llvm:: Attribute :: NoAlias . apply_llfn ( idx, llfn) ;
87
+ }
65
88
match self . arg_ext {
66
89
ArgExtension :: None => { }
67
90
ArgExtension :: Zext => {
@@ -74,7 +97,12 @@ impl ArgAttributesExt for ArgAttributes {
74
97
}
75
98
}
76
99
77
- fn apply_attrs_to_callsite ( & self , idx : AttributePlace , callsite : & Value ) {
100
+ fn apply_attrs_to_callsite (
101
+ & self ,
102
+ idx : AttributePlace ,
103
+ cx : & CodegenCx < ' _ , ' _ > ,
104
+ callsite : & Value ,
105
+ ) {
78
106
let mut regular = self . regular ;
79
107
unsafe {
80
108
let deref = self . pointee_size . bytes ( ) ;
@@ -98,6 +126,9 @@ impl ArgAttributesExt for ArgAttributes {
98
126
) ;
99
127
}
100
128
regular. for_each_kind ( |attr| attr. apply_callsite ( idx, callsite) ) ;
129
+ if regular. contains ( ArgAttribute :: NoAliasMutRef ) && should_use_mutable_noalias ( cx) {
130
+ llvm:: Attribute :: NoAlias . apply_callsite ( idx, callsite) ;
131
+ }
101
132
match self . arg_ext {
102
133
ArgExtension :: None => { }
103
134
ArgExtension :: Zext => {
@@ -419,13 +450,13 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
419
450
420
451
let mut i = 0 ;
421
452
let mut apply = |attrs : & ArgAttributes | {
422
- attrs. apply_attrs_to_llfn ( llvm:: AttributePlace :: Argument ( i) , llfn) ;
453
+ attrs. apply_attrs_to_llfn ( llvm:: AttributePlace :: Argument ( i) , cx , llfn) ;
423
454
i += 1 ;
424
455
i - 1
425
456
} ;
426
457
match self . ret . mode {
427
458
PassMode :: Direct ( ref attrs) => {
428
- attrs. apply_attrs_to_llfn ( llvm:: AttributePlace :: ReturnValue , llfn) ;
459
+ attrs. apply_attrs_to_llfn ( llvm:: AttributePlace :: ReturnValue , cx , llfn) ;
429
460
}
430
461
PassMode :: Indirect { ref attrs, extra_attrs : _, on_stack } => {
431
462
assert ! ( !on_stack) ;
@@ -480,18 +511,18 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
480
511
// FIXME(wesleywiser, eddyb): We should apply `nounwind` and `noreturn` as appropriate to this callsite.
481
512
482
513
let mut i = 0 ;
483
- let mut apply = |attrs : & ArgAttributes | {
484
- attrs. apply_attrs_to_callsite ( llvm:: AttributePlace :: Argument ( i) , callsite) ;
514
+ let mut apply = |cx : & CodegenCx < ' _ , ' _ > , attrs : & ArgAttributes | {
515
+ attrs. apply_attrs_to_callsite ( llvm:: AttributePlace :: Argument ( i) , cx , callsite) ;
485
516
i += 1 ;
486
517
i - 1
487
518
} ;
488
519
match self . ret . mode {
489
520
PassMode :: Direct ( ref attrs) => {
490
- attrs. apply_attrs_to_callsite ( llvm:: AttributePlace :: ReturnValue , callsite) ;
521
+ attrs. apply_attrs_to_callsite ( llvm:: AttributePlace :: ReturnValue , & bx . cx , callsite) ;
491
522
}
492
523
PassMode :: Indirect { ref attrs, extra_attrs : _, on_stack } => {
493
524
assert ! ( !on_stack) ;
494
- let i = apply ( attrs) ;
525
+ let i = apply ( bx . cx , attrs) ;
495
526
unsafe {
496
527
llvm:: LLVMRustAddStructRetCallSiteAttr (
497
528
callsite,
@@ -517,12 +548,12 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
517
548
}
518
549
for arg in & self . args {
519
550
if arg. pad . is_some ( ) {
520
- apply ( & ArgAttributes :: new ( ) ) ;
551
+ apply ( bx . cx , & ArgAttributes :: new ( ) ) ;
521
552
}
522
553
match arg. mode {
523
554
PassMode :: Ignore => { }
524
555
PassMode :: Indirect { ref attrs, extra_attrs : None , on_stack : true } => {
525
- let i = apply ( attrs) ;
556
+ let i = apply ( bx . cx , attrs) ;
526
557
unsafe {
527
558
llvm:: LLVMRustAddByValCallSiteAttr (
528
559
callsite,
@@ -533,22 +564,22 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
533
564
}
534
565
PassMode :: Direct ( ref attrs)
535
566
| PassMode :: Indirect { ref attrs, extra_attrs : None , on_stack : false } => {
536
- apply ( attrs) ;
567
+ apply ( bx . cx , attrs) ;
537
568
}
538
569
PassMode :: Indirect {
539
570
ref attrs,
540
571
extra_attrs : Some ( ref extra_attrs) ,
541
572
on_stack : _,
542
573
} => {
543
- apply ( attrs) ;
544
- apply ( extra_attrs) ;
574
+ apply ( bx . cx , attrs) ;
575
+ apply ( bx . cx , extra_attrs) ;
545
576
}
546
577
PassMode :: Pair ( ref a, ref b) => {
547
- apply ( a) ;
548
- apply ( b) ;
578
+ apply ( bx . cx , a) ;
579
+ apply ( bx . cx , b) ;
549
580
}
550
581
PassMode :: Cast ( _) => {
551
- apply ( & ArgAttributes :: new ( ) ) ;
582
+ apply ( bx . cx , & ArgAttributes :: new ( ) ) ;
552
583
}
553
584
}
554
585
}
0 commit comments