[Debian GNUstep maintainers] Bug#893442: lynkeos.app: FTBFS on ppc64el: AltiVec argument passed to unprototyped function

Frédéric Bonnard frediz at debian.org
Wed Mar 21 18:32:36 UTC 2018


Hi Yavor,
thanks for already digging into this issue.
I'm not an altivec expert but I was interested to look into this and
maybe help.

On Sun, 18 Mar 2018 22:33:16 +0200, Yavor Doganov <yavor at gnu.org> wrote:
> Source: lynkeos.app
> Version: 2.10+dfsg1-2
> Severity: serious
> Tags: patch
> User: debian-powerpc at lists.debian.org
> Usertags: ppc64el
> 
> I would appreciate if someone knowledgeable from -powerpc confirms
> that the attached patch is correct.  The build failure is:
> 
> gcc /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m -c \
>       -MMD -MP -Wdate-time -D_FORTIFY_SOURCE=2 -I. -I.. -I/<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep.. -I/<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources -I/<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../ThreadConnectionSources -I/<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../ThirdPartySources/SMDoubleSlider -DNO_FRAMEWORK_CHECK=1 -DGNUSTEP -DGNUSTEP_BASE_LIBRARY=1 -DGNU_GUI_LIBRARY=1 -DGNU_RUNTIME=1 -DGNUSTEP_BASE_LIBRARY=1 -fno-strict-aliasing -fexceptions -fobjc-exceptions -D_NATIVE_OBJC_EXCEPTIONS -pthread -fPIC -Wall -DGSWARN -DGSDIAGNOSE -Wno-import -g -O2 -g -O2 -fdebug-prefix-map=/<<BUILDDIR>>/lynkeos.app-2.10+dfsg1=. -fstack-protector-strong -Wformat -Werror=format-security -fgnu-runtime -Wno-unknown-pragmas -Wno-cpp -fconstant-string-class=NSConstantString -I. -I/usr/local/include/GNUstep -I/usr/include/GNUstep \
>        -o obj/Lynkeos.obj/MyDeconvolution.m.o
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m: In function 'vector_Process_One_line':
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:72:44: warning: excess elements in vector initializer
>                                             0x04050607, 0x04050607 };
>                                             ^~~~~~~~~~
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:72:44: note: (near initialization for 'Vperma')
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:72:56: warning: excess elements in vector initializer
>                                             0x04050607, 0x04050607 };
>                                                         ^~~~~~~~~~
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:72:56: note: (near initialization for 'Vperma')
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:74:44: warning: excess elements in vector initializer
>                                             0x0C0D0E0F, 0x0C0D0E0F };
>                                             ^~~~~~~~~~
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:74:44: note: (near initialization for 'Vpermb')
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:74:56: warning: excess elements in vector initializer
>                                             0x0C0D0E0F, 0x0C0D0E0F };
>                                                         ^~~~~~~~~~
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:74:56: note: (near initialization for 'Vpermb')
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:88:13: warning: implicit declaration of function 'vec_madd' [-Wimplicit-function-declaration]
>        Vdx = vec_madd( vec_ld(0,expXptr), Vdy, Vzero );
>              ^~~~~~~~
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:88:23: warning: implicit declaration of function 'vec_ld'; did you mean 'vector'? [-Wimplicit-function-declaration]
>        Vdx = vec_madd( vec_ld(0,expXptr), Vdy, Vzero );
>                        ^~~~~~
>                        vector
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:88:7: error: AltiVec argument passed to unprototyped function
>        Vdx = vec_madd( vec_ld(0,expXptr), Vdy, Vzero );
>        ^~~
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:89:41: warning: implicit declaration of function 'vec_cmplt' [-Wimplicit-function-declaration]
>        const __vector __bool int Vmask = vec_cmplt(Vdx,Vthr);
>                                          ^~~~~~~~~
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:89:7: error: AltiVec argument passed to unprototyped function
>        const __vector __bool int Vmask = vec_cmplt(Vdx,Vthr);
>        ^~~~~
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:90:27: warning: implicit declaration of function 'vec_and'; did you mean 'vscanf'? [-Wimplicit-function-declaration]
>        __vector REAL Vge = vec_and(Vdx,Vmask);
>                            ^~~~~~~
>                            vscanf
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:90:7: error: AltiVec argument passed to unprototyped function
>        __vector REAL Vge = vec_and(Vdx,Vmask);
>        ^~~~~~~~
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:91:27: warning: implicit declaration of function 'vec_andc'; did you mean 'vscanf'? [-Wimplicit-function-declaration]
>        __vector REAL Vlt = vec_andc(Vthr,Vmask);
>                            ^~~~~~~~
>                            vscanf
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:91:7: error: AltiVec argument passed to unprototyped function
>        __vector REAL Vlt = vec_andc(Vthr,Vmask);
>        ^~~~~~~~
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:92:13: warning: implicit declaration of function 'vec_or'; did you mean 'vector'? [-Wimplicit-function-declaration]
>        Vdx = vec_or(Vge,Vlt);
>              ^~~~~~
>              vector
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:92:7: error: AltiVec argument passed to unprototyped function
>        Vdx = vec_or(Vge,Vlt);
>        ^~~
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:93:13: warning: implicit declaration of function 'vec_perm'; did you mean 'vector'? [-Wimplicit-function-declaration]
>        Vda = vec_perm(Vdx,Vzero,Vperma);
>              ^~~~~~~~
>              vector
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:93:7: error: AltiVec argument passed to unprototyped function
>        Vda = vec_perm(Vdx,Vzero,Vperma);
>        ^~~
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:98:10: error: AltiVec argument passed to unprototyped function
>           Vdb = vec_perm(Vdx,Vzero,Vpermb);
>           ^~~
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:101:34: error: incompatible types when initializing type '__vector float {aka __vector(4) float}' using type 'int'
>              __vector REAL Vbuf = vec_ld(c,(REAL*)linePtr);
>                                   ^~~~~~
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:102:13: error: AltiVec argument passed to unprototyped function
>              Vbuf = vec_madd( Vbuf, Vda, Vzero);
>              ^~~~
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:103:13: warning: implicit declaration of function 'vec_st'; did you mean 'qecvt'? [-Wimplicit-function-declaration]
>              vec_st( Vbuf,c, (REAL*)linePtr );
>              ^~~~~~
>              qecvt
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:103:13: error: AltiVec argument passed to unprototyped function
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:104:18: error: incompatible types when assigning to type '__vector float {aka __vector(4) float}' from type 'int'
>              Vbuf = vec_ld(c+2*sizeof(COMPLEX),(REAL*)linePtr);
>                   ^
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:105:13: error: AltiVec argument passed to unprototyped function
>              Vbuf = vec_madd( Vbuf, Vdb, Vzero);
>              ^~~~
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:106:13: error: AltiVec argument passed to unprototyped function
>              vec_st( Vbuf,c+2*sizeof(COMPLEX), (REAL*)linePtr );
>              ^~~~~~
> /<<BUILDDIR>>/lynkeos.app-2.10+dfsg1/GNUstep/../Sources/MyDeconvolution.m:112:13: error: AltiVec argument passed to unprototyped function
>              vec_st( vec_madd( vec_ld(c,(REAL*)linePtr), Vda, Vzero),
>              ^~~~~~
> 
> Link to the build log:
> https://buildd.debian.org/status/fetch.php?pkg=lynkeos.app&arch=ppc64el&ver=2.10%2Bdfsg1-2&stamp=1521251706&raw=0
> 
> Quick link to the source code:
> https://sources.debian.org/src/lynkeos.app/2.10+dfsg1-2/Sources/MyDeconvolution.m/#L68
> 
> Most of these warnings/errors should be fixed by including
> <altivec.h>.  However, I think there are at least two other issues.
> 
> According to the OpenPOWER 64-Bit ELF V2 ABI Specification, vector
> unsigned long is a vector of 2 unsigned doublewords so the
> Vperma/Vpermb initializers seem incorrect; the compiler rightfully
> complains.
> 
> According to the GCC manual, the third argument of vec_perm is always a
> vector unsigned char, so Vperma/Vpermb must be converted to that type.

Right.
From what I understood, the 3rd argument corresponds to the list of byte
indexes to fetch from the first 2 128b arguments(Vector Registers), i.e.
indexes of 2x 16 bytes. So those should go from 00 to 1F.
When I compile :
__vector unsigned char Va = vec_pack(vec_pack(vec_ctu(Vperma, 0), vec_splat_u32(0)), vec_splat_u16(0));
__vector unsigned char Vb = vec_pack(vec_pack(vec_ctu(Vpermb, 0), vec_splat_u32(0)), vec_splat_u16(0));

and print those, I have : 
Va :  3  3  8  8 0 0 0 0 0 0 0 0 0 0 0 0
Vb : 10 10 10 10 0 0 0 0 0 0 0 0 0 0 0 0

On the other side, reading the code, it works on vectors of 4 floats.
That is for example :

Vdx :    float1        float2        float3        float4
      00 01 02 03   04 05 06 07   08 09 0A 0B   0C 0D 0E 0F

Vzero :  float5        float6        float7        float8
      10 11 12 13   14 15 16 17   18 19 1A 1B   1C 1D 1E 1F

and I don't get what could represent Vda = vec_perm(Vdx,Vzero,Va)
with his first float being bytes 03 03 08 08 (from float1 and float3)
and the 3others being 00 00 00 00 (from float1)

Initial content of Vperma, Vpermb is : 
static const __vector u_long Vperma = { 0x00010203, 0x00010203, 0x04050607, 0x04050607 };
static const __vector u_long Vpermb = { 0x08090A0B, 0x08090A0B, 0x0C0D0E0F, 0x0C0D0E0F };

and it looks to me as they store indexes that would make sense for
vec_perm to give some meaningful floats.
In vec_perm(Vdx,Vzero,Vperma)
Vperma would get [ float1 float1 float2 float2 ] and
Vpermb would get [ float3 float3 float4 float4 ]

So with this :
vector unsigned char Va = { 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7 };
vector unsigned char Vb = { 8, 9, 10, 11, 8, 9, 10, 11, 12, 13, 14, 15, 12, 13, 14, 15};
we get the following indexes :
Va : 0 1 2 3 0 1 2 3 4 5 6 7 4 5 6 7
Vb : 8 9 a b 8 9 a b c d e f c d e f

which extracts good looking floats.

So I would tend to keep :
static const __vector unsigned char Vperma = { 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7 };
static const __vector unsigned char Vpermb = { 8, 9, 10, 11, 8, 9, 10, 11, 12, 13, 14, 15, 12, 13, 14, 15};

I also extracted part of the computation code to test the computation
done with some random floats and check if the results make some sense which
seems to be the case (in terms of addition, multiplication, load/store).
I also did this on powerpc, ppc64 and ppc64el to see if I had some
endianness issue, but I got the same results on the 3 archs.

The best would be to test all this in real by running lynkeos.app's
deconvulation, or at least compile part of the original code on Mac OS X and check
if the indexes used here gives the same results compared to the original
ones.

F.


> --- lynkeos.app.orig/Sources/MyDeconvolution.m
> +++ lynkeos.app/Sources/MyDeconvolution.m
> @@ -20,6 +20,9 @@
>  // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
>  //
>  #include <objc/runtime.h>
> +#ifdef __ALTIVEC__
> +#include <altivec.h>
> +#endif
> 
>  #include "MyGeneralPrefs.h"
>  #include "LynkeosFourierBuffer.h"
> @@ -68,10 +71,16 @@
>  #ifdef __ALTIVEC__
>     // Altivec code
>     static const __vector REAL Vzero = { -0.0, -0.0, -0.0, -0.0 };
> -   static const __vector u_long Vperma = { 0x00010203, 0x00010203,
> -                                           0x04050607, 0x04050607 };
> -   static const __vector u_long Vpermb = { 0x08090A0B, 0x08090A0B,
> -                                           0x0C0D0E0F, 0x0C0D0E0F };
> +   static const __vector REAL Vperma = { (float)0x00010203, (float)0x00010203,
> +                                         (float)0x04050607, (float)0x04050607 };
> +   static const __vector REAL Vpermb = { (float)0x08090A0B, (float)0x08090A0B,
> +                                         (float)0x0C0D0E0F, (float)0x0C0D0E0F };
> +   __vector unsigned char Va = vec_pack(vec_pack(vec_ctu(Vperma, 0),
> +                                                 vec_splat_u32(0)),
> +                                        vec_splat_u16(0));
> +   __vector unsigned char Vb = vec_pack(vec_pack(vec_ctu(Vpermb, 0),
> +                                                 vec_splat_u32(0)),
> +                                        vec_splat_u16(0));
>     const u_long byteLineWidth = spectrum->_halfw*sizeof(COMPLEX);
>     const u_long bytePlaneSize = spectrum->_h*spectrum->_padw*sizeof(REAL); // padw is for REALs
>     COMPLEX * const linePtr = &colorComplexValue(spectrum,0,y,0);
> @@ -90,12 +99,12 @@
>        __vector REAL Vge = vec_and(Vdx,Vmask);
>        __vector REAL Vlt = vec_andc(Vthr,Vmask);
>        Vdx = vec_or(Vge,Vlt);
> -      Vda = vec_perm(Vdx,Vzero,Vperma);
> +      Vda = vec_perm(Vdx,Vzero,Va);
> 
>        // Apply it on each plane
>        if ( x < byteLineWidth-2*sizeof(COMPLEX) )
>        {
> -         Vdb = vec_perm(Vdx,Vzero,Vpermb);
> +         Vdb = vec_perm(Vdx,Vzero,Vb);
>           for( c = x; c < x+nPlanes*bytePlaneSize; c += bytePlaneSize )
>           {
>              __vector REAL Vbuf = vec_ld(c,(REAL*)linePtr);
> --- lynkeos.app.orig/Sources/MyUnsharpMask.m
> +++ lynkeos.app/Sources/MyUnsharpMask.m
> @@ -20,6 +20,9 @@
>  // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
>  //
>  #include <objc/runtime.h>
> +#ifdef __ALTIVEC__
> +#include <altivec.h>
> +#endif
> 
>  #include "MyGeneralPrefs.h"
>  #include "LynkeosFourierBuffer.h"
-------------- next part --------------
--- a/Sources/MyDeconvolution.m
+++ b/Sources/MyDeconvolution.m
@@ -20,6 +20,9 @@
 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 //
 #include <objc/runtime.h>
+#ifdef __ALTIVEC__
+#include <altivec.h>
+#endif
 
 #include "MyGeneralPrefs.h"
 #include "LynkeosFourierBuffer.h"
@@ -68,10 +71,8 @@
 #ifdef __ALTIVEC__
    // Altivec code
    static const __vector REAL Vzero = { -0.0, -0.0, -0.0, -0.0 };
-   static const __vector u_long Vperma = { 0x00010203, 0x00010203,
-                                           0x04050607, 0x04050607 };
-   static const __vector u_long Vpermb = { 0x08090A0B, 0x08090A0B,
-                                           0x0C0D0E0F, 0x0C0D0E0F };
+   static const __vector unsigned char Vperma = { 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7 };
+   static const __vector unsigned char Vpermb = { 8, 9, 10, 11, 8, 9, 10, 11, 12, 13, 14, 15, 12, 13, 14, 15};
    const u_long byteLineWidth = spectrum->_halfw*sizeof(COMPLEX);
    const u_long bytePlaneSize = spectrum->_h*spectrum->_padw*sizeof(REAL); // padw is for REALs
    COMPLEX * const linePtr = &colorComplexValue(spectrum,0,y,0);
--- a/Sources/MyUnsharpMask.m
+++ b/Sources/MyUnsharpMask.m
@@ -20,6 +20,9 @@
 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 //
 #include <objc/runtime.h>
+#ifdef __ALTIVEC__
+#include <altivec.h>
+#endif
 
 #include "MyGeneralPrefs.h"
 #include "LynkeosFourierBuffer.h"
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.alioth.debian.org/pipermail/pkg-gnustep-maintainers/attachments/20180321/f5ea687a/attachment-0003.sig>


More information about the pkg-GNUstep-maintainers mailing list