Multiple values in the standard iteration constructs is not really supported.
With LOOP your snippet might look like this:
(loop with x and y and z
do (setf (values x y z) (3-val-fn))
while (equal y 'some-val)
finally (return y)
do ...)
If I would need something like that often, I might define a do-mv
macro which would expand into above code. Code then would look like:
(do-mv ((x y z) (3-val-fn))
((equal y 'some-val) y)
...)
The advantage to use above is that it does not create lists from multiple values during each iteration. Creating lists out of multiple values kind of defeats the purpose of multiple values, which are there to return more than one values and allowing it to be implemented in an efficient way.