public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH, rs6000] Fix addg6s builtin with long long parameters. (PR100693)
@ 2022-10-06 21:29 will schmidt
  2022-10-07 20:00 ` Segher Boessenkool
  0 siblings, 1 reply; 2+ messages in thread
From: will schmidt @ 2022-10-06 21:29 UTC (permalink / raw)
  To: 'GCC Patches'; +Cc: Segher Boessenkool, Kewen.Lin, David Edelsohn

[PATCH, rs6000] Fix addg6s builtin with long long parameters. (PR100693)

Hi,
  As reported in PR 100693, attempts to use __builtin_addg6s
with long long arguments result in truncated results.

Since the int and long long types can be coerced into each other,
(documented further near the rs6000-c.cc change), this is handled
by adding a builtin overload (ADDG6S_OV), and the addition of some
special handling in altivec_resolve_overloaded_builtin() to map
the calls to addg6s_32 or addg6s_64; similar to how the SCAL_CMPB
builtins are currently handled.

This has sniff-tested cleanly.

I'm seeing a regression failure show up in
testsuite/g++.dg/modules/adl-3*.c; which seems entirely unrelated
to the content in this change.  I'm poking at that a bit more to
see if I can tell the what/why for that.

OK for trunk?

Thanks,
-Will

gcc/
	PR target/100693

	* config/rs6000/rs6000-builtins.def ([POWER7]): Replace bif-name
	__builtin_addg6s with bif-name __builtin_addg6s_32.
	([POWER7-64]): New bif-name __builtin_addg6s_64.
	* config/rs6000/rs6000-c.cc (altivec_resolve_overloaded_builtin):
	Add handler mapping RS6000_OVLD_ADDG6S_OV to RS6000_BIF_ADDG6S
	and RS6000_BIF_ADDG6S_32.
	* config/rs6000/rs6000-overload.def (ADDG6S_OV): Add overloaded
	entry __builtin_addg6s mapped to ADDG6S_32 and ADDG6S.
	* config/rs6000/rs6000.md ("addg6s", UNSPEC_ADDG6S): Replace with
	("addg6s<mode>3") and rework.
	* doc/extend.texi (__builtin_addg6s): Add documentation for
	__builtin_addg6s with unsigned long long parameters.

gcc/testsuite/
	* testsuite/gcc.target/powerpc/pr100693-compile.c: New.
	* testsuite/gcc.target/powerpc/pr100693-run.c: New.

diff --git a/gcc/config/rs6000/rs6000-builtins.def b/gcc/config/rs6000/rs6000-builtins.def
index f76f54793d73..11050e4c26d5 100644
--- a/gcc/config/rs6000/rs6000-builtins.def
+++ b/gcc/config/rs6000/rs6000-builtins.def
@@ -2010,12 +2010,13 @@
     XXSPLTD_V2DI vsx_xxspltd_v2di {}
 
 
 ; Power7 builtins (ISA 2.06).
 [power7]
-  const unsigned int __builtin_addg6s (unsigned int, unsigned int);
-    ADDG6S addg6s {}
+
+  const unsigned int __builtin_addg6s_32 (unsigned int, unsigned int);
+    ADDG6S_32 addg6ssi3 {}
 
   const signed long __builtin_bpermd (signed long, signed long);
     BPERMD bpermd_di {32bit}
 
   const unsigned int __builtin_cbcdtd (unsigned int);
@@ -2041,10 +2042,14 @@
     UNPACK_V1TI unpackv1ti {}
 
 
 ; Power7 builtins requiring 64-bit GPRs (even with 32-bit addressing).
 [power7-64]
+
+  const unsigned long __builtin_addg6s_64 (unsigned long, unsigned long);
+    ADDG6S addg6sdi3 {no32bit}
+
   const signed long long __builtin_divde (signed long long, signed long long);
     DIVDE dive_di {}
 
   const unsigned long long __builtin_divdeu (unsigned long long, \
                                              unsigned long long);
diff --git a/gcc/config/rs6000/rs6000-c.cc b/gcc/config/rs6000/rs6000-c.cc
index 566094626293..28e8b6761ce5 100644
--- a/gcc/config/rs6000/rs6000-c.cc
+++ b/gcc/config/rs6000/rs6000-c.cc
@@ -1919,10 +1919,35 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
 				   instance_code, fcode, types, args);
 	if (call != error_mark_node)
 	  return call;
 	break;
       }
+      /* We need to special case __builtin_addg6s because the overloaded
+	 forms of this function take (unsigned int, unsigned int) or
+	 (unsigned long long, unsigned long long).  Since C conventions
+	 allow the respective argument types to be implicitly coerced into
+	 each other, the default handling does not provide adequate
+	 discrimination between the desired forms of the function.  */
+    case RS6000_OVLD_ADDG6S_OV:
+      {
+	machine_mode arg1_mode = TYPE_MODE (types[0]);
+	machine_mode arg2_mode = TYPE_MODE (types[1]);
+
+	/* If any supplied arguments are wider than 32 bits, resolve to
+	   64-bit variant of built-in function.  */
+	if (GET_MODE_PRECISION (arg1_mode) > 32
+	    || GET_MODE_PRECISION (arg2_mode) > 32)
+	  instance_code = RS6000_BIF_ADDG6S;
+	else
+	  instance_code = RS6000_BIF_ADDG6S_32;
+
+	tree call = find_instance (&unsupported_builtin, &instance,
+				   instance_code, fcode, types, args);
+	if (call != error_mark_node)
+	  return call;
+	break;
+      }
     case RS6000_OVLD_VEC_VSIE:
       {
 	machine_mode arg1_mode = TYPE_MODE (types[0]);
 
 	/* If supplied first argument is wider than 64 bits, resolve to
diff --git a/gcc/config/rs6000/rs6000-overload.def b/gcc/config/rs6000/rs6000-overload.def
index 44e2945aaa0e..41b74c0c1500 100644
--- a/gcc/config/rs6000/rs6000-overload.def
+++ b/gcc/config/rs6000/rs6000-overload.def
@@ -193,10 +193,16 @@
   unsigned int __builtin_cmpb (unsigned int, unsigned int);
     CMPB_32
   unsigned long long __builtin_cmpb (unsigned long long, unsigned long long);
     CMPB
 
+[ADDG6S_OV, SKIP, __builtin_addg6s]
+  unsigned int __builtin_addg6s (unsigned int, unsigned int);
+    ADDG6S_32
+  unsigned long long __builtin_addg6s (unsigned long long, unsigned long long);
+    ADDG6S
+
 [VEC_ABS, vec_abs, __builtin_vec_abs]
   vsc __builtin_vec_abs (vsc);
     ABS_V16QI
   vss __builtin_vec_abs (vss);
     ABS_V8HI
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index ad5a4cf2ef83..b172ffd097ab 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -14534,14 +14534,14 @@ (define_peephole2
   operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
 })
    
 \f
 ;; Miscellaneous ISA 2.06 (power7) instructions
-(define_insn "addg6s"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-	(unspec:SI [(match_operand:SI 1 "register_operand" "r")
-		    (match_operand:SI 2 "register_operand" "r")]
+(define_insn "addg6s<mode>3"
+  [(set (match_operand:GPR 0 "register_operand" "=r")
+	(unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
+		    (match_operand:GPR 2 "register_operand" "r")]
 		   UNSPEC_ADDG6S))]
   "TARGET_POPCNTD"
   "addg6s %0,%1,%2"
   [(set_attr "type" "integer")])
 
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index a5afb467d235..d393062e790f 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -18139,10 +18139,11 @@ addition to the @option{-maltivec}, @option{-mpopcntd}, and
 @option{-mvsx} options.
 
 The following basic built-in functions require @option{-mpopcntd}:
 @smallexample
 unsigned int __builtin_addg6s (unsigned int, unsigned int);
+unsigned long long __builtin_addg6s (unsigned long long, unsigned long long);
 long long __builtin_bpermd (long long, long long);
 unsigned int __builtin_cbcdtd (unsigned int);
 unsigned int __builtin_cdtbcd (unsigned int);
 long long __builtin_divde (long long, long long);
 unsigned long long __builtin_divdeu (unsigned long long, unsigned long long);
diff --git a/gcc/testsuite/gcc.target/powerpc/pr100693-compile.c b/gcc/testsuite/gcc.target/powerpc/pr100693-compile.c
new file mode 100644
index 000000000000..113936a3d9f8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr100693-compile.c
@@ -0,0 +1,30 @@
+/* { dg-do compile { target { powerpc*-*-linux* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-mdejagnu-cpu=power7 -O3" } */
+/* { dg-final { scan-assembler-times {\maddg6s\M} 4 } } */
+/* { dg-final { scan-assembler-not    "bl __builtin" } } */
+
+/* Test case for the addg6s builtin, exercising both
+   unsigned int and unsigned long long arguments. */
+
+unsigned long long test2_ull (unsigned long long a, unsigned long long b)
+{
+    return __builtin_addg6s (a, b);
+}
+
+unsigned int test1_ui (unsigned int a, unsigned int b)
+{
+    return __builtin_addg6s (a, b);
+}
+
+unsigned int test3_ui (unsigned int *a, unsigned int *b)
+{
+	return __builtin_addg6s(*a, *b);
+}
+
+unsigned long long test4_ull (unsigned long long *a, unsigned long long *b)
+{
+	return __builtin_addg6s(*a, *b);
+}
+
diff --git a/gcc/testsuite/gcc.target/powerpc/pr100693-run.c b/gcc/testsuite/gcc.target/powerpc/pr100693-run.c
new file mode 100644
index 000000000000..3694010b10ae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr100693-run.c
@@ -0,0 +1,78 @@
+/* { dg-do run { target { powerpc*-*-linux* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-mdejagnu-cpu=power7 -O3" } */
+
+/* Test case for the addg6s builtin, exercising both
+   unsigned int and unsigned long long arguments.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+unsigned int test_addg6s_int (unsigned int a, unsigned int b)
+{
+    return __builtin_addg6s (a, b);
+}
+
+unsigned long long test_addg6s_longlong (unsigned long long a, unsigned long long b)
+{
+    return __builtin_addg6s (a, b);
+}
+
+/* Table of expected values.  */
+
+unsigned int exp_i[] = {
+0x66666660,
+0x66666606,
+0x66666066,
+0x66660666,
+0x66606666,
+0x66066666,
+0x60666666,
+0x06666666,
+0x77777777
+};
+
+unsigned long long exp_ll[] = {
+0x6666666666666660,
+0x6666666666666606,
+0x6666666666666066,
+0x6666666666660666,
+0x6666666666606666,
+0x6666666666066666,
+0x6666666660666666,
+0x6666666606666666,
+0x6666666066666666,
+0x6666660666666666,
+0x6666606666666666,
+0x6666066666666666,
+0x6660666666666666, 
+0x6606666666666666, 
+0x6066666666666666, 
+0x0666666666666666, 
+0x7777777777777777
+};
+
+int main() {
+	unsigned int intresult;
+	unsigned long long longresult;
+	int idx;
+	int fail=0;
+
+	for (idx=0; idx<8; idx++) {
+	   intresult = test_addg6s_int (0x01<<4*idx, 0x0f<<4*idx);
+	   if (exp_i[idx] != intresult)
+	      printf("index:%2d Got:%8x Expected:%8x %d\n",
+			idx, intresult, exp_i[idx], ++fail);
+	}
+
+	for (idx=0; idx<16; idx++) {
+	   longresult = test_addg6s_longlong (0x01ULL<<4*idx, 0x0fULL<<4*idx);
+	   if (exp_ll[idx] != longresult)
+	      printf("index:%2d Got:%16llx Expected:%16llx %d\n",
+			idx, longresult, exp_ll[idx], ++fail);
+	}
+	if (fail)
+		abort();
+}
+


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-10-07 20:01 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-06 21:29 [PATCH, rs6000] Fix addg6s builtin with long long parameters. (PR100693) will schmidt
2022-10-07 20:00 ` Segher Boessenkool

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).