Compiler bug with SSSE3 - by Tom Sirgedas

Status : 

  Fixed<br /><br />
		This item has been fixed in the current or upcoming version of this product.<br /><br />
		A more detailed explanation for the resolution of this particular item may have been provided in the comments section.


1
0
Sign in
to vote
ID 634606 Comments
Status Closed Workarounds
Type Bug Repros 0
Opened 1/4/2011 12:18:34 PM
Access Restriction Public

Description

as posted on http://social.msdn.microsoft.com/Forums/en/vcgeneral/thread/92f9515f-849b-429a-984b-ac32c20be69c

----

The code below displays an incorrect value in Release mode. ("0003 0003 0003 0003 0000 0003 0000 0003" -- all eight values should be 0003).

The code will produce the correct values if the out[] lines are deleted (which shouldn't matter, since they occur after the show()'s).

I'm using Visual Studio 2010, Version 10.0.30319.1 RTMRel

Here is the dissasembly: http://pastebin.com/phJcUFtj

Tom Sirgedas

#include <tmmintrin.h>
#include <stdio.h>
#include <stdint.h>

void show( const __m128i& m ) { printf( "%04X %04X %04X %04X %04X %04X %04X %04X\n"
  , ((uint16_t*)&m)[7], ((uint16_t*)&m)[6], ((uint16_t*)&m)[5], ((uint16_t*)&m)[4]
  , ((uint16_t*)&m)[3], ((uint16_t*)&m)[2], ((uint16_t*)&m)[1], ((uint16_t*)&m)[0] ); }

__m128i operator*( __m128i a, __m128i b ) { return _mm_mullo_epi16( a, b ); }  

const __m128i i0 = _mm_set1_epi16( 1 );
const __m128i i1 = _mm_set1_epi16( 1 );
const __m128i i2 = _mm_set1_epi16( 1 );
const __m128i i3 = _mm_set1_epi16( 1 );
const __m128i a = _mm_set1_epi16( 0x4000 );
void func( __m128i out[4], __m128i h[8] )
{ 
  __m128i D0 = _mm_mulhrs_epi16( h[0], a );
  __m128i D1 = _mm_mulhrs_epi16( h[1], a );
  __m128i D2 = _mm_mulhrs_epi16( h[2], a );
  __m128i D3 = _mm_mulhrs_epi16( h[3], a );
  __m128i D4 = _mm_mulhrs_epi16( h[4], a );
  __m128i D5 = _mm_mulhrs_epi16( h[5], a );
  __m128i D6 = _mm_mulhrs_epi16( h[6], a );
  __m128i D7 = _mm_mulhrs_epi16( h[7], a );
  
  __m128i R0 = _mm_hadd_epi16( _mm_hadd_epi16( D0 * i0, D0 * i1 ), _mm_hadd_epi16( D0 * i2, D0 * i3 ) );
  __m128i R1 = _mm_hadd_epi16( _mm_hadd_epi16( D1 * i0, D1 * i1 ), _mm_hadd_epi16( D1 * i2, D1 * i3 ) );
  __m128i R2 = _mm_hadd_epi16( _mm_hadd_epi16( D2 * i0, D2 * i1 ), _mm_hadd_epi16( D2 * i2, D2 * i3 ) );
  __m128i R3 = _mm_hadd_epi16( _mm_hadd_epi16( D3 * i0, D3 * i1 ), _mm_hadd_epi16( D3 * i2, D3 * i3 ) );
  __m128i R4 = _mm_hadd_epi16( _mm_hadd_epi16( D4 * i0, D4 * i1 ), _mm_hadd_epi16( D4 * i2, D4 * i3 ) );
  __m128i R5 = _mm_hadd_epi16( _mm_hadd_epi16( D5 * i0, D5 * i1 ), _mm_hadd_epi16( D5 * i2, D5 * i3 ) );
  __m128i R6 = _mm_hadd_epi16( _mm_hadd_epi16( D6 * i0, D6 * i1 ), _mm_hadd_epi16( D6 * i2, D6 * i3 ) );
  
  __m128i expectedValue = _mm_set1_epi16( 3 );
  show( expectedValue );
  show( R0 );
         
  out[0] = R0 * R1 * R2 * R3 * R4 * R5;
  out[1] = R3;
  out[2] = R4 * R6;
  out[3] = R1 * R6;  
}

int main()
{
  const __m128i zero = _mm_setzero_si128();
  __m128i h[8] = { _mm_set_epi16( 0, 0, 0, 6, 0, 0, 0, 6 ), zero, zero, zero, zero, zero, zero, zero };
  __m128i out[4];
  func( out, h );
  return 0;
}
Sign in to post a comment.
Posted by Microsoft on 1/6/2011 at 12:49 PM
Tom,

Thank you for your report. While this problem does occur with VS 2010, we have changes planned for the next major release of VC that will handle your test case correctly. I am going to resolve this as fixed. If you have additional feedback, please feel free to re-activate this report.

Mark Levine
Visual C++
Posted by Microsoft on 1/4/2011 at 10:22 PM
Thanks for your feedback.
We are routing this issue to the appropriate group within the Visual Studio Product Team for triage and resolution. These specialized experts will follow-up with your issue.
Posted by Microsoft on 1/4/2011 at 12:22 PM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)