Bug 80482 - [7/8 Regression] vec_mul produces compilation error if 1 of its parms is const or volatile
Summary: [7/8 Regression] vec_mul produces compilation error if 1 of its parms is cons...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 7.0
: P2 normal
Target Milestone: 7.0
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-04-21 13:59 UTC by seurer
Modified: 2017-04-25 16:50 UTC (History)
4 users (show)

See Also:
Host: powerpc*-*-*
Target: powerpc*-*-*
Build:
Known to work:
Known to fail:
Last reconfirmed: 2017-04-22 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description seurer 2017-04-21 13:59:10 UTC
If one (just one) of its parameters is const, volatile, or const volatile vec_mul produces a compilation error.  This occurs for gcc 7 but not 5 nor 6.

For example:

#include <altivec.h>

void P() {

  const volatile vector float cvva = vec_splats(0.00187682f);
  volatile vector float vva = vec_splats(0.00187682f);
  const vector float cva = vec_splats(0.00187682f);
  vector float va = vec_splats(0.00187682f);
  vector float dx = {1.0f, 2.0f, 3.0f, 4.0f};

  vector float X1m0 = vec_mul(va, va);
  vector float X2m0 = vec_mul(va, dx);
  vector float X3m0 = vec_mul(dx, va);

  vector float X1m1 = vec_mul(cva, cva);
  vector float X2m1 = vec_mul(cva, dx);
  vector float X3m1 = vec_mul(dx, cva);

  vector float Y1m2 = vec_mul(vva, vva);
  vector float Y2m2 = vec_mul(vva, dx);
  vector float Y3m2 = vec_mul(dx, vva);

  vector float X1m3 = vec_mul(cvva, cvva);
  vector float X2m3 = vec_mul(cvva, dx);
  vector float X3m3 = vec_mul(dx, cvva);
}

bii.c:16:3: error: invalid parameter combination for AltiVec intrinsic __builtin_vec_mul
   vector float X2m1 = vec_mul(cva, dx);
   ^~~~~~
bii.c:17:3: error: invalid parameter combination for AltiVec intrinsic __builtin_vec_mul
   vector float X3m1 = vec_mul(dx, cva);
   ^~~~~~
bii.c:20:3: error: invalid parameter combination for AltiVec intrinsic __builtin_vec_mul
   vector float Y2m2 = vec_mul(vva, dx);
   ^~~~~~
bii.c:21:3: error: invalid parameter combination for AltiVec intrinsic __builtin_vec_mul
   vector float Y3m2 = vec_mul(dx, vva);
   ^~~~~~
bii.c:24:3: error: invalid parameter combination for AltiVec intrinsic __builtin_vec_mul
   vector float X2m3 = vec_mul(cvva, dx);
   ^~~~~~
bii.c:25:3: error: invalid parameter combination for AltiVec intrinsic __builtin_vec_mul
   vector float X3m3 = vec_mul(dx, cvva);
   ^~~~~~

I tried a few of the other vec_XYZ built-ins and they do not produce the same error (though I did not test them all).

Note that I am investigating this further.
Comment 1 seurer 2017-04-21 21:21:24 UTC
I see the problem.  The compiler is enforcing "the parameter types must match" too tightly.  It should be checking the unqualified types (sans const/volatile) instead of the types directly.
Comment 2 Jakub Jelinek 2017-04-22 19:55:49 UTC
Started with r237183.
I think best would be just to require that the types are compatible, like below (swapped the TREE_CODE check because it is cheaper).
Or you can compare TYPE_MAIN_VARIANT (arg0_type) with TYPE_MAIN_VARIANT (arg1_type), but that is less robust.

--- gcc/rs6000-c.c.jj	2017-03-29 07:11:23.000000000 +0200
+++ gcc/rs6000-c.c	2017-04-22 21:50:24.614009489 +0200
@@ -5596,10 +5596,10 @@ altivec_resolve_overloaded_builtin (loca
       tree arg1_type = TREE_TYPE (arg1);
 
       /* Both arguments must be vectors and the types must match.  */
-      if (arg0_type != arg1_type)
-	goto bad;
       if (TREE_CODE (arg0_type) != VECTOR_TYPE)
 	goto bad;
+      if (!types_compatible_p (arg0_type, arg1_type))
+	goto bad;
 
       switch (TYPE_MODE (TREE_TYPE (arg0_type)))
 	{
@@ -5610,8 +5610,8 @@ altivec_resolve_overloaded_builtin (loca
 	  case TImode:
 	    {
 	      /* For scalar types just use a multiply expression.  */
-	      return fold_build2_loc (loc, MULT_EXPR, TREE_TYPE (arg0),
-					arg0, arg1);
+	      return fold_build2_loc (loc, MULT_EXPR, TREE_TYPE (arg0), arg0,
+				      fold_convert (TREE_TYPE (arg0), arg1));
 	    }
 	  case SFmode:
 	    {
Comment 3 seurer 2017-04-24 14:00:23 UTC
Yeah, I was going to try something like that.  There are some other places this probably need to be done too.
Comment 4 Jakub Jelinek 2017-04-24 14:04:54 UTC
If you want the fix in 7.1, please post is soon (best later today).
Comment 5 seurer 2017-04-25 15:23:11 UTC
Author: seurer
Date: Tue Apr 25 15:22:40 2017
New Revision: 247250

URL: https://gcc.gnu.org/viewcvs?rev=247250&root=gcc&view=rev
Log:
[PATCH, rs6000] pr80482 Relax vector builtin parameter checks

PR target/80482

This patch changes the parameter testing for powerpc vector builtins to relax
the existing requirement that the parameters be identical to instead that they
be compatible.  This allows for mixing parameters with differing qualified
(const, volatile, etc.) types.

See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80482 for more information.

Bootstrapped and tested on powerpc64le-unknown-linux-gnu and
powerpc64be-unknown-linux-gnu with no regressions.  Is this ok for trunk?

[gcc]

2017-04-25  Bill Seurer  <seurer@linux.vnet.ibm.com>

	PR target/80482
	* config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin): Change
	type checks to test for compatibility instead of equality.

[gcc/testsuite]

2017-04-25  Bill Seurer  <seurer@linux.vnet.ibm.com>

	PR target/80482
	* gcc.target/powerpc/vec-constvolatile.c: New test.

Added:
    trunk/gcc/testsuite/gcc.target/powerpc/vec-constvolatile.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/rs6000/rs6000-c.c
    trunk/gcc/testsuite/ChangeLog
Comment 6 seurer 2017-04-25 16:16:44 UTC
Author: seurer
Date: Tue Apr 25 16:16:13 2017
New Revision: 247256

URL: https://gcc.gnu.org/viewcvs?rev=247256&root=gcc&view=rev
Log:
[PATCH, rs6000] pr80482 Relax vector builtin parameter checks

PR target/80482
Backport from mainline

This patch changes the parameter testing for powerpc vector builtins to relax
the existing requirement that the parameters be identical to instead that they
be compatible.  This allows for mixing parameters with differing qualified
(const, volatile, etc.) types.

See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80482 for more information.

Bootstrapped and tested on powerpc64le-unknown-linux-gnu and
powerpc64be-unknown-linux-gnu with no regressions.  Is this ok for trunk?

[gcc]

2017-04-25  Bill Seurer  <seurer@linux.vnet.ibm.com>

	Backport from mainline
	PR target/80482
	* config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin): Change
	type checks to test for compatibility instead of equality.

[gcc/testsuite]

2017-04-25  Bill Seurer  <seurer@linux.vnet.ibm.com>

	Backport from mainline
	PR target/80482
	* gcc.target/powerpc/vec-constvolatile.c: New test.

Added:
    branches/gcc-7-branch/gcc/testsuite/gcc.target/powerpc/vec-constvolatile.c
Modified:
    branches/gcc-7-branch/gcc/ChangeLog
    branches/gcc-7-branch/gcc/config/rs6000/rs6000-c.c
    branches/gcc-7-branch/gcc/testsuite/ChangeLog
Comment 7 Jakub Jelinek 2017-04-25 16:50:12 UTC
Fixed.