Show most popular post of last 12 months

Just as @Rarst suggested, you must have your $args defined within your function. You could solve it by using global variables, but we don’t want too many such variables flying around!

Check out the PHP docs on the scope of a variable or write your code in a class.

You can also simplify your query. Here’s an example how your function could look like:

function mts_popular_tabs( $nr = 5 )
{
    $args = array(  
        'date_query'     => array( array( 'after' => '-1 year' ) ),  
        'posts_per_page' => (int) $nr,
        'orderby'        => 'comment_count',
        'order'          => 'DESC'  
    ); 
    $popular = new WP_Query( $args );
    // ... your loop ...
    wp_reset_postdata();
}

This will generate the following SQL query:

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID 
    FROM wp_posts 
    WHERE 1=1 
          AND ( ( post_date > '2013-04-06 11:30:26' ) ) 
          AND wp_posts.post_type="post" 
          AND (wp_posts.post_status="publish") 
    ORDER BY wp_posts.comment_count DESC 
    LIMIT 0, 5 

if the current date is '2014-04-06 11:30:26'.

ps: If you want the posts_where filter to only affect your instance of WP_Query, you should also move it into the function:

function mts_popular_tabs( $nr = 5 )
{
    add_filter( 'posts_where', 'filter_where' );
    $popular = new WP_Query( $args );
    remove_filter( 'posts_where', 'filter_where' );
    // ... your loop ...
    wp_reset_postdata();
}

but you don’t need it in this case.

Hope this helps.