@@ -352,84 +352,84 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
352352 | sym:: saturating_add
353353 | sym:: saturating_sub => {
354354 let ty = arg_tys[ 0 ] ;
355- match int_type_width_signed ( ty, self ) {
356- Some ( ( width, signed) ) => match name {
357- sym:: ctlz | sym:: cttz => {
358- let y = self . const_bool ( false ) ;
359- let ret = self . call_intrinsic ( & format ! ( "llvm.{name}.i{width}" ) , & [
360- args[ 0 ] . immediate ( ) ,
361- y,
362- ] ) ;
363-
364- self . intcast ( ret, llret_ty, false )
365- }
366- sym:: ctlz_nonzero => {
367- let y = self . const_bool ( true ) ;
368- let llvm_name = & format ! ( "llvm.ctlz.i{width}" ) ;
369- let ret = self . call_intrinsic ( llvm_name, & [ args[ 0 ] . immediate ( ) , y] ) ;
370- self . intcast ( ret, llret_ty, false )
371- }
372- sym:: cttz_nonzero => {
373- let y = self . const_bool ( true ) ;
374- let llvm_name = & format ! ( "llvm.cttz.i{width}" ) ;
375- let ret = self . call_intrinsic ( llvm_name, & [ args[ 0 ] . immediate ( ) , y] ) ;
376- self . intcast ( ret, llret_ty, false )
377- }
378- sym:: ctpop => {
379- let ret = self . call_intrinsic ( & format ! ( "llvm.ctpop.i{width}" ) , & [ args
380- [ 0 ]
381- . immediate ( ) ] ) ;
382- self . intcast ( ret, llret_ty, false )
383- }
384- sym:: bswap => {
385- if width == 8 {
386- args[ 0 ] . immediate ( ) // byte swap a u8/i8 is just a no-op
387- } else {
388- self . call_intrinsic ( & format ! ( "llvm.bswap.i{width}" ) , & [
389- args[ 0 ] . immediate ( )
390- ] )
391- }
392- }
393- sym:: bitreverse => self
394- . call_intrinsic ( & format ! ( "llvm.bitreverse.i{width}" ) , & [
355+ if !ty. is_integral ( ) {
356+ tcx. dcx ( ) . emit_err ( InvalidMonomorphization :: BasicIntegerType {
357+ span,
358+ name,
359+ ty,
360+ } ) ;
361+ return Ok ( ( ) ) ;
362+ }
363+ let ( size, signed) = ty. int_size_and_signed ( self . tcx ) ;
364+ let width = size. bits ( ) ;
365+ match name {
366+ sym:: ctlz | sym:: cttz => {
367+ let y = self . const_bool ( false ) ;
368+ let ret = self . call_intrinsic ( & format ! ( "llvm.{name}.i{width}" ) , & [
369+ args[ 0 ] . immediate ( ) ,
370+ y,
371+ ] ) ;
372+
373+ self . intcast ( ret, llret_ty, false )
374+ }
375+ sym:: ctlz_nonzero => {
376+ let y = self . const_bool ( true ) ;
377+ let llvm_name = & format ! ( "llvm.ctlz.i{width}" ) ;
378+ let ret = self . call_intrinsic ( llvm_name, & [ args[ 0 ] . immediate ( ) , y] ) ;
379+ self . intcast ( ret, llret_ty, false )
380+ }
381+ sym:: cttz_nonzero => {
382+ let y = self . const_bool ( true ) ;
383+ let llvm_name = & format ! ( "llvm.cttz.i{width}" ) ;
384+ let ret = self . call_intrinsic ( llvm_name, & [ args[ 0 ] . immediate ( ) , y] ) ;
385+ self . intcast ( ret, llret_ty, false )
386+ }
387+ sym:: ctpop => {
388+ let ret = self . call_intrinsic ( & format ! ( "llvm.ctpop.i{width}" ) , & [
389+ args[ 0 ] . immediate ( )
390+ ] ) ;
391+ self . intcast ( ret, llret_ty, false )
392+ }
393+ sym:: bswap => {
394+ if width == 8 {
395+ args[ 0 ] . immediate ( ) // byte swap a u8/i8 is just a no-op
396+ } else {
397+ self . call_intrinsic ( & format ! ( "llvm.bswap.i{width}" ) , & [
395398 args[ 0 ] . immediate ( )
396- ] ) ,
397- sym:: rotate_left | sym:: rotate_right => {
398- let is_left = name == sym:: rotate_left;
399- let val = args[ 0 ] . immediate ( ) ;
400- let raw_shift = args[ 1 ] . immediate ( ) ;
401- // rotate = funnel shift with first two args the same
402- let llvm_name =
403- & format ! ( "llvm.fsh{}.i{}" , if is_left { 'l' } else { 'r' } , width) ;
404-
405- // llvm expects shift to be the same type as the values, but rust
406- // always uses `u32`.
407- let raw_shift = self . intcast ( raw_shift, self . val_ty ( val) , false ) ;
408-
409- self . call_intrinsic ( llvm_name, & [ val, val, raw_shift] )
399+ ] )
410400 }
411- sym:: saturating_add | sym:: saturating_sub => {
412- let is_add = name == sym:: saturating_add;
413- let lhs = args[ 0 ] . immediate ( ) ;
414- let rhs = args[ 1 ] . immediate ( ) ;
415- let llvm_name = & format ! (
416- "llvm.{}{}.sat.i{}" ,
417- if signed { 's' } else { 'u' } ,
418- if is_add { "add" } else { "sub" } ,
419- width
420- ) ;
421- self . call_intrinsic ( llvm_name, & [ lhs, rhs] )
422- }
423- _ => bug ! ( ) ,
424- } ,
425- None => {
426- tcx. dcx ( ) . emit_err ( InvalidMonomorphization :: BasicIntegerType {
427- span,
428- name,
429- ty,
430- } ) ;
431- return Ok ( ( ) ) ;
432401 }
402+ sym:: bitreverse => self
403+ . call_intrinsic ( & format ! ( "llvm.bitreverse.i{width}" ) , & [
404+ args[ 0 ] . immediate ( )
405+ ] ) ,
406+ sym:: rotate_left | sym:: rotate_right => {
407+ let is_left = name == sym:: rotate_left;
408+ let val = args[ 0 ] . immediate ( ) ;
409+ let raw_shift = args[ 1 ] . immediate ( ) ;
410+ // rotate = funnel shift with first two args the same
411+ let llvm_name =
412+ & format ! ( "llvm.fsh{}.i{}" , if is_left { 'l' } else { 'r' } , width) ;
413+
414+ // llvm expects shift to be the same type as the values, but rust
415+ // always uses `u32`.
416+ let raw_shift = self . intcast ( raw_shift, self . val_ty ( val) , false ) ;
417+
418+ self . call_intrinsic ( llvm_name, & [ val, val, raw_shift] )
419+ }
420+ sym:: saturating_add | sym:: saturating_sub => {
421+ let is_add = name == sym:: saturating_add;
422+ let lhs = args[ 0 ] . immediate ( ) ;
423+ let rhs = args[ 1 ] . immediate ( ) ;
424+ let llvm_name = & format ! (
425+ "llvm.{}{}.sat.i{}" ,
426+ if signed { 's' } else { 'u' } ,
427+ if is_add { "add" } else { "sub" } ,
428+ width
429+ ) ;
430+ self . call_intrinsic ( llvm_name, & [ lhs, rhs] )
431+ }
432+ _ => bug ! ( ) ,
433433 }
434434 }
435435
@@ -2531,19 +2531,3 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
25312531
25322532 span_bug ! ( span, "unknown SIMD intrinsic" ) ;
25332533}
2534-
2535- // Returns the width of an int Ty, and if it's signed or not
2536- // Returns None if the type is not an integer
2537- // FIXME: there’s multiple of this functions, investigate using some of the already existing
2538- // stuffs.
2539- fn int_type_width_signed ( ty : Ty < ' _ > , cx : & CodegenCx < ' _ , ' _ > ) -> Option < ( u64 , bool ) > {
2540- match ty. kind ( ) {
2541- ty:: Int ( t) => {
2542- Some ( ( t. bit_width ( ) . unwrap_or ( u64:: from ( cx. tcx . sess . target . pointer_width ) ) , true ) )
2543- }
2544- ty:: Uint ( t) => {
2545- Some ( ( t. bit_width ( ) . unwrap_or ( u64:: from ( cx. tcx . sess . target . pointer_width ) ) , false ) )
2546- }
2547- _ => None ,
2548- }
2549- }
0 commit comments