I believe we should be legalizing these with the rest of vector binary operations. If any custom lowering is required for these nodes, this will give the DAG combine between LegalizeVectorOps and LegalizeDAG to run on the custom code before constant build_vectors are lowered in LegalizeDAG.
Unfortunately, this regressed some AArch64 tests because that DAG combine is now combining (extract_subvector (build_vector)) into a narrower build_vector. This caused it to stop matching an isel pattern that was looking for a multipy and extract_subvector to generate u/smull2. Perhaps the MULHS/MULHU lowering should pick some new AArchISD node that can be directly matched u/smull2?
X86 is showing some weird code too due to aggressive constant broadcast formation using GPR even when it doesn't remove the BUILD_VECTOR completely.
This is zero extending a truncate implemented with packuswb which means the upper bits before the truncate were already zero. So that's pretty silly. I'll file a bug.