@@ -304,33 +304,42 @@ impl<'ll, 'tcx> ArgAbiBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
304304}
305305
306306pub ( crate ) enum FunctionSignature < ' ll > {
307- /// The signature is obtained directly from LLVM, and **may not match the Rust signature**
308- Intrinsic ( & ' ll Type ) ,
307+ /// This is an LLVM intrinsic, the signature is obtained directly from LLVM, and **may not match the Rust signature**
308+ LLVMSignature ( llvm:: Intrinsic , & ' ll Type ) ,
309+ /// This is an LLVM intrinsic, but the signature is just the Rust signature.
310+ /// FIXME: this should ideally not exist, we should be using the LLVM signature for all LLVM intrinsics
311+ RustSignature ( llvm:: Intrinsic , & ' ll Type ) ,
309312 /// The name starts with `llvm.`, but can't obtain the intrinsic ID. May be invalid or upgradable
310- MaybeInvalidIntrinsic ( & ' ll Type ) ,
313+ MaybeInvalid ( & ' ll Type ) ,
311314 /// Just the Rust signature
312- Rust ( & ' ll Type ) ,
315+ NotIntrinsic ( & ' ll Type ) ,
313316}
314317
315318impl < ' ll > FunctionSignature < ' ll > {
316319 pub ( crate ) fn fn_ty ( & self ) -> & ' ll Type {
317320 match self {
318- FunctionSignature :: Intrinsic ( fn_ty)
319- | FunctionSignature :: MaybeInvalidIntrinsic ( fn_ty)
320- | FunctionSignature :: Rust ( fn_ty) => fn_ty,
321+ FunctionSignature :: LLVMSignature ( _, fn_ty)
322+ | FunctionSignature :: RustSignature ( _, fn_ty)
323+ | FunctionSignature :: MaybeInvalid ( fn_ty)
324+ | FunctionSignature :: NotIntrinsic ( fn_ty) => fn_ty,
325+ }
326+ }
327+
328+ pub ( crate ) fn intrinsic ( & self ) -> Option < llvm:: Intrinsic > {
329+ match self {
330+ FunctionSignature :: RustSignature ( intrinsic, _)
331+ | FunctionSignature :: LLVMSignature ( intrinsic, _) => Some ( * intrinsic) ,
332+ _ => None ,
321333 }
322334 }
323335}
324336
325337pub ( crate ) trait FnAbiLlvmExt < ' ll , ' tcx > {
326338 fn llvm_return_type ( & self , cx : & CodegenCx < ' ll , ' tcx > ) -> & ' ll Type ;
327339 fn llvm_argument_types ( & self , cx : & CodegenCx < ' ll , ' tcx > ) -> Vec < & ' ll Type > ;
328- fn llvm_type (
329- & self ,
330- cx : & CodegenCx < ' ll , ' tcx > ,
331- name : & [ u8 ] ,
332- do_verify : bool ,
333- ) -> FunctionSignature < ' ll > ;
340+ fn llvm_type ( & self , cx : & CodegenCx < ' ll , ' tcx > , name : & [ u8 ] ) -> FunctionSignature < ' ll > ;
341+ /// The normal Rust signature for this
342+ fn rust_signature ( & self , cx : & CodegenCx < ' ll , ' tcx > ) -> & ' ll Type ;
334343 /// **If this function is an LLVM intrinsic** checks if the LLVM signature provided matches with this
335344 fn verify_intrinsic_signature ( & self , cx : & CodegenCx < ' ll , ' tcx > , llvm_ty : & ' ll Type ) -> bool ;
336345
@@ -476,51 +485,35 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
476485 . all ( |( rust_ty, llvm_ty) | cx. equate_ty ( rust_ty, llvm_ty) )
477486 }
478487
479- fn llvm_type (
480- & self ,
481- cx : & CodegenCx < ' ll , ' tcx > ,
482- name : & [ u8 ] ,
483- do_verify : bool ,
484- ) -> FunctionSignature < ' ll > {
485- let mut maybe_invalid = false ;
488+ fn rust_signature ( & self , cx : & CodegenCx < ' ll , ' tcx > ) -> & ' ll Type {
489+ let return_ty = self . llvm_return_type ( cx) ;
490+ let argument_tys = self . llvm_argument_types ( cx) ;
486491
492+ if self . c_variadic {
493+ cx. type_variadic_func ( & argument_tys, return_ty)
494+ } else {
495+ cx. type_func ( & argument_tys, return_ty)
496+ }
497+ }
498+
499+ fn llvm_type ( & self , cx : & CodegenCx < ' ll , ' tcx > , name : & [ u8 ] ) -> FunctionSignature < ' ll > {
487500 if name. starts_with ( b"llvm." ) {
488501 if let Some ( intrinsic) = llvm:: Intrinsic :: lookup ( name) {
489502 if !intrinsic. is_overloaded ( ) {
490503 // FIXME: also do this for overloaded intrinsics
491- let llvm_fn_ty = intrinsic. get_type ( cx. llcx , & [ ] ) ;
492- if do_verify {
493- if !self . verify_intrinsic_signature ( cx, llvm_fn_ty) {
494- cx. tcx . dcx ( ) . fatal ( format ! (
495- "Intrinsic signature mismatch for `{}`: expected signature `{llvm_fn_ty:?}`" ,
496- str :: from_utf8( name) . unwrap( )
497- ) ) ;
498- }
499- }
500- return FunctionSignature :: Intrinsic ( llvm_fn_ty) ;
504+ FunctionSignature :: LLVMSignature ( intrinsic, intrinsic. get_type ( cx. llcx , & [ ] ) )
505+ } else {
506+ FunctionSignature :: RustSignature ( intrinsic, self . rust_signature ( cx) )
501507 }
502508 } else {
503509 // it's one of 2 cases,
504510 // - either the base name is invalid
505511 // - it has been superseded by something else, so the intrinsic was removed entirely
506512 // to check for upgrades, we need the `llfn`, so we defer it for now
507- maybe_invalid = true ;
513+ FunctionSignature :: MaybeInvalid ( self . rust_signature ( cx ) )
508514 }
509- }
510-
511- let return_ty = self . llvm_return_type ( cx) ;
512- let argument_tys = self . llvm_argument_types ( cx) ;
513-
514- let fn_ty = if self . c_variadic {
515- cx. type_variadic_func ( & argument_tys, return_ty)
516515 } else {
517- cx. type_func ( & argument_tys, return_ty)
518- } ;
519-
520- if maybe_invalid {
521- FunctionSignature :: MaybeInvalidIntrinsic ( fn_ty)
522- } else {
523- FunctionSignature :: Rust ( fn_ty)
516+ FunctionSignature :: NotIntrinsic ( self . rust_signature ( cx) )
524517 }
525518 }
526519
@@ -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