@@ -14,7 +14,6 @@ use rustc_codegen_ssa::mir::place::PlaceRef;
14
14
use rustc_codegen_ssa:: traits:: * ;
15
15
use rustc_data_structures:: small_c_str:: SmallCStr ;
16
16
use rustc_hir:: def_id:: DefId ;
17
- use rustc_middle:: bug;
18
17
use rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrs ;
19
18
use rustc_middle:: ty:: layout:: {
20
19
FnAbiError , FnAbiOfHelpers , FnAbiRequest , HasTypingEnv , LayoutError , LayoutOfHelpers ,
@@ -485,73 +484,28 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
485
484
fn checked_binop (
486
485
& mut self ,
487
486
oop : OverflowOp ,
488
- ty : Ty < ' _ > ,
487
+ ty : Ty < ' tcx > ,
489
488
lhs : Self :: Value ,
490
489
rhs : Self :: Value ,
491
490
) -> ( Self :: Value , Self :: Value ) {
492
- use rustc_middle:: ty:: IntTy :: * ;
493
- use rustc_middle:: ty:: UintTy :: * ;
494
- use rustc_middle:: ty:: { Int , Uint } ;
495
-
496
- let new_kind = match ty. kind ( ) {
497
- Int ( t @ Isize ) => Int ( t. normalize ( self . tcx . sess . target . pointer_width ) ) ,
498
- Uint ( t @ Usize ) => Uint ( t. normalize ( self . tcx . sess . target . pointer_width ) ) ,
499
- t @ ( Uint ( _) | Int ( _) ) => * t,
500
- _ => panic ! ( "tried to get overflow intrinsic for op applied to non-int type" ) ,
501
- } ;
491
+ let ( size, signed) = ty. int_size_and_signed ( self . tcx ) ;
492
+ let width = size. bits ( ) ;
502
493
503
- let name = match oop {
504
- OverflowOp :: Add => match new_kind {
505
- Int ( I8 ) => "llvm.sadd.with.overflow.i8" ,
506
- Int ( I16 ) => "llvm.sadd.with.overflow.i16" ,
507
- Int ( I32 ) => "llvm.sadd.with.overflow.i32" ,
508
- Int ( I64 ) => "llvm.sadd.with.overflow.i64" ,
509
- Int ( I128 ) => "llvm.sadd.with.overflow.i128" ,
510
-
511
- Uint ( U8 ) => "llvm.uadd.with.overflow.i8" ,
512
- Uint ( U16 ) => "llvm.uadd.with.overflow.i16" ,
513
- Uint ( U32 ) => "llvm.uadd.with.overflow.i32" ,
514
- Uint ( U64 ) => "llvm.uadd.with.overflow.i64" ,
515
- Uint ( U128 ) => "llvm.uadd.with.overflow.i128" ,
516
-
517
- _ => unreachable ! ( ) ,
518
- } ,
519
- OverflowOp :: Sub => match new_kind {
520
- Int ( I8 ) => "llvm.ssub.with.overflow.i8" ,
521
- Int ( I16 ) => "llvm.ssub.with.overflow.i16" ,
522
- Int ( I32 ) => "llvm.ssub.with.overflow.i32" ,
523
- Int ( I64 ) => "llvm.ssub.with.overflow.i64" ,
524
- Int ( I128 ) => "llvm.ssub.with.overflow.i128" ,
525
-
526
- Uint ( _) => {
527
- // Emit sub and icmp instead of llvm.usub.with.overflow. LLVM considers these
528
- // to be the canonical form. It will attempt to reform llvm.usub.with.overflow
529
- // in the backend if profitable.
494
+ if oop == OverflowOp :: Sub && !signed {
530
495
let sub = self . sub ( lhs, rhs) ;
531
496
let cmp = self . icmp ( IntPredicate :: IntULT , lhs, rhs) ;
532
497
return ( sub, cmp) ;
533
498
}
534
499
535
- _ => unreachable ! ( ) ,
536
- } ,
537
- OverflowOp :: Mul => match new_kind {
538
- Int ( I8 ) => "llvm.smul.with.overflow.i8" ,
539
- Int ( I16 ) => "llvm.smul.with.overflow.i16" ,
540
- Int ( I32 ) => "llvm.smul.with.overflow.i32" ,
541
- Int ( I64 ) => "llvm.smul.with.overflow.i64" ,
542
- Int ( I128 ) => "llvm.smul.with.overflow.i128" ,
543
-
544
- Uint ( U8 ) => "llvm.umul.with.overflow.i8" ,
545
- Uint ( U16 ) => "llvm.umul.with.overflow.i16" ,
546
- Uint ( U32 ) => "llvm.umul.with.overflow.i32" ,
547
- Uint ( U64 ) => "llvm.umul.with.overflow.i64" ,
548
- Uint ( U128 ) => "llvm.umul.with.overflow.i128" ,
549
-
550
- _ => unreachable ! ( ) ,
551
- } ,
500
+ let oop_str = match oop {
501
+ OverflowOp :: Add => "add" ,
502
+ OverflowOp :: Sub => "sub" ,
503
+ OverflowOp :: Mul => "mul" ,
552
504
} ;
553
505
554
- let res = self . call_intrinsic ( name, & [ lhs, rhs] ) ;
506
+ let name = format ! ( "llvm.{}{oop_str}.with.overflow" , if signed { 's' } else { 'u' } ) ;
507
+
508
+ let res = self . call_intrinsic ( & name, & [ self . type_ix ( width) ] , & [ lhs, rhs] ) ;
555
509
( self . extract_value ( res, 0 ) , self . extract_value ( res, 1 ) )
556
510
}
557
511
@@ -955,11 +909,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
955
909
}
956
910
957
911
fn fptoui_sat ( & mut self , val : & ' ll Value , dest_ty : & ' ll Type ) -> & ' ll Value {
958
- self . fptoint_sat ( false , val, dest_ty )
912
+ self . call_intrinsic ( "llvm.fptoui.sat" , & [ dest_ty , self . val_ty ( val) ] , & [ val ] )
959
913
}
960
914
961
915
fn fptosi_sat ( & mut self , val : & ' ll Value , dest_ty : & ' ll Type ) -> & ' ll Value {
962
- self . fptoint_sat ( true , val, dest_ty )
916
+ self . call_intrinsic ( "llvm.fptosi.sat" , & [ dest_ty , self . val_ty ( val) ] , & [ val ] )
963
917
}
964
918
965
919
fn fptoui ( & mut self , val : & ' ll Value , dest_ty : & ' ll Type ) -> & ' ll Value {
@@ -982,15 +936,12 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
982
936
if self . cx . type_kind ( src_ty) != TypeKind :: Vector {
983
937
let float_width = self . cx . float_width ( src_ty) ;
984
938
let int_width = self . cx . int_width ( dest_ty) ;
985
- let name = match ( int_width, float_width) {
986
- ( 32 , 32 ) => Some ( "llvm.wasm.trunc.unsigned.i32.f32" ) ,
987
- ( 32 , 64 ) => Some ( "llvm.wasm.trunc.unsigned.i32.f64" ) ,
988
- ( 64 , 32 ) => Some ( "llvm.wasm.trunc.unsigned.i64.f32" ) ,
989
- ( 64 , 64 ) => Some ( "llvm.wasm.trunc.unsigned.i64.f64" ) ,
990
- _ => None ,
991
- } ;
992
- if let Some ( name) = name {
993
- return self . call_intrinsic ( name, & [ val] ) ;
939
+ if matches ! ( ( int_width, float_width) , ( 32 | 64 , 32 | 64 ) ) {
940
+ return self . call_intrinsic (
941
+ "llvm.wasm.trunc.unsigned" ,
942
+ & [ dest_ty, src_ty] ,
943
+ & [ val] ,
944
+ ) ;
994
945
}
995
946
}
996
947
}
@@ -1004,15 +955,12 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
1004
955
if self . cx . type_kind ( src_ty) != TypeKind :: Vector {
1005
956
let float_width = self . cx . float_width ( src_ty) ;
1006
957
let int_width = self . cx . int_width ( dest_ty) ;
1007
- let name = match ( int_width, float_width) {
1008
- ( 32 , 32 ) => Some ( "llvm.wasm.trunc.signed.i32.f32" ) ,
1009
- ( 32 , 64 ) => Some ( "llvm.wasm.trunc.signed.i32.f64" ) ,
1010
- ( 64 , 32 ) => Some ( "llvm.wasm.trunc.signed.i64.f32" ) ,
1011
- ( 64 , 64 ) => Some ( "llvm.wasm.trunc.signed.i64.f64" ) ,
1012
- _ => None ,
1013
- } ;
1014
- if let Some ( name) = name {
1015
- return self . call_intrinsic ( name, & [ val] ) ;
958
+ if matches ! ( ( int_width, float_width) , ( 32 | 64 , 32 | 64 ) ) {
959
+ return self . call_intrinsic (
960
+ "llvm.wasm.trunc.signed" ,
961
+ & [ dest_ty, src_ty] ,
962
+ & [ val] ,
963
+ ) ;
1016
964
}
1017
965
}
1018
966
}
@@ -1085,22 +1033,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
1085
1033
return None ;
1086
1034
}
1087
1035
1088
- let name = match ( ty. is_signed ( ) , ty. primitive_size ( self . tcx ) . bits ( ) ) {
1089
- ( true , 8 ) => "llvm.scmp.i8.i8" ,
1090
- ( true , 16 ) => "llvm.scmp.i8.i16" ,
1091
- ( true , 32 ) => "llvm.scmp.i8.i32" ,
1092
- ( true , 64 ) => "llvm.scmp.i8.i64" ,
1093
- ( true , 128 ) => "llvm.scmp.i8.i128" ,
1036
+ let size = ty. primitive_size ( self . tcx ) ;
1037
+ let name = if ty. is_signed ( ) { "llvm.scmp" } else { "llvm.ucmp" } ;
1094
1038
1095
- ( false , 8 ) => "llvm.ucmp.i8.i8" ,
1096
- ( false , 16 ) => "llvm.ucmp.i8.i16" ,
1097
- ( false , 32 ) => "llvm.ucmp.i8.i32" ,
1098
- ( false , 64 ) => "llvm.ucmp.i8.i64" ,
1099
- ( false , 128 ) => "llvm.ucmp.i8.i128" ,
1100
-
1101
- _ => bug ! ( "three-way compare unsupported for type {ty:?}" ) ,
1102
- } ;
1103
- Some ( self . call_intrinsic ( name, & [ lhs, rhs] ) )
1039
+ Some ( self . call_intrinsic ( & name, & [ self . type_i8 ( ) , self . type_ix ( size. bits ( ) ) ] , & [ lhs, rhs] ) )
1104
1040
}
1105
1041
1106
1042
/* Miscellaneous instructions */
@@ -1386,11 +1322,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
1386
1322
}
1387
1323
1388
1324
fn lifetime_start ( & mut self , ptr : & ' ll Value , size : Size ) {
1389
- self . call_lifetime_intrinsic ( "llvm.lifetime.start.p0i8 " , ptr, size) ;
1325
+ self . call_lifetime_intrinsic ( "llvm.lifetime.start" , ptr, size) ;
1390
1326
}
1391
1327
1392
1328
fn lifetime_end ( & mut self , ptr : & ' ll Value , size : Size ) {
1393
- self . call_lifetime_intrinsic ( "llvm.lifetime.end.p0i8 " , ptr, size) ;
1329
+ self . call_lifetime_intrinsic ( "llvm.lifetime.end" , ptr, size) ;
1394
1330
}
1395
1331
1396
1332
fn call (
@@ -1605,8 +1541,13 @@ impl<'a, 'll, CX: Borrow<SCx<'ll>>> GenericBuilder<'a, 'll, CX> {
1605
1541
}
1606
1542
1607
1543
impl < ' a , ' ll , ' tcx > Builder < ' a , ' ll , ' tcx > {
1608
- pub ( crate ) fn call_intrinsic ( & mut self , intrinsic : & str , args : & [ & ' ll Value ] ) -> & ' ll Value {
1609
- let ( ty, f) = self . cx . get_intrinsic ( intrinsic) ;
1544
+ pub ( crate ) fn call_intrinsic (
1545
+ & mut self ,
1546
+ base_name : & str ,
1547
+ type_params : & [ & ' ll Type ] ,
1548
+ args : & [ & ' ll Value ] ,
1549
+ ) -> & ' ll Value {
1550
+ let ( ty, f) = self . cx . get_intrinsic ( base_name, type_params) ;
1610
1551
self . call ( ty, None , None , f, args, None , None )
1611
1552
}
1612
1553
@@ -1620,7 +1561,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
1620
1561
return ;
1621
1562
}
1622
1563
1623
- self . call_intrinsic ( intrinsic, & [ self . cx . const_u64 ( size) , ptr] ) ;
1564
+ self . call_intrinsic ( intrinsic, & [ self . type_ptr ( ) ] , & [ self . cx . const_u64 ( size) , ptr] ) ;
1624
1565
}
1625
1566
}
1626
1567
impl < ' a , ' ll , CX : Borrow < SCx < ' ll > > > GenericBuilder < ' a , ' ll , CX > {
@@ -1645,31 +1586,6 @@ impl<'a, 'll, CX: Borrow<SCx<'ll>>> GenericBuilder<'a, 'll, CX> {
1645
1586
}
1646
1587
}
1647
1588
impl < ' a , ' ll , ' tcx > Builder < ' a , ' ll , ' tcx > {
1648
- fn fptoint_sat ( & mut self , signed : bool , val : & ' ll Value , dest_ty : & ' ll Type ) -> & ' ll Value {
1649
- let src_ty = self . cx . val_ty ( val) ;
1650
- let ( float_ty, int_ty, vector_length) = if self . cx . type_kind ( src_ty) == TypeKind :: Vector {
1651
- assert_eq ! ( self . cx. vector_length( src_ty) , self . cx. vector_length( dest_ty) ) ;
1652
- (
1653
- self . cx . element_type ( src_ty) ,
1654
- self . cx . element_type ( dest_ty) ,
1655
- Some ( self . cx . vector_length ( src_ty) ) ,
1656
- )
1657
- } else {
1658
- ( src_ty, dest_ty, None )
1659
- } ;
1660
- let float_width = self . cx . float_width ( float_ty) ;
1661
- let int_width = self . cx . int_width ( int_ty) ;
1662
-
1663
- let instr = if signed { "fptosi" } else { "fptoui" } ;
1664
- let name = if let Some ( vector_length) = vector_length {
1665
- format ! ( "llvm.{instr}.sat.v{vector_length}i{int_width}.v{vector_length}f{float_width}" )
1666
- } else {
1667
- format ! ( "llvm.{instr}.sat.i{int_width}.f{float_width}" )
1668
- } ;
1669
- let f = self . declare_cfn ( & name, llvm:: UnnamedAddr :: No , self . type_func ( & [ src_ty] , dest_ty) ) ;
1670
- self . call ( self . type_func ( & [ src_ty] , dest_ty) , None , None , f, & [ val] , None , None )
1671
- }
1672
-
1673
1589
fn trunc_int_to_i1_vector ( & mut self , val : & ' ll Value , dest_ty : & ' ll Type ) -> & ' ll Value {
1674
1590
let vector_length = self . vector_length ( dest_ty) as u64 ;
1675
1591
let int_width = cmp:: max ( vector_length. next_power_of_two ( ) , 8 ) ;
@@ -1976,7 +1892,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
1976
1892
num_counters : & ' ll Value ,
1977
1893
index : & ' ll Value ,
1978
1894
) {
1979
- self . call_intrinsic ( "llvm.instrprof.increment" , & [ fn_name, hash, num_counters, index] ) ;
1895
+ self . call_intrinsic ( "llvm.instrprof.increment" , & [ ] , & [ fn_name, hash, num_counters, index] ) ;
1980
1896
}
1981
1897
1982
1898
/// Emits a call to `llvm.instrprof.mcdc.parameters`.
@@ -1995,7 +1911,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
1995
1911
hash : & ' ll Value ,
1996
1912
bitmap_bits : & ' ll Value ,
1997
1913
) {
1998
- self . call_intrinsic ( "llvm.instrprof.mcdc.parameters" , & [ fn_name, hash, bitmap_bits] ) ;
1914
+ self . call_intrinsic ( "llvm.instrprof.mcdc.parameters" , & [ ] , & [ fn_name, hash, bitmap_bits] ) ;
1999
1915
}
2000
1916
2001
1917
#[ instrument( level = "debug" , skip( self ) ) ]
@@ -2007,7 +1923,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
2007
1923
mcdc_temp : & ' ll Value ,
2008
1924
) {
2009
1925
let args = & [ fn_name, hash, bitmap_index, mcdc_temp] ;
2010
- self . call_intrinsic ( "llvm.instrprof.mcdc.tvbitmap.update" , args) ;
1926
+ self . call_intrinsic ( "llvm.instrprof.mcdc.tvbitmap.update" , & [ ] , args) ;
2011
1927
}
2012
1928
2013
1929
#[ instrument( level = "debug" , skip( self ) ) ]
0 commit comments