Somehow the upsert part on FuelSDK core (ET_Patch class __construct) isn't used on patch(). Also a known feature request/update on https://github.com/salesforce-marketingcloud/FuelSDK-CSharp/issues/48.
Instead, I use a filter on a Row->get() to do my thing.
$row = new ET_DataExtension_Row();
$row->authStub = $client;
$row->filter = ['Property' => 'SubscriberKey', 'SimpleOperator' => 'equals', 'Value' => 123920932];
$row->props = ["SubscriberKey"];
$response = $row->get();
if (!count($response->results)) {
// use post
} else {
// use patch
}