https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89582
--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> --- Looks like LLVM has all the ABI details exposed very early but also in a very awkward way(?). The vfloat one shows define { <2 x float>, <2 x float> } @f(<2 x float> %x.coerce0, <2 x float> %x.coerce1, <2 x float> %y.coerce0, <2 x float> %y.coerce1) #0 { %1 = alloca %struct.vfloat, align 16 %x = alloca %struct.vfloat, align 16 %y = alloca %struct.vfloat, align 16 %2 = bitcast %struct.vfloat* %x to { <2 x float>, <2 x float> }* %3 = getelementptr inbounds { <2 x float>, <2 x float> }, { <2 x float>, <2 x float> }* %2, i32 0, i32 0 store <2 x float> %x.coerce0, <2 x float>* %3, align 16 %4 = getelementptr inbounds { <2 x float>, <2 x float> }, { <2 x float>, <2 x float> }* %2, i32 0, i32 1 store <2 x float> %x.coerce1, <2 x float>* %4, align 8 %5 = bitcast %struct.vfloat* %y to { <2 x float>, <2 x float> }* %6 = getelementptr inbounds { <2 x float>, <2 x float> }, { <2 x float>, <2 x float> }* %5, i32 0, i32 0 store <2 x float> %y.coerce0, <2 x float>* %6, align 16 %7 = getelementptr inbounds { <2 x float>, <2 x float> }, { <2 x float>, <2 x float> }* %5, i32 0, i32 1 store <2 x float> %y.coerce1, <2 x float>* %7, align 8 for the parameter setup (if I deciper the IL correctly) and %32 = bitcast %struct.vfloat* %1 to { <2 x float>, <2 x float> }* %33 = load { <2 x float>, <2 x float> }, { <2 x float>, <2 x float> }* %32, align 16 ret { <2 x float>, <2 x float> } %33 for the return value. I was thinking of a way to expose the ABI details to GIMPLE recently but feared this would look a bit like a mess (also considering prologue/epilogue expansion target constraints).