@@ -224,39 +224,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
224224 match int_type_width_signed ( ty, self ) {
225225 Some ( ( width, signed) ) => match name {
226226 sym:: ctlz | sym:: cttz => {
227- let func = self . current_func . borrow ( ) . expect ( "func" ) ;
228- let then_block = func. new_block ( "then" ) ;
229- let else_block = func. new_block ( "else" ) ;
230- let after_block = func. new_block ( "after" ) ;
231-
232- let arg = args[ 0 ] . immediate ( ) ;
233- let result = func. new_local ( None , self . u32_type , "zeros" ) ;
234- let zero = self . cx . gcc_zero ( arg. get_type ( ) ) ;
235- let cond = self . gcc_icmp ( IntPredicate :: IntEQ , arg, zero) ;
236- self . llbb ( ) . end_with_conditional ( None , cond, then_block, else_block) ;
237-
238- let zero_result = self . cx . gcc_uint ( self . u32_type , width) ;
239- then_block. add_assignment ( None , result, zero_result) ;
240- then_block. end_with_jump ( None , after_block) ;
241-
242- // NOTE: since jumps were added in a place
243- // count_leading_zeroes() does not expect, the current block
244- // in the state need to be updated.
245- self . switch_to_block ( else_block) ;
246-
247- let zeros = match name {
248- sym:: ctlz => self . count_leading_zeroes ( width, arg) ,
249- sym:: cttz => self . count_trailing_zeroes ( width, arg) ,
250- _ => unreachable ! ( ) ,
251- } ;
252- self . llbb ( ) . add_assignment ( None , result, zeros) ;
253- self . llbb ( ) . end_with_jump ( None , after_block) ;
254-
255- // NOTE: since jumps were added in a place rustc does not
256- // expect, the current block in the state need to be updated.
257- self . switch_to_block ( after_block) ;
258-
259- result. to_rvalue ( )
227+ self . checked_bitcount_intrinsic ( name, args[ 0 ] . immediate ( ) , width)
260228 }
261229 sym:: ctlz_nonzero => self . count_leading_zeroes ( width, args[ 0 ] . immediate ( ) ) ,
262230 sym:: cttz_nonzero => self . count_trailing_zeroes ( width, args[ 0 ] . immediate ( ) ) ,
@@ -712,7 +680,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
712680 self . gcc_int_cast ( result, result_type)
713681 }
714682
715- fn count_leading_zeroes ( & mut self , width : u64 , arg : RValue < ' gcc > ) -> RValue < ' gcc > {
683+ pub fn count_leading_zeroes ( & mut self , width : u64 , arg : RValue < ' gcc > ) -> RValue < ' gcc > {
716684 // TODO(antoyo): use width?
717685 let arg_type = arg. get_type ( ) ;
718686 let result_type = self . u32_type ;
@@ -743,15 +711,16 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
743711 let one = self . context . new_rvalue_one ( self . usize_type ) ;
744712 let two = self . context . new_rvalue_from_long ( self . usize_type , 2 ) ;
745713
746- let clzll = self . context . get_builtin_function ( "__builtin_clzll" ) ;
747-
748714 let first_elem = self . context . new_array_access ( None , result, zero) ;
749- let first_value = self . gcc_int_cast ( self . context . new_call ( None , clzll, & [ high] ) , arg_type) ;
715+ let high_ctlz = self . checked_bitcount_intrinsic ( sym:: ctlz, high, 64 ) ;
716+ let first_value = self . gcc_int_cast ( high_ctlz, arg_type) ;
750717 self . llbb ( )
751718 . add_assignment ( self . location , first_elem, first_value) ;
752719
753720 let second_elem = self . context . new_array_access ( self . location , result, one) ;
754- let cast = self . gcc_int_cast ( self . context . new_call ( self . location , clzll, & [ low] ) , arg_type) ;
721+
722+ let low_ctlz = self . checked_bitcount_intrinsic ( sym:: ctlz, low, 64 ) ;
723+ let cast = self . gcc_int_cast ( low_ctlz, arg_type) ;
755724 let second_value = self . add ( cast, sixty_four) ;
756725 self . llbb ( )
757726 . add_assignment ( self . location , second_elem, second_value) ;
@@ -788,7 +757,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
788757 self . context . new_cast ( self . location , res, result_type)
789758 }
790759
791- fn count_trailing_zeroes ( & mut self , _width : u64 , arg : RValue < ' gcc > ) -> RValue < ' gcc > {
760+ pub fn count_trailing_zeroes ( & mut self , _width : u64 , arg : RValue < ' gcc > ) -> RValue < ' gcc > {
792761 let arg_type = arg. get_type ( ) ;
793762 let result_type = self . u32_type ;
794763 let arg = if arg_type. is_signed ( self . cx ) {
@@ -826,15 +795,15 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
826795 let one = self . context . new_rvalue_one ( self . usize_type ) ;
827796 let two = self . context . new_rvalue_from_long ( self . usize_type , 2 ) ;
828797
829- let ctzll = self . context . get_builtin_function ( "__builtin_ctzll" ) ;
830-
831798 let first_elem = self . context . new_array_access ( self . location , result, zero) ;
832- let first_value = self . gcc_int_cast ( self . context . new_call ( self . location , ctzll, & [ low] ) , arg_type) ;
799+ let low_ctzll = self . checked_bitcount_intrinsic ( sym:: cttz, low , 64 ) ;
800+ let first_value = self . gcc_int_cast ( low_ctzll, arg_type) ;
833801 self . llbb ( )
834802 . add_assignment ( self . location , first_elem, first_value) ;
835803
836804 let second_elem = self . context . new_array_access ( self . location , result, one) ;
837- let second_value = self . gcc_add ( self . gcc_int_cast ( self . context . new_call ( self . location , ctzll, & [ high] ) , arg_type) , sixty_four) ;
805+ let high_ctzll = self . checked_bitcount_intrinsic ( sym:: cttz, high , 64 ) ;
806+ let second_value = self . gcc_add ( self . gcc_int_cast ( high_ctzll, arg_type) , sixty_four) ;
838807 self . llbb ( )
839808 . add_assignment ( self . location , second_elem, second_value) ;
840809
0 commit comments