BUG/ENH: guarantee blocks will upcast as needed, and split as needed

- replace on an IntBlock with a float will upcast, it may yield multiple blocks if the original IntBlock didn't fully replace

- small fix in com.mask_missing to guarantee that a bool ndarray is returned even in the case of a string comparison with a numeric array, (which for some reason numpy returns a single, non-ndarray value)

allows #3064 to proceed (e.g. df.replace(0,0.5) will work on an integer dtype)