11use crate :: builder:: Builder ;
22use crate :: context:: CodegenCx ;
33use crate :: llvm:: { self , AttributePlace } ;
4+ use crate :: llvm_util;
45use crate :: type_:: Type ;
56use crate :: type_of:: LayoutLlvmExt ;
67use crate :: value:: Value ;
@@ -41,12 +42,29 @@ impl ArgAttributeExt for ArgAttribute {
4142}
4243
4344pub 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 ) )
4664}
4765
4866impl 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 ) {
5068 let mut regular = self . regular ;
5169 unsafe {
5270 let deref = self . pointee_size . bytes ( ) ;
@@ -62,6 +80,9 @@ impl ArgAttributesExt for ArgAttributes {
6280 llvm:: LLVMRustAddAlignmentAttr ( llfn, idx. as_uint ( ) , align. bytes ( ) as u32 ) ;
6381 }
6482 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+ }
6586 match self . arg_ext {
6687 ArgExtension :: None => { }
6788 ArgExtension :: Zext => {
@@ -74,7 +95,12 @@ impl ArgAttributesExt for ArgAttributes {
7495 }
7596 }
7697
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+ ) {
78104 let mut regular = self . regular ;
79105 unsafe {
80106 let deref = self . pointee_size . bytes ( ) ;
@@ -98,6 +124,9 @@ impl ArgAttributesExt for ArgAttributes {
98124 ) ;
99125 }
100126 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+ }
101130 match self . arg_ext {
102131 ArgExtension :: None => { }
103132 ArgExtension :: Zext => {
@@ -419,13 +448,13 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
419448
420449 let mut i = 0 ;
421450 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) ;
423452 i += 1 ;
424453 i - 1
425454 } ;
426455 match self . ret . mode {
427456 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) ;
429458 }
430459 PassMode :: Indirect { ref attrs, extra_attrs : _, on_stack } => {
431460 assert ! ( !on_stack) ;
@@ -480,18 +509,18 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
480509 // FIXME(wesleywiser, eddyb): We should apply `nounwind` and `noreturn` as appropriate to this callsite.
481510
482511 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) ;
485514 i += 1 ;
486515 i - 1
487516 } ;
488517 match self . ret . mode {
489518 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) ;
491520 }
492521 PassMode :: Indirect { ref attrs, extra_attrs : _, on_stack } => {
493522 assert ! ( !on_stack) ;
494- let i = apply ( attrs) ;
523+ let i = apply ( bx . cx , attrs) ;
495524 unsafe {
496525 llvm:: LLVMRustAddStructRetCallSiteAttr (
497526 callsite,
@@ -517,12 +546,12 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
517546 }
518547 for arg in & self . args {
519548 if arg. pad . is_some ( ) {
520- apply ( & ArgAttributes :: new ( ) ) ;
549+ apply ( bx . cx , & ArgAttributes :: new ( ) ) ;
521550 }
522551 match arg. mode {
523552 PassMode :: Ignore => { }
524553 PassMode :: Indirect { ref attrs, extra_attrs : None , on_stack : true } => {
525- let i = apply ( attrs) ;
554+ let i = apply ( bx . cx , attrs) ;
526555 unsafe {
527556 llvm:: LLVMRustAddByValCallSiteAttr (
528557 callsite,
@@ -533,22 +562,22 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
533562 }
534563 PassMode :: Direct ( ref attrs)
535564 | PassMode :: Indirect { ref attrs, extra_attrs : None , on_stack : false } => {
536- apply ( attrs) ;
565+ apply ( bx . cx , attrs) ;
537566 }
538567 PassMode :: Indirect {
539568 ref attrs,
540569 extra_attrs : Some ( ref extra_attrs) ,
541570 on_stack : _,
542571 } => {
543- apply ( attrs) ;
544- apply ( extra_attrs) ;
572+ apply ( bx . cx , attrs) ;
573+ apply ( bx . cx , extra_attrs) ;
545574 }
546575 PassMode :: Pair ( ref a, ref b) => {
547- apply ( a) ;
548- apply ( b) ;
576+ apply ( bx . cx , a) ;
577+ apply ( bx . cx , b) ;
549578 }
550579 PassMode :: Cast ( _) => {
551- apply ( & ArgAttributes :: new ( ) ) ;
580+ apply ( bx . cx , & ArgAttributes :: new ( ) ) ;
552581 }
553582 }
554583 }
0 commit comments