Hello! Currently, gcc emits wrong warning for MMX argument passing on 32 bit targets, even when MMX is enabled:
pr59405.c: In function ‘foo32x2_be’: pr59405.c:7:1: warning: SSE vector argument without SSE enabled changes the ABI [enabled by default] foo32x2_be (float32x2_t x) Attached patch fixes this oversight. The testcase also tests correct function of necessary _mm_empty intrinsic. 2013-12-06 Uros Bizjak <ubiz...@gmail.com> PR target/59405 * config/i386/i386.c (type_natural_mode): Properly handle size 8 for !TARGET_64BIT. testsuite/ChangeLog: 2013-12-06 Uros Bizjak <ubiz...@gmail.com> PR target/59405 * gcc.target/i386/pr59405.c: New test. Bootstrapped and regression tested on x86_64-pc-linux-gnu {,-m32} and committed to mainline SVN. The patch will be backported to other release branches. Uros.
Index: config/i386/i386.c =================================================================== --- config/i386/i386.c (revision 205748) +++ config/i386/i386.c (working copy) @@ -6172,7 +6172,8 @@ type_natural_mode (const_tree type, const CUMULATI } return TYPE_MODE (type); } - else if ((size == 8 || size == 16) && !TARGET_SSE) + else if (((size == 8 && TARGET_64BIT) || size == 16) + && !TARGET_SSE) { static bool warnedsse; @@ -6184,10 +6185,21 @@ type_natural_mode (const_tree type, const CUMULATI warning (0, "SSE vector argument without SSE " "enabled changes the ABI"); } - return mode; } - else - return mode; + else if ((size == 8 && !TARGET_64BIT) && !TARGET_MMX) + { + static bool warnedmmx; + + if (cum + && !warnedmmx + && cum->warn_mmx) + { + warnedmmx = true; + warning (0, "MMX vector argument without MMX " + "enabled changes the ABI"); + } + } + return mode; } gcc_unreachable (); Index: testsuite/gcc.target/i386/pr59405.c =================================================================== --- testsuite/gcc.target/i386/pr59405.c (revision 0) +++ testsuite/gcc.target/i386/pr59405.c (working copy) @@ -0,0 +1,24 @@ +/* { dg-do run } */ +/* { dg-options "-mmmx -mfpmath=387" } */ + +#include "mmx-check.h" + +#include <mmintrin.h> + +typedef float float32x2_t __attribute__ ((vector_size (8))); + +float +foo32x2_be (float32x2_t x) +{ + _mm_empty(); + return x[1]; +} + +static void +mmx_test (void) +{ + float32x2_t b = { 0.0f, 1.0f }; + + if (foo32x2_be (b) != 1.0f) + abort (); +}