@@ -306,33 +306,42 @@ impl<'ll, 'tcx> ArgAbiBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
306306}
307307
308308pub ( crate ) enum FunctionSignature < ' ll > {
309- /// The signature is obtained directly from LLVM, and **may not match the Rust signature**
310- Intrinsic ( & ' ll Type ) ,
309+ /// This is an LLVM intrinsic, the signature is obtained directly from LLVM, and **may not match the Rust signature**
310+ LLVMSignature ( llvm:: Intrinsic , & ' ll Type ) ,
311+ /// This is an LLVM intrinsic, but the signature is just the Rust signature.
312+ /// FIXME: this should ideally not exist, we should be using the LLVM signature for all LLVM intrinsics
313+ RustSignature ( llvm:: Intrinsic , & ' ll Type ) ,
311314 /// The name starts with `llvm.`, but can't obtain the intrinsic ID. May be invalid or upgradable
312- MaybeInvalidIntrinsic ( & ' ll Type ) ,
315+ MaybeInvalid ( & ' ll Type ) ,
313316 /// Just the Rust signature
314- Rust ( & ' ll Type ) ,
317+ NotIntrinsic ( & ' ll Type ) ,
315318}
316319
317320impl < ' ll > FunctionSignature < ' ll > {
318321 pub ( crate ) fn fn_ty ( & self ) -> & ' ll Type {
319322 match self {
320- FunctionSignature :: Intrinsic ( fn_ty)
321- | FunctionSignature :: MaybeInvalidIntrinsic ( fn_ty)
322- | FunctionSignature :: Rust ( fn_ty) => fn_ty,
323+ FunctionSignature :: LLVMSignature ( _, fn_ty)
324+ | FunctionSignature :: RustSignature ( _, fn_ty)
325+ | FunctionSignature :: MaybeInvalid ( fn_ty)
326+ | FunctionSignature :: NotIntrinsic ( fn_ty) => fn_ty,
327+ }
328+ }
329+
330+ pub ( crate ) fn intrinsic ( & self ) -> Option < llvm:: Intrinsic > {
331+ match self {
332+ FunctionSignature :: RustSignature ( intrinsic, _)
333+ | FunctionSignature :: LLVMSignature ( intrinsic, _) => Some ( * intrinsic) ,
334+ _ => None ,
323335 }
324336 }
325337}
326338
327339pub ( crate ) trait FnAbiLlvmExt < ' ll , ' tcx > {
328340 fn llvm_return_type ( & self , cx : & CodegenCx < ' ll , ' tcx > ) -> & ' ll Type ;
329341 fn llvm_argument_types ( & self , cx : & CodegenCx < ' ll , ' tcx > ) -> Vec < & ' ll Type > ;
330- fn llvm_type (
331- & self ,
332- cx : & CodegenCx < ' ll , ' tcx > ,
333- name : & [ u8 ] ,
334- do_verify : bool ,
335- ) -> FunctionSignature < ' ll > ;
342+ fn llvm_type ( & self , cx : & CodegenCx < ' ll , ' tcx > , name : & [ u8 ] ) -> FunctionSignature < ' ll > ;
343+ /// The normal Rust signature for this
344+ fn rust_signature ( & self , cx : & CodegenCx < ' ll , ' tcx > ) -> & ' ll Type ;
336345 /// **If this function is an LLVM intrinsic** checks if the LLVM signature provided matches with this
337346 fn verify_intrinsic_signature ( & self , cx : & CodegenCx < ' ll , ' tcx > , llvm_ty : & ' ll Type ) -> bool ;
338347
@@ -478,51 +487,35 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
478487 . all ( |( rust_ty, llvm_ty) | cx. equate_ty ( rust_ty, llvm_ty) )
479488 }
480489
481- fn llvm_type (
482- & self ,
483- cx : & CodegenCx < ' ll , ' tcx > ,
484- name : & [ u8 ] ,
485- do_verify : bool ,
486- ) -> FunctionSignature < ' ll > {
487- let mut maybe_invalid = false ;
490+ fn rust_signature ( & self , cx : & CodegenCx < ' ll , ' tcx > ) -> & ' ll Type {
491+ let return_ty = self . llvm_return_type ( cx) ;
492+ let argument_tys = self . llvm_argument_types ( cx) ;
488493
494+ if self . c_variadic {
495+ cx. type_variadic_func ( & argument_tys, return_ty)
496+ } else {
497+ cx. type_func ( & argument_tys, return_ty)
498+ }
499+ }
500+
501+ fn llvm_type ( & self , cx : & CodegenCx < ' ll , ' tcx > , name : & [ u8 ] ) -> FunctionSignature < ' ll > {
489502 if name. starts_with ( b"llvm." ) {
490503 if let Some ( intrinsic) = llvm:: Intrinsic :: lookup ( name) {
491504 if !intrinsic. is_overloaded ( ) {
492505 // FIXME: also do this for overloaded intrinsics
493- let llvm_fn_ty = intrinsic. get_type ( cx. llcx , & [ ] ) ;
494- if do_verify {
495- if !self . verify_intrinsic_signature ( cx, llvm_fn_ty) {
496- cx. tcx . dcx ( ) . fatal ( format ! (
497- "Intrinsic signature mismatch for `{}`: expected signature `{llvm_fn_ty:?}`" ,
498- str :: from_utf8( name) . unwrap( )
499- ) ) ;
500- }
501- }
502- return FunctionSignature :: Intrinsic ( llvm_fn_ty) ;
506+ FunctionSignature :: LLVMSignature ( intrinsic, intrinsic. get_type ( cx. llcx , & [ ] ) )
507+ } else {
508+ FunctionSignature :: RustSignature ( intrinsic, self . rust_signature ( cx) )
503509 }
504510 } else {
505511 // it's one of 2 cases,
506512 // - either the base name is invalid
507513 // - it has been superseded by something else, so the intrinsic was removed entirely
508514 // to check for upgrades, we need the `llfn`, so we defer it for now
509- maybe_invalid = true ;
515+ FunctionSignature :: MaybeInvalid ( self . rust_signature ( cx ) )
510516 }
511- }
512-
513- let return_ty = self . llvm_return_type ( cx) ;
514- let argument_tys = self . llvm_argument_types ( cx) ;
515-
516- let fn_ty = if self . c_variadic {
517- cx. type_variadic_func ( & argument_tys, return_ty)
518517 } else {
519- cx. type_func ( & argument_tys, return_ty)
520- } ;
521-
522- if maybe_invalid {
523- FunctionSignature :: MaybeInvalidIntrinsic ( fn_ty)
524- } else {
525- FunctionSignature :: Rust ( fn_ty)
518+ FunctionSignature :: NotIntrinsic ( self . rust_signature ( cx) )
526519 }
527520 }
528521
@@ -686,15 +679,9 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
686679 callsite : & ' ll Value ,
687680 llfn : & ' ll Value ,
688681 ) {
689- // if we are using the LLVM signature, use the LLVM attributes otherwise it might be problematic
690- let name = llvm:: get_value_name ( llfn) ;
691- if name. starts_with ( b"llvm." )
692- && let Some ( intrinsic) = llvm:: Intrinsic :: lookup ( & name)
693- {
694- // FIXME: also do this for overloaded intrinsics
695- if !intrinsic. is_overloaded ( ) {
696- return ;
697- }
682+ // Don't apply any attributes to LLVM intrinsics, they will be applied by AutoUpgrade
683+ if llvm:: get_value_name ( llfn) . starts_with ( b"llvm." ) {
684+ return ;
698685 }
699686
700687 let mut func_attrs = SmallVec :: < [ _ ; 2 ] > :: new ( ) ;
0 commit comments