Thanks to ACF support I was able to solve my problem like this:
function my_auto_title( $post_id ) {
// Check if this is not an autosave
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
// Check if this is a revision
if ( wp_is_post_revision( $post_id ) ) {
return;
}
// Set the post title based on ACF fields
$title = get_field('field_65a95b23de2d4', $post_id) . ' - ' . get_field('field_65a95bd0de2d5', $post_id);
$post = array(
'ID' => $post_id,
'post_title' => $title,
);
// Remove the action to avoid infinite loop
remove_action( 'acf/save_post', 'my_auto_title', 20 );
// Update the post
wp_update_post( $post );
// Re-add the action
add_action( 'acf/save_post', 'my_auto_title', 20 );
}
add_action('acf/save_post', 'my_auto_title', 20);
Not entirely sure why the infinite loop is not triggered anymore, but leaving this here if someone has a similar problem.