2

What is the best way to load from a const pointer using altivec?

According to the documentation (and my results) vec_ld doesn't take a const pointer as an argument: http://www-01.ibm.com/support/knowledgecenter/SS2LWA_12.1.0/com.ibm.xlcpp121.bg.doc/compiler_ref/vec_ld.html

Hence something like this will fail:

void foo(const float* A){
   vector4double a = vec_ld(0,A);
   ...
}

A nasty work-around would be:

void foo(const float* A){
   vector4double a = vec_ld(0,const_cast<float*>A);
   ...
}

Is there a better way to do this? Thank you.

unwind
  • 391,730
  • 64
  • 469
  • 606
user1829358
  • 1,041
  • 2
  • 9
  • 19
  • I've never used AltiVec, but that kind of const-brokenness would send me screaming. :( – unwind Nov 05 '15 at 09:18
  • Also see all of Bill Schmidt's comments at http://gcc.gnu.org/ml/gcc/2015-03/msg00140.html, http://gcc.gnu.org/ml/gcc/2015-03/msg00143.html and http://gcc.gnu.org/ml/gcc/2015-03/msg00147.html. – jww Sep 07 '17 at 05:19

3 Answers3

2

Use const_cast.

It exists exactly for that purpose: handling const-incorrect APIs.

Emil Laine
  • 41,598
  • 9
  • 101
  • 157
1

Function vec_ld loads a 128-bit vector (4 float values) to Altivec register. Loading is performed from 16-byte aligned address. It doesn't work properly if address doesn't have a 16-byte align. In that case you have to use next function:

typedef __vector uint8_t v128_u8;
typedef __vector float v128_f32;

inline v128_f32 Load(const float * p)
{
    v128_u8 lo = vec_ld(0, p);
    v128_u8 hi = vec_ld(A, p);
    return (v128_f32)vec_perm(lo, hi, vec_lvsl(0, p));        
}

or use function vec_vsx_ld if you have Power7 or Power8 CPU.

ErmIg
  • 3,980
  • 1
  • 27
  • 40
  • Thank you, but alignment wasn't the question. I am aware of that and I was only interested in the "const-issue". – user1829358 Nov 05 '15 at 11:31
  • In that case I don't understand your question - function vec_ld can get a parameter const * float. What is the problem? – ErmIg Nov 05 '15 at 11:57
-1

Your const float * means you point to something that is not modifiable, but you still can point to something else.

I don't know about your function vec_ld but I guess as it demands a pointer to a float, the function will change the value pointed.

Then, you have to provide a modifiable value.

I would not use your nasty workaround, because the user calling your method won't expect it's float value to be modified and it will surely because a nasty bug in the future.

If you could change your method foo to foo(float * A) or foo(float & A) it would be a relief.


For more information about const pointer, see : What is the difference between const int*, const int * const, and int const *?

Community
  • 1
  • 1
dkg
  • 1,775
  • 14
  • 34
  • vec_ld should _not_ modifiy A; it is just a load functions. Thus having const there is perfectly valid. I just don't understand why vec_ld is not taking a const pointer. – user1829358 Nov 05 '15 at 08:52
  • Ok, then in that case you have to use your const-cast. Check with the library's support if something can be done. – dkg Nov 05 '15 at 15:04