@@ -310,33 +310,42 @@ impl<'ll, 'tcx> ArgAbiBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
310310}
311311
312312pub ( crate ) enum FunctionSignature < ' ll > {
313- /// The signature is obtained directly from LLVM, and **may not match the Rust signature**
314- Intrinsic ( & ' ll Type ) ,
313+ /// This is an LLVM intrinsic, the signature is obtained directly from LLVM, and **may not match the Rust signature**
314+ LLVMSignature ( llvm:: Intrinsic , & ' ll Type ) ,
315+ /// This is an LLVM intrinsic, but the signature is just the Rust signature.
316+ /// FIXME: this should ideally not exist, we should be using the LLVM signature for all LLVM intrinsics
317+ RustSignature ( llvm:: Intrinsic , & ' ll Type ) ,
315318 /// The name starts with `llvm.`, but can't obtain the intrinsic ID. May be invalid or upgradable
316- MaybeInvalidIntrinsic ( & ' ll Type ) ,
319+ MaybeInvalid ( & ' ll Type ) ,
317320 /// Just the Rust signature
318- Rust ( & ' ll Type ) ,
321+ NotIntrinsic ( & ' ll Type ) ,
319322}
320323
321324impl < ' ll > FunctionSignature < ' ll > {
322325 pub ( crate ) fn fn_ty ( & self ) -> & ' ll Type {
323326 match self {
324- FunctionSignature :: Intrinsic ( fn_ty)
325- | FunctionSignature :: MaybeInvalidIntrinsic ( fn_ty)
326- | FunctionSignature :: Rust ( fn_ty) => fn_ty,
327+ FunctionSignature :: LLVMSignature ( _, fn_ty)
328+ | FunctionSignature :: RustSignature ( _, fn_ty)
329+ | FunctionSignature :: MaybeInvalid ( fn_ty)
330+ | FunctionSignature :: NotIntrinsic ( fn_ty) => fn_ty,
331+ }
332+ }
333+
334+ pub ( crate ) fn intrinsic ( & self ) -> Option < llvm:: Intrinsic > {
335+ match self {
336+ FunctionSignature :: RustSignature ( intrinsic, _)
337+ | FunctionSignature :: LLVMSignature ( intrinsic, _) => Some ( * intrinsic) ,
338+ _ => None ,
327339 }
328340 }
329341}
330342
331343pub ( crate ) trait FnAbiLlvmExt < ' ll , ' tcx > {
332344 fn llvm_return_type ( & self , cx : & CodegenCx < ' ll , ' tcx > ) -> & ' ll Type ;
333345 fn llvm_argument_types ( & self , cx : & CodegenCx < ' ll , ' tcx > ) -> Vec < & ' ll Type > ;
334- fn llvm_type (
335- & self ,
336- cx : & CodegenCx < ' ll , ' tcx > ,
337- name : & [ u8 ] ,
338- do_verify : bool ,
339- ) -> FunctionSignature < ' ll > ;
346+ fn llvm_type ( & self , cx : & CodegenCx < ' ll , ' tcx > , name : & [ u8 ] ) -> FunctionSignature < ' ll > ;
347+ /// The normal Rust signature for this
348+ fn rust_signature ( & self , cx : & CodegenCx < ' ll , ' tcx > ) -> & ' ll Type ;
340349 /// **If this function is an LLVM intrinsic** checks if the LLVM signature provided matches with this
341350 fn verify_intrinsic_signature ( & self , cx : & CodegenCx < ' ll , ' tcx > , llvm_ty : & ' ll Type ) -> bool ;
342351
@@ -482,51 +491,35 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
482491 . all ( |( rust_ty, llvm_ty) | cx. equate_ty ( rust_ty, llvm_ty) )
483492 }
484493
485- fn llvm_type (
486- & self ,
487- cx : & CodegenCx < ' ll , ' tcx > ,
488- name : & [ u8 ] ,
489- do_verify : bool ,
490- ) -> FunctionSignature < ' ll > {
491- let mut maybe_invalid = false ;
494+ fn rust_signature ( & self , cx : & CodegenCx < ' ll , ' tcx > ) -> & ' ll Type {
495+ let return_ty = self . llvm_return_type ( cx) ;
496+ let argument_tys = self . llvm_argument_types ( cx) ;
497+
498+ if self . c_variadic {
499+ cx. type_variadic_func ( & argument_tys, return_ty)
500+ } else {
501+ cx. type_func ( & argument_tys, return_ty)
502+ }
503+ }
492504
505+ fn llvm_type ( & self , cx : & CodegenCx < ' ll , ' tcx > , name : & [ u8 ] ) -> FunctionSignature < ' ll > {
493506 if name. starts_with ( b"llvm." ) {
494507 if let Some ( intrinsic) = llvm:: Intrinsic :: lookup ( name) {
495508 if !intrinsic. is_overloaded ( ) {
496509 // FIXME: also do this for overloaded intrinsics
497- let llvm_fn_ty = intrinsic. get_type ( cx. llcx , & [ ] ) ;
498- if do_verify {
499- if !self . verify_intrinsic_signature ( cx, llvm_fn_ty) {
500- cx. tcx . dcx ( ) . fatal ( format ! (
501- "Intrinsic signature mismatch for `{}`: expected signature `{llvm_fn_ty:?}`" ,
502- str :: from_utf8( name) . unwrap( )
503- ) ) ;
504- }
505- }
506- return FunctionSignature :: Intrinsic ( llvm_fn_ty) ;
510+ FunctionSignature :: LLVMSignature ( intrinsic, intrinsic. get_type ( cx. llcx , & [ ] ) )
511+ } else {
512+ FunctionSignature :: RustSignature ( intrinsic, self . rust_signature ( cx) )
507513 }
508514 } else {
509515 // it's one of 2 cases,
510516 // - either the base name is invalid
511517 // - it has been superseded by something else, so the intrinsic was removed entirely
512518 // to check for upgrades, we need the `llfn`, so we defer it for now
513- maybe_invalid = true ;
519+ FunctionSignature :: MaybeInvalid ( self . rust_signature ( cx ) )
514520 }
515- }
516-
517- let return_ty = self . llvm_return_type ( cx) ;
518- let argument_tys = self . llvm_argument_types ( cx) ;
519-
520- let fn_ty = if self . c_variadic {
521- cx. type_variadic_func ( & argument_tys, return_ty)
522521 } else {
523- cx. type_func ( & argument_tys, return_ty)
524- } ;
525-
526- if maybe_invalid {
527- FunctionSignature :: MaybeInvalidIntrinsic ( fn_ty)
528- } else {
529- FunctionSignature :: Rust ( fn_ty)
522+ FunctionSignature :: NotIntrinsic ( self . rust_signature ( cx) )
530523 }
531524 }
532525
@@ -684,15 +677,9 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
684677 callsite : & ' ll Value ,
685678 llfn : & ' ll Value ,
686679 ) {
687- // if we are using the LLVM signature, use the LLVM attributes otherwise it might be problematic
688- let name = llvm:: get_value_name ( llfn) ;
689- if name. starts_with ( b"llvm." )
690- && let Some ( intrinsic) = llvm:: Intrinsic :: lookup ( & name)
691- {
692- // FIXME: also do this for overloaded intrinsics
693- if !intrinsic. is_overloaded ( ) {
694- return ;
695- }
680+ // Don't apply any attributes to LLVM intrinsics, they will be applied by AutoUpgrade
681+ if llvm:: get_value_name ( llfn) . starts_with ( b"llvm." ) {
682+ return ;
696683 }
697684
698685 let mut func_attrs = SmallVec :: < [ _ ; 2 ] > :: new ( ) ;
0 commit comments