Index: gcc/gcc/config/i386/i386.c =================================================================== --- gcc.orig/gcc/config/i386/i386.c +++ gcc/gcc/config/i386/i386.c @@ -4506,11 +4506,15 @@ ix86_pass_by_reference (CUMULATIVE_ARGS } } - /* __m128 is passed by reference. */ - /* ??? How to handle complex? For now treat them as structs, - and pass them by reference if they're too large. */ - if (GET_MODE_SIZE (mode) > 8) - return true; + if (COMPLEX_MODE_P (mode) || VECTOR_MODE_P (mode)) + return true; + switch (GET_MODE_SIZE (mode)) + { + case 1: case 2: case 4: case 8: + break; + default: + return true; + } } else if (TARGET_64BIT && type && int_size_in_bytes (type) == -1) return 1; @@ -4823,13 +4827,14 @@ return_in_memory_ms_64 (const_tree type, { HOST_WIDE_INT size = int_size_in_bytes (type); - /* __m128 and friends are returned in xmm0. */ - if (!COMPLEX_MODE_P (mode) && size == 16 && VECTOR_MODE_P (mode)) - return 0; + /* Structures pass always via memory. */ + if (mode == BLKmode) + return 1; - /* Otherwise, the size must be exactly in [1248]. But not for complex. */ + /* Otherwise, the size must be exactly in [1248]. But not for complex + and vector. */ return (size != 1 && size != 2 && size != 4 && size != 8) - || COMPLEX_MODE_P (mode); + || COMPLEX_MODE_P (mode) || VECTOR_MODE_P (mode); } int =