Ho sorry I think I misread the title of the topic and though it was an error 
Does the function f has any parameter into it?
If there is nothing else in there, and the only way to get to the parameters is via x and y, I would do:
x, y = g(input, params)
# f must have NO parameters
# Equivalent (by linearity of the gradient) to 
# l1 = f(x.detach(), y)
# l1.backward()
# l2 = -1*f(x, y.detach())
# l2.backward()
y.register_hook(lambda x: -x)
loss = f(x, y)
loss.backward()

Note that you should double check that you get the same gradients still as I might be missing something