@@ -728,49 +728,45 @@ pub fn invoke<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
728728 }
729729 }
730730
731- if need_invoke ( bcx) {
731+ let ( mut llresult , bcx ) = if need_invoke ( bcx) {
732732 debug ! ( "invoking {} at {:?}" , bcx. val_to_string( llfn) , bcx. llbb) ;
733733 for & llarg in llargs {
734734 debug ! ( "arg: {}" , bcx. val_to_string( llarg) ) ;
735735 }
736736 let normal_bcx = bcx. fcx . new_temp_block ( "normal-return" ) ;
737737 let landing_pad = bcx. fcx . get_landing_pad ( ) ;
738738
739- let mut llresult = Invoke ( bcx,
739+ let llresult = Invoke ( bcx,
740740 llfn,
741741 & llargs[ ..] ,
742742 normal_bcx. llbb ,
743743 landing_pad,
744744 Some ( attributes) ,
745745 debug_loc) ;
746- if let ty:: FnConverging ( ty) = ret_ty {
747- if return_type_is_void ( bcx. ccx ( ) , ty) {
748- llresult = C_nil ( bcx. ccx ( ) ) ;
749- }
750- } else {
751- llresult = C_nil ( bcx. ccx ( ) ) ;
752- }
753- return ( llresult, normal_bcx) ;
746+ ( llresult, normal_bcx)
754747 } else {
755748 debug ! ( "calling {} at {:?}" , bcx. val_to_string( llfn) , bcx. llbb) ;
756749 for & llarg in llargs {
757750 debug ! ( "arg: {}" , bcx. val_to_string( llarg) ) ;
758751 }
759752
760- let mut llresult = Call ( bcx,
753+ let llresult = Call ( bcx,
761754 llfn,
762755 & llargs[ ..] ,
763756 Some ( attributes) ,
764757 debug_loc) ;
765- if let ty :: FnConverging ( ty ) = ret_ty {
766- if return_type_is_void ( bcx . ccx ( ) , ty ) {
767- llresult = C_nil ( bcx . ccx ( ) ) ;
768- }
769- } else {
758+ ( llresult , bcx )
759+ } ;
760+
761+ if let ty :: FnConverging ( ty ) = ret_ty {
762+ if return_type_is_void ( bcx . ccx ( ) , ty ) {
770763 llresult = C_nil ( bcx. ccx ( ) ) ;
771764 }
772- return ( llresult, bcx) ;
765+ } else {
766+ llresult = C_nil ( bcx. ccx ( ) ) ;
773767 }
768+
769+ ( llresult, bcx)
774770}
775771
776772pub fn need_invoke ( bcx : Block ) -> bool {
@@ -803,41 +799,30 @@ pub fn load_if_immediate<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
803799/// gives us better information about what we are loading.
804800pub fn load_ty < ' blk , ' tcx > ( cx : Block < ' blk , ' tcx > ,
805801 ptr : ValueRef , t : Ty < ' tcx > ) -> ValueRef {
806- use trans:: basic_block:: BasicBlock ;
807-
808802 if cx. unreachable . get ( ) || type_is_zero_size ( cx. ccx ( ) , t) {
809803 return C_undef ( type_of:: type_of ( cx. ccx ( ) , t) ) ;
810804 }
811805
812806 let ptr = to_arg_ty_ptr ( cx, ptr, t) ;
813- let ptr = Value ( ptr) ;
814807 let align = type_of:: align_of ( cx. ccx ( ) , t) ;
815808
816- let bb = BasicBlock ( cx. llbb ) ;
817-
818809 if type_is_immediate ( cx. ccx ( ) , t) && type_of:: type_of ( cx. ccx ( ) , t) . is_aggregate ( ) {
819- if let Some ( val) = ptr. get_dominating_store ( cx) {
820- let valbb = val. get_parent ( ) ;
821-
822- if Some ( bb) == valbb {
823- if let Some ( val) = val. get_operand ( 0 ) {
824- debug ! ( "Eliding load from {}" , cx. ccx( ) . tn( ) . val_to_string( ptr. get( ) ) ) ;
825- debug ! ( " Using previous stored value: {}" ,
826- cx. ccx( ) . tn( ) . val_to_string( val. get( ) ) ) ;
827- return val. get ( ) ;
828- }
829- }
810+ if let Some ( val) = Value ( ptr) . get_stored_value_opt ( cx) {
811+ debug ! ( "Eliding load from {}" , cx. ccx( ) . tn( ) . val_to_string( ptr) ) ;
812+ debug ! ( " Using previous stored value: {}" ,
813+ cx. ccx( ) . tn( ) . val_to_string( val. get( ) ) ) ;
814+ return val. get ( ) ;
830815 }
831816
832- let load = Load ( cx, ptr. get ( ) ) ;
817+ let load = Load ( cx, ptr) ;
833818 unsafe {
834819 llvm:: LLVMSetAlignment ( load, align) ;
835820 }
836821 return load;
837822 }
838823
839824 unsafe {
840- let global = llvm:: LLVMIsAGlobalVariable ( ptr. get ( ) ) ;
825+ let global = llvm:: LLVMIsAGlobalVariable ( ptr) ;
841826 if !global. is_null ( ) && llvm:: LLVMIsGlobalConstant ( global) == llvm:: True {
842827 let val = llvm:: LLVMGetInitializer ( global) ;
843828 if !val. is_null ( ) {
@@ -846,30 +831,24 @@ pub fn load_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
846831 }
847832 }
848833
849- if let Some ( val) = ptr. get_dominating_store ( cx) {
850- let valbb = val. get_parent ( ) ;
851-
852- if Some ( bb) == valbb {
853- if let Some ( val) = val. get_operand ( 0 ) {
854- debug ! ( "Eliding load from {}" , cx. ccx( ) . tn( ) . val_to_string( ptr. get( ) ) ) ;
855- debug ! ( " Using previous stored value: {}" ,
856- cx. ccx( ) . tn( ) . val_to_string( val. get( ) ) ) ;
857- return to_arg_ty ( cx, val. get ( ) , t) ;
858- }
859- }
834+ if let Some ( val) = Value ( ptr) . get_stored_value_opt ( cx) {
835+ debug ! ( "Eliding load from {}" , cx. ccx( ) . tn( ) . val_to_string( ptr) ) ;
836+ debug ! ( " Using previous stored value: {}" ,
837+ cx. ccx( ) . tn( ) . val_to_string( val. get( ) ) ) ;
838+ return to_arg_ty ( cx, val. get ( ) , t) ;
860839 }
861840
862841 let val = if t. is_bool ( ) {
863- LoadRangeAssert ( cx, ptr. get ( ) , 0 , 2 , llvm:: False )
842+ LoadRangeAssert ( cx, ptr, 0 , 2 , llvm:: False )
864843 } else if t. is_char ( ) {
865844 // a char is a Unicode codepoint, and so takes values from 0
866845 // to 0x10FFFF inclusive only.
867- LoadRangeAssert ( cx, ptr. get ( ) , 0 , 0x10FFFF + 1 , llvm:: False )
846+ LoadRangeAssert ( cx, ptr, 0 , 0x10FFFF + 1 , llvm:: False )
868847 } else if ( t. is_region_ptr ( ) || t. is_unique ( ) )
869848 && !common:: type_is_fat_ptr ( cx. tcx ( ) , t) {
870- LoadNonNull ( cx, ptr. get ( ) )
849+ LoadNonNull ( cx, ptr)
871850 } else {
872- Load ( cx, ptr. get ( ) )
851+ Load ( cx, ptr)
873852 } ;
874853
875854 unsafe {
@@ -918,11 +897,16 @@ pub fn from_arg_ty(bcx: Block, val: ValueRef, ty: Ty) -> ValueRef {
918897
919898pub fn to_arg_ty ( bcx : Block , val : ValueRef , ty : Ty ) -> ValueRef {
920899 if ty. is_bool ( ) {
900+ // Look for cases where we're truncating a zext from a bool already and grab the original
901+ // value. This can happen with an elided load from a boolean location. While this can be
902+ // easily optimized out, the indirection can interfere with some intrinsics.
921903 let val = Value ( val) ;
922904 if let Some ( zext) = val. as_zext_inst ( ) {
905+ // `val` == zext %foo
923906 if let Some ( val) = zext. get_operand ( 0 ) {
924907 let valty = val_ty ( val. get ( ) ) ;
925908 if valty == Type :: i1 ( bcx. ccx ( ) ) {
909+ // %foo : i1
926910 return val. get ( ) ;
927911 }
928912 }
0 commit comments