@@ -41,12 +41,32 @@ impl ArgAttributeExt for ArgAttribute {
4141}
4242
4343pub 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
4666}
4767
4868impl 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 ) {
5070 let mut regular = self . regular ;
5171 unsafe {
5272 let deref = self . pointee_size . bytes ( ) ;
@@ -62,6 +82,9 @@ impl ArgAttributesExt for ArgAttributes {
6282 llvm:: LLVMRustAddAlignmentAttr ( llfn, idx. as_uint ( ) , align. bytes ( ) as u32 ) ;
6383 }
6484 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+ }
6588 match self . arg_ext {
6689 ArgExtension :: None => { }
6790 ArgExtension :: Zext => {
@@ -74,7 +97,12 @@ impl ArgAttributesExt for ArgAttributes {
7497 }
7598 }
7699
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+ ) {
78106 let mut regular = self . regular ;
79107 unsafe {
80108 let deref = self . pointee_size . bytes ( ) ;
@@ -98,6 +126,9 @@ impl ArgAttributesExt for ArgAttributes {
98126 ) ;
99127 }
100128 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+ }
101132 match self . arg_ext {
102133 ArgExtension :: None => { }
103134 ArgExtension :: Zext => {
@@ -419,13 +450,13 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
419450
420451 let mut i = 0 ;
421452 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) ;
423454 i += 1 ;
424455 i - 1
425456 } ;
426457 match self . ret . mode {
427458 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) ;
429460 }
430461 PassMode :: Indirect { ref attrs, extra_attrs : _, on_stack } => {
431462 assert ! ( !on_stack) ;
@@ -480,18 +511,18 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
480511 // FIXME(wesleywiser, eddyb): We should apply `nounwind` and `noreturn` as appropriate to this callsite.
481512
482513 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) ;
485516 i += 1 ;
486517 i - 1
487518 } ;
488519 match self . ret . mode {
489520 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) ;
491522 }
492523 PassMode :: Indirect { ref attrs, extra_attrs : _, on_stack } => {
493524 assert ! ( !on_stack) ;
494- let i = apply ( attrs) ;
525+ let i = apply ( bx . cx , attrs) ;
495526 unsafe {
496527 llvm:: LLVMRustAddStructRetCallSiteAttr (
497528 callsite,
@@ -517,12 +548,12 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
517548 }
518549 for arg in & self . args {
519550 if arg. pad . is_some ( ) {
520- apply ( & ArgAttributes :: new ( ) ) ;
551+ apply ( bx . cx , & ArgAttributes :: new ( ) ) ;
521552 }
522553 match arg. mode {
523554 PassMode :: Ignore => { }
524555 PassMode :: Indirect { ref attrs, extra_attrs : None , on_stack : true } => {
525- let i = apply ( attrs) ;
556+ let i = apply ( bx . cx , attrs) ;
526557 unsafe {
527558 llvm:: LLVMRustAddByValCallSiteAttr (
528559 callsite,
@@ -533,22 +564,22 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
533564 }
534565 PassMode :: Direct ( ref attrs)
535566 | PassMode :: Indirect { ref attrs, extra_attrs : None , on_stack : false } => {
536- apply ( attrs) ;
567+ apply ( bx . cx , attrs) ;
537568 }
538569 PassMode :: Indirect {
539570 ref attrs,
540571 extra_attrs : Some ( ref extra_attrs) ,
541572 on_stack : _,
542573 } => {
543- apply ( attrs) ;
544- apply ( extra_attrs) ;
574+ apply ( bx . cx , attrs) ;
575+ apply ( bx . cx , extra_attrs) ;
545576 }
546577 PassMode :: Pair ( ref a, ref b) => {
547- apply ( a) ;
548- apply ( b) ;
578+ apply ( bx . cx , a) ;
579+ apply ( bx . cx , b) ;
549580 }
550581 PassMode :: Cast ( _) => {
551- apply ( & ArgAttributes :: new ( ) ) ;
582+ apply ( bx . cx , & ArgAttributes :: new ( ) ) ;
552583 }
553584 }
554585 }
0 commit comments