Incompatible x86 calling convention for __m64 parameters and returns.

On x86 (32 bit) GCC passes mmx parameters in mm0, mm1 and mm2 and returns in mm0.
According to comments in X86CallingConv.td, llvm supposedly does the same:

// MMX vector types are always returned in MM0. If the target doesn't have
// MM0, it doesn't support these vector types.
CCIfType<[x86mmx], CCAssignToReg<[MM0]>>,

and

// The first 3 __m64 vector arguments are passed in mmx registers if the
// call is not a vararg call.
CCIfNotVarArg<CCIfType<[x86mmx],
               CCAssignToReg<[MM0, MM1, MM2]>>>,

However in practice, llvm is actually passing parameters on the stack and returning them
in the eax:edx register pair as if they were long long or unsigned long long.

This goes back to at least clang-3.0, but I couldn't find a bug report on it... maybe because
mmx intrinsics are rarely used, so it may have no real world implications.

R,
Brad Conroy

On x86 (32 bit) GCC passes mmx parameters in mm0, mm1 and mm2 and returns in mm0.
According to comments in X86CallingConv.td, llvm supposedly does the same:

  // MMX vector types are always returned in MM0. If the target doesn't have
  // MM0, it doesn't support these vector types.
  CCIfType<[x86mmx], CCAssignToReg<[MM0]>>,

and

  // The first 3 __m64 vector arguments are passed in mmx registers if the
  // call is not a vararg call.
  CCIfNotVarArg<CCIfType<[x86mmx],
                CCAssignToReg<[MM0, MM1, MM2]>>>,

However in practice, llvm is actually passing parameters on the stack and returning them
in the eax:edx register pair as if they were long long or unsigned long long.

This goes back to at least clang-3.0, but I couldn't find a bug report on it... maybe because
mmx intrinsics are rarely used, so it may have no real world implications.

You're probably right about the intrinsics being rarely used (at this point), but filing a bug report sounds like the right thing to do.

  -Hal