@@ -14,7 +14,6 @@ use rustc_codegen_ssa::mir::place::PlaceRef;
1414use  rustc_codegen_ssa:: traits:: * ; 
1515use  rustc_data_structures:: small_c_str:: SmallCStr ; 
1616use  rustc_hir:: def_id:: DefId ; 
17- use  rustc_middle:: bug; 
1817use  rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrs ; 
1918use  rustc_middle:: ty:: layout:: { 
2019    FnAbiError ,  FnAbiOfHelpers ,  FnAbiRequest ,  HasTypingEnv ,  LayoutError ,  LayoutOfHelpers , 
@@ -484,73 +483,31 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
484483    fn  checked_binop ( 
485484        & mut  self , 
486485        oop :  OverflowOp , 
487-         ty :  Ty < ' _ > , 
486+         ty :  Ty < ' tcx > , 
488487        lhs :  Self :: Value , 
489488        rhs :  Self :: Value , 
490489    )  -> ( Self :: Value ,  Self :: Value )  { 
491-         use  rustc_middle:: ty:: IntTy :: * ; 
492-         use  rustc_middle:: ty:: UintTy :: * ; 
493-         use  rustc_middle:: ty:: { Int ,  Uint } ; 
494- 
495-         let  new_kind = match  ty. kind ( )  { 
496-             Int ( t @ Isize )  => Int ( t. normalize ( self . tcx . sess . target . pointer_width ) ) , 
497-             Uint ( t @ Usize )  => Uint ( t. normalize ( self . tcx . sess . target . pointer_width ) ) , 
498-             t @ ( Uint ( _)  | Int ( _) )  => * t, 
499-             _ => panic ! ( "tried to get overflow intrinsic for op applied to non-int type" ) , 
490+         let  ( size,  signed)  = ty. int_size_and_signed ( self . tcx ) ; 
491+         let  width = size. bits ( ) ; 
492+ 
493+         if  oop == OverflowOp :: Sub  && !signed { 
494+             // Emit sub and icmp instead of llvm.usub.with.overflow. LLVM considers these 
495+             // to be the canonical form. It will attempt to reform llvm.usub.with.overflow 
496+             // in the backend if profitable. 
497+             let  sub = self . sub ( lhs,  rhs) ; 
498+             let  cmp = self . icmp ( IntPredicate :: IntULT ,  lhs,  rhs) ; 
499+             return  ( sub,  cmp) ; 
500+         } 
501+ 
502+         let  oop_str = match  oop { 
503+             OverflowOp :: Add  => "add" , 
504+             OverflowOp :: Sub  => "sub" , 
505+             OverflowOp :: Mul  => "mul" , 
500506        } ; 
501507
502-         let  name = match  oop { 
503-             OverflowOp :: Add  => match  new_kind { 
504-                 Int ( I8 )  => "llvm.sadd.with.overflow.i8" , 
505-                 Int ( I16 )  => "llvm.sadd.with.overflow.i16" , 
506-                 Int ( I32 )  => "llvm.sadd.with.overflow.i32" , 
507-                 Int ( I64 )  => "llvm.sadd.with.overflow.i64" , 
508-                 Int ( I128 )  => "llvm.sadd.with.overflow.i128" , 
509- 
510-                 Uint ( U8 )  => "llvm.uadd.with.overflow.i8" , 
511-                 Uint ( U16 )  => "llvm.uadd.with.overflow.i16" , 
512-                 Uint ( U32 )  => "llvm.uadd.with.overflow.i32" , 
513-                 Uint ( U64 )  => "llvm.uadd.with.overflow.i64" , 
514-                 Uint ( U128 )  => "llvm.uadd.with.overflow.i128" , 
515- 
516-                 _ => unreachable ! ( ) , 
517-             } , 
518-             OverflowOp :: Sub  => match  new_kind { 
519-                 Int ( I8 )  => "llvm.ssub.with.overflow.i8" , 
520-                 Int ( I16 )  => "llvm.ssub.with.overflow.i16" , 
521-                 Int ( I32 )  => "llvm.ssub.with.overflow.i32" , 
522-                 Int ( I64 )  => "llvm.ssub.with.overflow.i64" , 
523-                 Int ( I128 )  => "llvm.ssub.with.overflow.i128" , 
524- 
525-                 Uint ( _)  => { 
526-                     // Emit sub and icmp instead of llvm.usub.with.overflow. LLVM considers these 
527-                     // to be the canonical form. It will attempt to reform llvm.usub.with.overflow 
528-                     // in the backend if profitable. 
529-                     let  sub = self . sub ( lhs,  rhs) ; 
530-                     let  cmp = self . icmp ( IntPredicate :: IntULT ,  lhs,  rhs) ; 
531-                     return  ( sub,  cmp) ; 
532-                 } 
533- 
534-                 _ => unreachable ! ( ) , 
535-             } , 
536-             OverflowOp :: Mul  => match  new_kind { 
537-                 Int ( I8 )  => "llvm.smul.with.overflow.i8" , 
538-                 Int ( I16 )  => "llvm.smul.with.overflow.i16" , 
539-                 Int ( I32 )  => "llvm.smul.with.overflow.i32" , 
540-                 Int ( I64 )  => "llvm.smul.with.overflow.i64" , 
541-                 Int ( I128 )  => "llvm.smul.with.overflow.i128" , 
542- 
543-                 Uint ( U8 )  => "llvm.umul.with.overflow.i8" , 
544-                 Uint ( U16 )  => "llvm.umul.with.overflow.i16" , 
545-                 Uint ( U32 )  => "llvm.umul.with.overflow.i32" , 
546-                 Uint ( U64 )  => "llvm.umul.with.overflow.i64" , 
547-                 Uint ( U128 )  => "llvm.umul.with.overflow.i128" , 
548- 
549-                 _ => unreachable ! ( ) , 
550-             } , 
551-         } ; 
508+         let  name = format ! ( "llvm.{}{oop_str}.with.overflow" ,  if  signed {  's'  }  else {  'u'  } ) ; 
552509
553-         let  res = self . call_intrinsic ( name,  & [ lhs,  rhs] ) ; 
510+         let  res = self . call_intrinsic ( & name,   & [ self . type_ix ( width ) ] ,  & [ lhs,  rhs] ) ; 
554511        ( self . extract_value ( res,  0 ) ,  self . extract_value ( res,  1 ) ) 
555512    } 
556513
@@ -954,11 +911,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
954911    } 
955912
956913    fn  fptoui_sat ( & mut  self ,  val :  & ' ll  Value ,  dest_ty :  & ' ll  Type )  -> & ' ll  Value  { 
957-         self . fptoint_sat ( false ,   val,  dest_ty ) 
914+         self . call_intrinsic ( "llvm.fptoui.sat" ,   & [ dest_ty ,   self . val_ty ( val) ] ,   & [ val ] ) 
958915    } 
959916
960917    fn  fptosi_sat ( & mut  self ,  val :  & ' ll  Value ,  dest_ty :  & ' ll  Type )  -> & ' ll  Value  { 
961-         self . fptoint_sat ( true ,   val,  dest_ty ) 
918+         self . call_intrinsic ( "llvm.fptosi.sat" ,   & [ dest_ty ,   self . val_ty ( val) ] ,   & [ val ] ) 
962919    } 
963920
964921    fn  fptoui ( & mut  self ,  val :  & ' ll  Value ,  dest_ty :  & ' ll  Type )  -> & ' ll  Value  { 
@@ -981,15 +938,12 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
981938            if  self . cx . type_kind ( src_ty)  != TypeKind :: Vector  { 
982939                let  float_width = self . cx . float_width ( src_ty) ; 
983940                let  int_width = self . cx . int_width ( dest_ty) ; 
984-                 let  name = match  ( int_width,  float_width)  { 
985-                     ( 32 ,  32 )  => Some ( "llvm.wasm.trunc.unsigned.i32.f32" ) , 
986-                     ( 32 ,  64 )  => Some ( "llvm.wasm.trunc.unsigned.i32.f64" ) , 
987-                     ( 64 ,  32 )  => Some ( "llvm.wasm.trunc.unsigned.i64.f32" ) , 
988-                     ( 64 ,  64 )  => Some ( "llvm.wasm.trunc.unsigned.i64.f64" ) , 
989-                     _ => None , 
990-                 } ; 
991-                 if  let  Some ( name)  = name { 
992-                     return  self . call_intrinsic ( name,  & [ val] ) ; 
941+                 if  matches ! ( ( int_width,  float_width) ,  ( 32  | 64 ,  32  | 64 ) )  { 
942+                     return  self . call_intrinsic ( 
943+                         "llvm.wasm.trunc.unsigned" , 
944+                         & [ dest_ty,  src_ty] , 
945+                         & [ val] , 
946+                     ) ; 
993947                } 
994948            } 
995949        } 
@@ -1003,15 +957,12 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
1003957            if  self . cx . type_kind ( src_ty)  != TypeKind :: Vector  { 
1004958                let  float_width = self . cx . float_width ( src_ty) ; 
1005959                let  int_width = self . cx . int_width ( dest_ty) ; 
1006-                 let  name = match  ( int_width,  float_width)  { 
1007-                     ( 32 ,  32 )  => Some ( "llvm.wasm.trunc.signed.i32.f32" ) , 
1008-                     ( 32 ,  64 )  => Some ( "llvm.wasm.trunc.signed.i32.f64" ) , 
1009-                     ( 64 ,  32 )  => Some ( "llvm.wasm.trunc.signed.i64.f32" ) , 
1010-                     ( 64 ,  64 )  => Some ( "llvm.wasm.trunc.signed.i64.f64" ) , 
1011-                     _ => None , 
1012-                 } ; 
1013-                 if  let  Some ( name)  = name { 
1014-                     return  self . call_intrinsic ( name,  & [ val] ) ; 
960+                 if  matches ! ( ( int_width,  float_width) ,  ( 32  | 64 ,  32  | 64 ) )  { 
961+                     return  self . call_intrinsic ( 
962+                         "llvm.wasm.trunc.signed" , 
963+                         & [ dest_ty,  src_ty] , 
964+                         & [ val] , 
965+                     ) ; 
1015966                } 
1016967            } 
1017968        } 
@@ -1084,22 +1035,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
10841035            return  None ; 
10851036        } 
10861037
1087-         let  name = match  ( ty. is_signed ( ) ,  ty. primitive_size ( self . tcx ) . bits ( ) )  { 
1088-             ( true ,  8 )  => "llvm.scmp.i8.i8" , 
1089-             ( true ,  16 )  => "llvm.scmp.i8.i16" , 
1090-             ( true ,  32 )  => "llvm.scmp.i8.i32" , 
1091-             ( true ,  64 )  => "llvm.scmp.i8.i64" , 
1092-             ( true ,  128 )  => "llvm.scmp.i8.i128" , 
1093- 
1094-             ( false ,  8 )  => "llvm.ucmp.i8.i8" , 
1095-             ( false ,  16 )  => "llvm.ucmp.i8.i16" , 
1096-             ( false ,  32 )  => "llvm.ucmp.i8.i32" , 
1097-             ( false ,  64 )  => "llvm.ucmp.i8.i64" , 
1098-             ( false ,  128 )  => "llvm.ucmp.i8.i128" , 
1038+         let  size = ty. primitive_size ( self . tcx ) ; 
1039+         let  name = if  ty. is_signed ( )  {  "llvm.scmp"  }  else  {  "llvm.ucmp"  } ; 
10991040
1100-             _ => bug ! ( "three-way compare unsupported for type {ty:?}" ) , 
1101-         } ; 
1102-         Some ( self . call_intrinsic ( name,  & [ lhs,  rhs] ) ) 
1041+         Some ( self . call_intrinsic ( & name,  & [ self . type_i8 ( ) ,  self . type_ix ( size. bits ( ) ) ] ,  & [ lhs,  rhs] ) ) 
11031042    } 
11041043
11051044    /* Miscellaneous instructions */ 
@@ -1385,11 +1324,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
13851324    } 
13861325
13871326    fn  lifetime_start ( & mut  self ,  ptr :  & ' ll  Value ,  size :  Size )  { 
1388-         self . call_lifetime_intrinsic ( "llvm.lifetime.start.p0i8 " ,  ptr,  size) ; 
1327+         self . call_lifetime_intrinsic ( "llvm.lifetime.start" ,  ptr,  size) ; 
13891328    } 
13901329
13911330    fn  lifetime_end ( & mut  self ,  ptr :  & ' ll  Value ,  size :  Size )  { 
1392-         self . call_lifetime_intrinsic ( "llvm.lifetime.end.p0i8 " ,  ptr,  size) ; 
1331+         self . call_lifetime_intrinsic ( "llvm.lifetime.end" ,  ptr,  size) ; 
13931332    } 
13941333
13951334    fn  call ( 
@@ -1454,7 +1393,7 @@ impl<'ll> StaticBuilderMethods for Builder<'_, 'll, '_> {
14541393        // Forward to the `get_static` method of `CodegenCx` 
14551394        let  global = self . cx ( ) . get_static ( def_id) ; 
14561395        if  self . cx ( ) . tcx . is_thread_local_static ( def_id)  { 
1457-             let  pointer = self . call_intrinsic ( "llvm.threadlocal.address" ,  & [ global] ) ; 
1396+             let  pointer = self . call_intrinsic ( "llvm.threadlocal.address" ,  & [ ] ,   & [ global] ) ; 
14581397            // Cast to default address space if globals are in a different addrspace 
14591398            self . pointercast ( pointer,  self . type_ptr ( ) ) 
14601399        }  else  { 
@@ -1649,8 +1588,13 @@ impl<'a, 'll, CX: Borrow<SCx<'ll>>> GenericBuilder<'a, 'll, CX> {
16491588} 
16501589
16511590impl < ' a ,  ' ll ,  ' tcx >  Builder < ' a ,  ' ll ,  ' tcx >  { 
1652-     pub ( crate )  fn  call_intrinsic ( & mut  self ,  intrinsic :  & str ,  args :  & [ & ' ll  Value ] )  -> & ' ll  Value  { 
1653-         let  ( ty,  f)  = self . cx . get_intrinsic ( intrinsic) ; 
1591+     pub ( crate )  fn  call_intrinsic ( 
1592+         & mut  self , 
1593+         base_name :  & str , 
1594+         type_params :  & [ & ' ll  Type ] , 
1595+         args :  & [ & ' ll  Value ] , 
1596+     )  -> & ' ll  Value  { 
1597+         let  ( ty,  f)  = self . cx . get_intrinsic ( base_name,  type_params) ; 
16541598        self . call ( ty,  None ,  None ,  f,  args,  None ,  None ) 
16551599    } 
16561600
@@ -1664,7 +1608,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
16641608            return ; 
16651609        } 
16661610
1667-         self . call_intrinsic ( intrinsic,  & [ self . cx . const_u64 ( size) ,  ptr] ) ; 
1611+         self . call_intrinsic ( intrinsic,  & [ self . type_ptr ( ) ] ,   & [ self . cx . const_u64 ( size) ,  ptr] ) ; 
16681612    } 
16691613} 
16701614impl < ' a ,  ' ll ,  CX :  Borrow < SCx < ' ll > > >  GenericBuilder < ' a ,  ' ll ,  CX >  { 
@@ -1689,31 +1633,6 @@ impl<'a, 'll, CX: Borrow<SCx<'ll>>> GenericBuilder<'a, 'll, CX> {
16891633    } 
16901634} 
16911635impl < ' a ,  ' ll ,  ' tcx >  Builder < ' a ,  ' ll ,  ' tcx >  { 
1692-     fn  fptoint_sat ( & mut  self ,  signed :  bool ,  val :  & ' ll  Value ,  dest_ty :  & ' ll  Type )  -> & ' ll  Value  { 
1693-         let  src_ty = self . cx . val_ty ( val) ; 
1694-         let  ( float_ty,  int_ty,  vector_length)  = if  self . cx . type_kind ( src_ty)  == TypeKind :: Vector  { 
1695-             assert_eq ! ( self . cx. vector_length( src_ty) ,  self . cx. vector_length( dest_ty) ) ; 
1696-             ( 
1697-                 self . cx . element_type ( src_ty) , 
1698-                 self . cx . element_type ( dest_ty) , 
1699-                 Some ( self . cx . vector_length ( src_ty) ) , 
1700-             ) 
1701-         }  else  { 
1702-             ( src_ty,  dest_ty,  None ) 
1703-         } ; 
1704-         let  float_width = self . cx . float_width ( float_ty) ; 
1705-         let  int_width = self . cx . int_width ( int_ty) ; 
1706- 
1707-         let  instr = if  signed {  "fptosi"  }  else  {  "fptoui"  } ; 
1708-         let  name = if  let  Some ( vector_length)  = vector_length { 
1709-             format ! ( "llvm.{instr}.sat.v{vector_length}i{int_width}.v{vector_length}f{float_width}" ) 
1710-         }  else  { 
1711-             format ! ( "llvm.{instr}.sat.i{int_width}.f{float_width}" ) 
1712-         } ; 
1713-         let  f = self . declare_cfn ( & name,  llvm:: UnnamedAddr :: No ,  self . type_func ( & [ src_ty] ,  dest_ty) ) ; 
1714-         self . call ( self . type_func ( & [ src_ty] ,  dest_ty) ,  None ,  None ,  f,  & [ val] ,  None ,  None ) 
1715-     } 
1716- 
17171636    pub ( crate )  fn  landing_pad ( 
17181637        & mut  self , 
17191638        ty :  & ' ll  Type , 
@@ -1819,7 +1738,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
18191738            // llvm.type.test intrinsic. The LowerTypeTests link-time optimization pass replaces 
18201739            // calls to this intrinsic with code to test type membership. 
18211740            let  typeid = self . get_metadata_value ( typeid_metadata) ; 
1822-             let  cond = self . call_intrinsic ( "llvm.type.test" ,  & [ llfn,  typeid] ) ; 
1741+             let  cond = self . call_intrinsic ( "llvm.type.test" ,  & [ ] ,   & [ llfn,  typeid] ) ; 
18231742            let  bb_pass = self . append_sibling_block ( "type_test.pass" ) ; 
18241743            let  bb_fail = self . append_sibling_block ( "type_test.fail" ) ; 
18251744            self . cond_br ( cond,  bb_pass,  bb_fail) ; 
@@ -1887,7 +1806,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
18871806        num_counters :  & ' ll  Value , 
18881807        index :  & ' ll  Value , 
18891808    )  { 
1890-         self . call_intrinsic ( "llvm.instrprof.increment" ,  & [ fn_name,  hash,  num_counters,  index] ) ; 
1809+         self . call_intrinsic ( "llvm.instrprof.increment" ,  & [ ] ,   & [ fn_name,  hash,  num_counters,  index] ) ; 
18911810    } 
18921811
18931812    /// Emits a call to `llvm.instrprof.mcdc.parameters`. 
@@ -1906,7 +1825,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
19061825        hash :  & ' ll  Value , 
19071826        bitmap_bits :  & ' ll  Value , 
19081827    )  { 
1909-         self . call_intrinsic ( "llvm.instrprof.mcdc.parameters" ,  & [ fn_name,  hash,  bitmap_bits] ) ; 
1828+         self . call_intrinsic ( "llvm.instrprof.mcdc.parameters" ,  & [ ] ,   & [ fn_name,  hash,  bitmap_bits] ) ; 
19101829    } 
19111830
19121831    #[ instrument( level = "debug" ,  skip( self ) ) ]  
@@ -1918,7 +1837,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
19181837        mcdc_temp :  & ' ll  Value , 
19191838    )  { 
19201839        let  args = & [ fn_name,  hash,  bitmap_index,  mcdc_temp] ; 
1921-         self . call_intrinsic ( "llvm.instrprof.mcdc.tvbitmap.update" ,  args) ; 
1840+         self . call_intrinsic ( "llvm.instrprof.mcdc.tvbitmap.update" ,  & [ ] ,   args) ; 
19221841    } 
19231842
19241843    #[ instrument( level = "debug" ,  skip( self ) ) ]  
0 commit comments