re PR middle-end/87138 (wrong code with TI multiplication with -O -march=k8 -fno...
authorJakub Jelinek <jakub@redhat.com>
Fri, 31 Aug 2018 07:49:12 +0000 (09:49 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 31 Aug 2018 07:49:12 +0000 (09:49 +0200)
PR middle-end/87138
* expmed.c (expand_mult_const): Use immed_wide_int_const instead of
gen_int_mode.  Formatting fixes.

* gcc.target/i386/avx512bw-pr87138.c: New test.

From-SVN: r264009

gcc/ChangeLog
gcc/expmed.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/avx512bw-pr87138.c [new file with mode: 0644]

index 363a80f..f1be88b 100644 (file)
@@ -1,3 +1,9 @@
+2018-08-31  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/87138
+       * expmed.c (expand_mult_const): Use immed_wide_int_const instead of
+       gen_int_mode.  Formatting fixes.
+
 2018-08-30  Sandra Loosemore  <sandra@codesourcery.com>
 
        * target.def (custom_function_descriptors): Improve documentation.
index caf29e8..29ce10b 100644 (file)
@@ -3347,19 +3347,21 @@ expand_mult_const (machine_mode mode, rtx op0, HOST_WIDE_INT val,
          /* Write a REG_EQUAL note on the last insn so that we can cse
             multiplication sequences.  Note that if ACCUM is a SUBREG,
             we've set the inner register and must properly indicate that.  */
-          tem = op0, nmode = mode;
-          accum_inner = accum;
-          if (GET_CODE (accum) == SUBREG)
+         tem = op0, nmode = mode;
+         accum_inner = accum;
+         if (GET_CODE (accum) == SUBREG)
            {
              accum_inner = SUBREG_REG (accum);
              nmode = GET_MODE (accum_inner);
              tem = gen_lowpart (nmode, op0);
            }
 
-          insn = get_last_insn ();
-          set_dst_reg_note (insn, REG_EQUAL,
-                           gen_rtx_MULT (nmode, tem,
-                                         gen_int_mode (val_so_far, nmode)),
+         insn = get_last_insn ();
+         wide_int wval_so_far
+           = wi::uhwi (val_so_far,
+                       GET_MODE_PRECISION (as_a <scalar_mode> (nmode)));
+         rtx c = immed_wide_int_const (wval_so_far, nmode);
+         set_dst_reg_note (insn, REG_EQUAL, gen_rtx_MULT (nmode, tem, c),
                            accum_inner);
        }
     }
index c0240a1..ac3722a 100644 (file)
@@ -1,3 +1,8 @@
+2018-08-31  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/87138
+       * gcc.target/i386/avx512bw-pr87138.c: New test.
+
 2018-08-31  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/86328
diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-pr87138.c b/gcc/testsuite/gcc.target/i386/avx512bw-pr87138.c
new file mode 100644 (file)
index 0000000..46cecb9
--- /dev/null
@@ -0,0 +1,29 @@
+/* PR middle-end/87138 */
+/* { dg-do run { target int128 } } */
+/* { dg-options "-O -fno-tree-fre -mavx512bw -mtune=k8" } */
+/* { dg-require-effective-target avx512bw } */
+
+#include "avx512bw-check.h"
+
+typedef int U __attribute__ ((vector_size (64)));
+typedef __int128 V __attribute__ ((vector_size (64)));
+V g, i;
+
+static inline void
+foo (unsigned h, V j, U k, V n)
+{
+  k /= h;
+  __builtin_memmove (&h, &n, 1);
+  n[j[1]] *= 0x7FFFFFFFFFFFFFFF;
+  j[k[5]] = 0;
+  g = n;
+  i = h + j + n;
+}
+
+void
+avx512bw_test ()
+{
+  foo (~0, (V) { }, (U) { 5 }, (V) { 3 });
+  if (g[0] != (__int128) 3 * 0x7FFFFFFFFFFFFFFF)
+    abort ();
+}