In the Microsoft implementation of the C# compiler and CLR, value types are stored on the stack when the value is a temporary value, local variable or formal parameter, that is neither a closed-over outer variable of an anonymous method nor in an iterator block.
Of course, why store stuff on the stack if you don't need to? Some local variables of value type never get on the stack at all; they stay in registers for their entire lifetimes.
Other values of value types are stored on the heap - boxed value types, value-typed fields on a reference type, and so on.
Value types can of course be stored on neither the stack, nor registers, nor the managed heap; they could be stored in unmanaged memory using some completely other memory manager not under control of the CLR.
(And of course note that using "the" in "the stack" is subtly misleading; there can be many stacks in a process. There need not be just one.)
All this is an implementation detail and subject to change without notice.
Also, obviously stuff allocated with the stack alloc declaration is allocated on the stack.
For more information on this topic see my articles on it:
http://blogs.msdn.com/b/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx
http://blogs.msdn.com/b/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx
Why do you care? The runtime manages all these details for you so that you don't have to worry about it. Are you just curious, or is this leading to some larger question?