1
1
use crate :: builder:: Builder ;
2
2
use crate :: context:: CodegenCx ;
3
3
use crate :: llvm:: { self , AttributePlace } ;
4
+ use crate :: llvm_util;
4
5
use crate :: type_:: Type ;
5
6
use crate :: type_of:: LayoutLlvmExt ;
6
7
use crate :: value:: Value ;
@@ -41,12 +42,29 @@ impl ArgAttributeExt for ArgAttribute {
41
42
}
42
43
43
44
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 ) ;
45
+ fn apply_attrs_to_llfn ( & self , idx : AttributePlace , cx : & CodegenCx < ' _ , ' _ > , llfn : & Value ) ;
46
+ fn apply_attrs_to_callsite (
47
+ & self ,
48
+ idx : AttributePlace ,
49
+ cx : & CodegenCx < ' _ , ' _ > ,
50
+ callsite : & Value ,
51
+ ) ;
52
+ }
53
+
54
+ fn should_use_mutable_noalias ( cx : & CodegenCx < ' _ , ' _ > ) -> bool {
55
+ // LLVM prior to version 12 has known miscompiles in the presence of
56
+ // noalias attributes (see #54878). Only enable mutable noalias by
57
+ // default for versions we believe to be safe.
58
+ cx. tcx
59
+ . sess
60
+ . opts
61
+ . debugging_opts
62
+ . mutable_noalias
63
+ . unwrap_or_else ( || llvm_util:: get_version ( ) >= ( 12 , 0 , 0 ) )
46
64
}
47
65
48
66
impl ArgAttributesExt for ArgAttributes {
49
- fn apply_attrs_to_llfn ( & self , idx : AttributePlace , llfn : & Value ) {
67
+ fn apply_attrs_to_llfn ( & self , idx : AttributePlace , cx : & CodegenCx < ' _ , ' _ > , llfn : & Value ) {
50
68
let mut regular = self . regular ;
51
69
unsafe {
52
70
let deref = self . pointee_size . bytes ( ) ;
@@ -62,6 +80,9 @@ impl ArgAttributesExt for ArgAttributes {
62
80
llvm:: LLVMRustAddAlignmentAttr ( llfn, idx. as_uint ( ) , align. bytes ( ) as u32 ) ;
63
81
}
64
82
regular. for_each_kind ( |attr| attr. apply_llfn ( idx, llfn) ) ;
83
+ if regular. contains ( ArgAttribute :: NoAliasMutRef ) && should_use_mutable_noalias ( cx) {
84
+ llvm:: Attribute :: NoAlias . apply_llfn ( idx, llfn) ;
85
+ }
65
86
match self . arg_ext {
66
87
ArgExtension :: None => { }
67
88
ArgExtension :: Zext => {
@@ -74,7 +95,12 @@ impl ArgAttributesExt for ArgAttributes {
74
95
}
75
96
}
76
97
77
- fn apply_attrs_to_callsite ( & self , idx : AttributePlace , callsite : & Value ) {
98
+ fn apply_attrs_to_callsite (
99
+ & self ,
100
+ idx : AttributePlace ,
101
+ cx : & CodegenCx < ' _ , ' _ > ,
102
+ callsite : & Value ,
103
+ ) {
78
104
let mut regular = self . regular ;
79
105
unsafe {
80
106
let deref = self . pointee_size . bytes ( ) ;
@@ -98,6 +124,9 @@ impl ArgAttributesExt for ArgAttributes {
98
124
) ;
99
125
}
100
126
regular. for_each_kind ( |attr| attr. apply_callsite ( idx, callsite) ) ;
127
+ if regular. contains ( ArgAttribute :: NoAliasMutRef ) && should_use_mutable_noalias ( cx) {
128
+ llvm:: Attribute :: NoAlias . apply_callsite ( idx, callsite) ;
129
+ }
101
130
match self . arg_ext {
102
131
ArgExtension :: None => { }
103
132
ArgExtension :: Zext => {
@@ -419,13 +448,13 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
419
448
420
449
let mut i = 0 ;
421
450
let mut apply = |attrs : & ArgAttributes | {
422
- attrs. apply_attrs_to_llfn ( llvm:: AttributePlace :: Argument ( i) , llfn) ;
451
+ attrs. apply_attrs_to_llfn ( llvm:: AttributePlace :: Argument ( i) , cx , llfn) ;
423
452
i += 1 ;
424
453
i - 1
425
454
} ;
426
455
match self . ret . mode {
427
456
PassMode :: Direct ( ref attrs) => {
428
- attrs. apply_attrs_to_llfn ( llvm:: AttributePlace :: ReturnValue , llfn) ;
457
+ attrs. apply_attrs_to_llfn ( llvm:: AttributePlace :: ReturnValue , cx , llfn) ;
429
458
}
430
459
PassMode :: Indirect { ref attrs, extra_attrs : _, on_stack } => {
431
460
assert ! ( !on_stack) ;
@@ -480,18 +509,18 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
480
509
// FIXME(wesleywiser, eddyb): We should apply `nounwind` and `noreturn` as appropriate to this callsite.
481
510
482
511
let mut i = 0 ;
483
- let mut apply = |attrs : & ArgAttributes | {
484
- attrs. apply_attrs_to_callsite ( llvm:: AttributePlace :: Argument ( i) , callsite) ;
512
+ let mut apply = |cx : & CodegenCx < ' _ , ' _ > , attrs : & ArgAttributes | {
513
+ attrs. apply_attrs_to_callsite ( llvm:: AttributePlace :: Argument ( i) , cx , callsite) ;
485
514
i += 1 ;
486
515
i - 1
487
516
} ;
488
517
match self . ret . mode {
489
518
PassMode :: Direct ( ref attrs) => {
490
- attrs. apply_attrs_to_callsite ( llvm:: AttributePlace :: ReturnValue , callsite) ;
519
+ attrs. apply_attrs_to_callsite ( llvm:: AttributePlace :: ReturnValue , & bx . cx , callsite) ;
491
520
}
492
521
PassMode :: Indirect { ref attrs, extra_attrs : _, on_stack } => {
493
522
assert ! ( !on_stack) ;
494
- let i = apply ( attrs) ;
523
+ let i = apply ( bx . cx , attrs) ;
495
524
unsafe {
496
525
llvm:: LLVMRustAddStructRetCallSiteAttr (
497
526
callsite,
@@ -517,12 +546,12 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
517
546
}
518
547
for arg in & self . args {
519
548
if arg. pad . is_some ( ) {
520
- apply ( & ArgAttributes :: new ( ) ) ;
549
+ apply ( bx . cx , & ArgAttributes :: new ( ) ) ;
521
550
}
522
551
match arg. mode {
523
552
PassMode :: Ignore => { }
524
553
PassMode :: Indirect { ref attrs, extra_attrs : None , on_stack : true } => {
525
- let i = apply ( attrs) ;
554
+ let i = apply ( bx . cx , attrs) ;
526
555
unsafe {
527
556
llvm:: LLVMRustAddByValCallSiteAttr (
528
557
callsite,
@@ -533,22 +562,22 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
533
562
}
534
563
PassMode :: Direct ( ref attrs)
535
564
| PassMode :: Indirect { ref attrs, extra_attrs : None , on_stack : false } => {
536
- apply ( attrs) ;
565
+ apply ( bx . cx , attrs) ;
537
566
}
538
567
PassMode :: Indirect {
539
568
ref attrs,
540
569
extra_attrs : Some ( ref extra_attrs) ,
541
570
on_stack : _,
542
571
} => {
543
- apply ( attrs) ;
544
- apply ( extra_attrs) ;
572
+ apply ( bx . cx , attrs) ;
573
+ apply ( bx . cx , extra_attrs) ;
545
574
}
546
575
PassMode :: Pair ( ref a, ref b) => {
547
- apply ( a) ;
548
- apply ( b) ;
576
+ apply ( bx . cx , a) ;
577
+ apply ( bx . cx , b) ;
549
578
}
550
579
PassMode :: Cast ( _) => {
551
- apply ( & ArgAttributes :: new ( ) ) ;
580
+ apply ( bx . cx , & ArgAttributes :: new ( ) ) ;
552
581
}
553
582
}
554
583
}
0 commit comments