@@ -306,33 +306,42 @@ impl<'ll, 'tcx> ArgAbiBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
306
306
}
307
307
308
308
pub ( 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 ) ,
311
314
/// 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 ) ,
313
316
/// Just the Rust signature
314
- Rust ( & ' ll Type ) ,
317
+ NotIntrinsic ( & ' ll Type ) ,
315
318
}
316
319
317
320
impl < ' ll > FunctionSignature < ' ll > {
318
321
pub ( crate ) fn fn_ty ( & self ) -> & ' ll Type {
319
322
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 ,
323
335
}
324
336
}
325
337
}
326
338
327
339
pub ( crate ) trait FnAbiLlvmExt < ' ll , ' tcx > {
328
340
fn llvm_return_type ( & self , cx : & CodegenCx < ' ll , ' tcx > ) -> & ' ll Type ;
329
341
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 ;
336
345
/// **If this function is an LLVM intrinsic** checks if the LLVM signature provided matches with this
337
346
fn verify_intrinsic_signature ( & self , cx : & CodegenCx < ' ll , ' tcx > , llvm_ty : & ' ll Type ) -> bool ;
338
347
@@ -478,51 +487,35 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
478
487
. all ( |( rust_ty, llvm_ty) | cx. equate_ty ( rust_ty, llvm_ty) )
479
488
}
480
489
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) ;
488
493
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 > {
489
502
if name. starts_with ( b"llvm." ) {
490
503
if let Some ( intrinsic) = llvm:: Intrinsic :: lookup ( name) {
491
504
if !intrinsic. is_overloaded ( ) {
492
505
// 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) )
503
509
}
504
510
} else {
505
511
// it's one of 2 cases,
506
512
// - either the base name is invalid
507
513
// - it has been superseded by something else, so the intrinsic was removed entirely
508
514
// 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 ) )
510
516
}
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)
518
517
} 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) )
526
519
}
527
520
}
528
521
@@ -686,15 +679,9 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
686
679
callsite : & ' ll Value ,
687
680
llfn : & ' ll Value ,
688
681
) {
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 ;
698
685
}
699
686
700
687
let mut func_attrs = SmallVec :: < [ _ ; 2 ] > :: new ( ) ;
0 commit comments