3

I'm trying to get the HADDPS instruction to work and I can't seem to declare __256 in this code.

#include <xmmintrin.h>
#include <emmintrin.h>
#include <pmmintrin.h>
#include <stdio.h>
#include <stdint.h>
#include <iostream>

__m256 HADDPS(__m256 __X, __m256 __Y)
{
    return _mm256_hadd_ps (__X, __Y);
}
int main()
{
    //horizontal add packed single-------------------------------------------------
    __m256 HADDPSA = _mm_set_ps(4.0f, 3.0f, 2.0f, 1.0f);
    __m256 HADDPSB = _mm_set_ps(4.0f, 3.0f, 2.0f, 1.0f);
    __m256 HADDPSR = HADDPS(HADDPSA, HADDPSB);

    return 0;
}

I'm using g++ with -msse -msse2 -msse3 -msse4.

This is the error.

HADDPS.cpp|8|error: '__m256' does not name a type|
HADDPS.cpp||In function 'int main()':|
HADDPS.cpp|15|error: '__m256' was not declared in this scope|
HADDPS.cpp|15|error: expected ';' before 'HADDPSA'|
HADDPS.cpp|16|error: expected ';' before 'HADDPSB'|
HADDPS.cpp|17|error: expected ';' before 'HADDPSR'|
pandoragami
  • 5,387
  • 15
  • 68
  • 116
  • Does it work if you add `-mavx`? – Brian Cain Jul 07 '13 at 01:00
  • Well its a compiler error so I wouldn't expect `-mavx` to do much anyways, but no I tried to link with that flag and same errors. I guess mentioning `-msse -msse2 -msse3 -msse4` was also pointless. – pandoragami Jul 07 '13 at 01:04
  • No, don't try to link with it, try to compile with it. – Brian Cain Jul 07 '13 at 01:07
  • 1
    @user2555139 `__m256` is an AVX datatype. It doesn't exist unless you enable `-mavx`. – Mysticial Jul 07 '13 at 01:07
  • I added `-mavx` under the "other options" for compiling (codeblocks 10) and same error. @Mysticial are you sure I don't need a header file to? – pandoragami Jul 07 '13 at 01:16
  • 2
    Yes, you need ``. – Mysticial Jul 07 '13 at 01:17
  • Or avxintrin.h. But including intrin.h gives access to all intrinsics I believe, so that may be the most general. After that, you will find you need something like: __m256 HADDPSA = _mm256_set_ps(4.0f, 3.0f, 2.0f, 1.0f, 4.0f, 3.0f, 2.0f, 1.0f); __m256 HADDPSB = _mm256_set_ps(4.0f, 3.0f, 2.0f, 1.0f, 4.0f, 3.0f, 2.0f, 1.0f); –  Jul 07 '13 at 01:21
  • @ScottD I tried what you said and now I'm getting a can full of worms within avxintrin.h mostly `error: cannot convert 'long long int __vector__' to 'double __vector__' for argument '2' to 'double __vector__ __builtin_ia32_maskloadpd(const double __vector__*, double __vector__)'|` on lines 896,902,909,915 and `error: cannot convert 'int __vector__' to 'float __vector__' for argument '2' to 'float __vector__ __builtin_ia32_maskloadps(const float __vector__*, float __vector__)'|` on lines 922,928,935,941? – pandoragami Jul 07 '13 at 02:01
  • @user2555139, I added a complete __m256 example based on your original example. See if it is what you are looking for. –  Jul 07 '13 at 16:18

2 Answers2

2

You have little mess here that starts right from the multiple inclusions that you have.

First your code is not clean C and it's not clean C++ either, it's a mix that can only give you an headache because you are not getting any benefit from this.

In case you really want to code in C++ you should add some extern "C" and remove the C headers involved, if you prefer C I suggest to remove that #include <iostream> and use gcc instead of g++ .

You are also including headers for multiple SSE sets at the same time, refer to this post for a cleaner approach.

In the end this is the source code for a program that tries to mimic the business logic that you are probably looking for

#include <pmmintrin.h>
#include <immintrin.h>

__m128 HADDPS(__m128 __X, __m128 __Y)
{
  return _mm_hadd_ps (__X, __Y);
}

int main()
{
  __m128 HADDPSA = _mm_set_ps(4.0f, 3.0f, 2.0f, 1.0f);
  __m128 HADDPSB = _mm_set_ps(4.0f, 3.0f, 2.0f, 1.0f);
  __m128 HADDPSR = HADDPS(HADDPSA, HADDPSB);

  return 0;
}

you should compile this with

gcc -msse3 main.c
Community
  • 1
  • 1
user2485710
  • 9,451
  • 13
  • 58
  • 102
1

Here is a an example that uses the __m256 data type of the original question. Compiles without error using gcc or g++ 4.8.1, or VS2012.

// gcc compile command line: gcc -mavx sample.c
// g++ compile command line: g++ -mavx sample.c
// VS2012 compile command line: cl sample.c

#include <intrin.h>

__m256 HADDPS(__m256 __X, __m256 __Y)
{
    return _mm256_hadd_ps (__X, __Y);
}
int main()
{
    //horizontal add packed single-------------------------------------------------
    __m256 HADDPSA = _mm256_set_ps(4.0f, 3.0f, 2.0f, 1.0f, 4.0f, 3.0f, 2.0f, 1.0f);
    __m256 HADDPSB = _mm256_set_ps(4.0f, 3.0f, 2.0f, 1.0f, 4.0f, 3.0f, 2.0f, 1.0f);
    __m256 HADDPSR = HADDPS(HADDPSA, HADDPSB);

    return 0;
}
  • Isn't `#include ` a Microsoft thing though? I tried using that header with GCC and its not anywhere to be found. – pandoragami Jul 07 '13 at 16:46
  • @user2555139 you should change the inclusion to `x86intrin.h` or `immintrin.h` but remember that AVX instructions are much less popular than SSE instructions. – user2485710 Jul 07 '13 at 17:39
  • My gcc test was done with Windows + mingw so it is entirely possible gcc for linux doesn't support #include . –  Jul 07 '13 at 18:34
  • Nor does cygwin contain . I use cygwin on windows and those are the headers available to me. – pandoragami Jul 07 '13 at 20:47