TL/DR: use BroadcastScalarToVector256 when the source data is in memory, and Vector256<int>.Create in all other cases.
The documentation for BroadcastScalarToVector256 says it compiles into this assembly: VPBROADCASTD ymm, m32 This is what you want when the source scalar is in memory, but takes roundtrip to memory and back if the source data is a register. That roundtrip is slightly slower in terms of latency, even if the memory is on stack i.e. on L1D cache.
The documentation for Vector256.Create( int ) doesn’t say what it compiles into, only says that it corresponds to _mm256_set1_epi32 intrinsic in C++. This means JIT compiler is free to do whatever’s the most efficient.
If you call Vector256<int>.Create( 0 ) it should compile into vpxor ymm0, ymm0, ymm0 instruction, because that instruction is a fast way to zero out a vector.
When you call Vector256<int>.Create( -1 ) it should compile into vpcmpeqd ymm0, ymm0, ymm0 instruction or similar, again because the value is known to compiler, vpcmpeqd has no data dependencies, and does the job, fast.
When you pass a variable there, Create should compile into code like vmovd xmm0, eax; vpbroadcastd ymm0, xmm0, that’s two instructions, but still faster than roundtrip to memory and back.