Hi, PR63335 reports that the builtins vec_any_nge, vec_all_nge, vec_any_nle, and vec_all_nle produce incorrect results for vector double. There is some special handling for these intrinsics for the various vector integral types. There is a test that excludes vector float from this handling, but when vector double was added with VSX, the required similar test was apparently not added. This patch fixes that. I've added a test based on the attachment in the bugzilla.
Bootstrapped and tested on powerpc64le-unknown-linux-gnu. Is this ok for trunk? I expect we should backport the fix to 4.8 and 4.9 as well. Thanks, Bill [gcc] 2014-09-24 Bill Schmidt <wschm...@linux.vnet.ibm.com> PR target/63335 * config/rs6000/rs6000-c.c (altivec_build_resolved_builtin): Exclude VSX_BUILTIN_XVCMPGEDP_P from special handling. [gcc/testsuite] 2014-09-24 Bill Schmidt <wschm...@linux.vnet.ibm.com> PR target/63335 * gcc.target/powerpc/pr63335.c: New test. Index: gcc/config/rs6000/rs6000-c.c =================================================================== --- gcc/config/rs6000/rs6000-c.c (revision 215563) +++ gcc/config/rs6000/rs6000-c.c (working copy) @@ -4267,7 +4267,8 @@ altivec_build_resolved_builtin (tree *args, int n, argument) is reversed. Patch the arguments here before building the resolved CALL_EXPR. */ if (desc->code == ALTIVEC_BUILTIN_VEC_VCMPGE_P - && desc->overloaded_code != ALTIVEC_BUILTIN_VCMPGEFP_P) + && desc->overloaded_code != ALTIVEC_BUILTIN_VCMPGEFP_P + && desc->overloaded_code != VSX_BUILTIN_XVCMPGEDP_P) { tree t; t = args[2], args[2] = args[1], args[1] = t; Index: gcc/testsuite/gcc.target/powerpc/pr63335.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/pr63335.c (revision 0) +++ gcc/testsuite/gcc.target/powerpc/pr63335.c (working copy) @@ -0,0 +1,30 @@ +/* { dg-do run { target { powerpc64*-*-* } } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-mvsx" } */ + +#include <altivec.h> + +void abort (void); + +vector double vec = (vector double) {99.0, 99.0}; + +int main() { + + int actual = vec_all_nge(vec, vec); + if ( actual != 0) + abort(); + + actual = vec_all_nle(vec, vec); + if ( actual != 0) + abort(); + + actual = vec_any_nge(vec, vec); + if ( actual != 0) + abort(); + + actual = vec_any_nle(vec, vec); + if ( actual != 0) + abort(); + + return 0; +}