public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [committed] powerpc: Another umaddditi4 fix [PR108862]
@ 2023-02-20 21:09 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2023-02-20 21:09 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: gcc-patches

Hi!

The following testcase is miscompiled on powerpc64le-linux with
-O2 -mcpu=power9.  The problem is that gen_umaddditi4 is called with
the same TImode register for both op0 and op3, and maddlddi4
overwrites the low half of op0 before the low half of op3 is read,
so when they are the same register it reads the result of maddlddi4.

The following patch fixes that by swapping maddlddi4 and
umadddi4_highpart{,_le} during expansion, as the latter writes into
a temporary pseudo and so can't change anything maddlddi4 depends on.

Bootstrapped/regtested on powerpc64-linux (power7, tested -m32/-m64),
powerpc64le-linux (power8 and another on power9 with
--with-cpu-64=power9 --with-tune-64=power9), preapproved by Segher on IRC,
committed to trunk.

2023-02-20  Jakub Jelinek  <jakub2redhat.com>

	PR target/108862
	* config/rs6000/rs6000.md (umaddditi4): Swap gen_maddlddi4 with
	gen_umadddi4_highpart{,_le}.

	* gcc.dg/pr108862.c: New test.
	* gcc.target/powerpc/pr108862.c: New test.

--- gcc/config/rs6000/rs6000.md.jj	2023-02-15 10:51:12.745802021 +0100
+++ gcc/config/rs6000/rs6000.md	2023-02-20 16:01:02.929027764 +0100
@@ -3249,8 +3249,6 @@
   rtx op3_hi = gen_rtx_SUBREG (DImode, operands[3], BYTES_BIG_ENDIAN ? 0 : 8);
   rtx hi_temp = gen_reg_rtx (DImode);
 
-  emit_insn (gen_maddlddi4 (op0_lo, operands[1], operands[2], op3_lo));
-
   if (BYTES_BIG_ENDIAN)
     emit_insn (gen_umadddi4_highpart (hi_temp, operands[1], operands[2],
 				      op3_lo));
@@ -3258,6 +3256,8 @@
     emit_insn (gen_umadddi4_highpart_le (hi_temp, operands[1], operands[2],
 					 op3_lo));
 
+  emit_insn (gen_maddlddi4 (op0_lo, operands[1], operands[2], op3_lo));
+
   emit_insn (gen_adddi3 (op0_hi, hi_temp, op3_hi));
 
   DONE;
--- gcc/testsuite/gcc.dg/pr108862.c.jj	2023-02-20 15:52:20.570619215 +0100
+++ gcc/testsuite/gcc.dg/pr108862.c	2023-02-20 15:51:52.363029125 +0100
@@ -0,0 +1,27 @@
+/* PR target/108862 */
+/* { dg-do run { target int128 } } */
+/* { dg-options "-O2" } */
+
+unsigned long long a[2] = { 0x04a13945d898c296ULL, 0x0000100000000fffULL };
+unsigned long long b[4] = { 0x04a13945d898c296ULL, 0, 0, 0x0000100000000fffULL };
+
+__attribute__((noipa)) unsigned __int128
+foo (int x, unsigned long long *y, unsigned long long *z)
+{
+  unsigned __int128 w = 0;
+  for (int i = 0; i < x; i++)
+    w += (unsigned __int128)*y++ * (unsigned __int128)*z--;
+  return w;
+}
+
+int
+main ()
+{
+  unsigned __int128 x = foo (1, &a[0], &a[1]);
+  unsigned __int128 y = foo (2, &b[0], &b[3]);
+  if ((unsigned long long) (x >> 64) != 0x0000004a13945dd3ULL
+      || (unsigned long long) x != 0x9b1c8443b3909d6aULL
+      || x != y)
+    __builtin_abort ();
+  return 0;
+}
--- gcc/testsuite/gcc.target/powerpc/pr108862.c.jj	2023-02-20 15:52:51.374171586 +0100
+++ gcc/testsuite/gcc.target/powerpc/pr108862.c	2023-02-20 15:53:04.497980869 +0100
@@ -0,0 +1,6 @@
+/* PR target/108862 */
+/* { dg-do run { target int128 } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
+
+#include "../../gcc.dg/pr108862.c"

	Jakub


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-02-20 21:09 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-20 21:09 [committed] powerpc: Another umaddditi4 fix [PR108862] Jakub Jelinek

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).