There were two mutually incompatible changes reviewed and
merged around the same time for different issues in
convert_mult_to_fma.

the change in r16-7353 keeps result in it's unpromoted form
and deals with it as such but the change in r16-7304 expects
it to be in it's promoted form.

This causes the assert to fail again and the SVE testcase I
added before to fail.

Since the value is now kept in it's unpromoted form, and result
is not used as any LHS side, I've partially reverted the
convert stripping to make use of it.

I also added a RVV testcase this time as well.

Bootstrapped Regtested on aarch64-none-linux-gnu,
arm-none-linux-gnueabihf, x86_64-pc-linux-gnu
-m32, -m64 and no issues.

And tested manually on RVV.

Ok for master?

Thanks,
Tamar

gcc/ChangeLog:

        PR tree-optimization/124038
        * tree-ssa-math-opts.cc (strip_nop_view_converts): Remove.
        (convert_mult_to_fma): Undo stripping.

gcc/testsuite/ChangeLog:

        PR tree-optimization/124038
        * gcc.target/riscv/rvv/pr124038.c: New test.

---
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/pr124038.c 
b/gcc/testsuite/gcc.target/riscv/rvv/pr124038.c
new file mode 100644
index 
0000000000000000000000000000000000000000..0f8075b0fbda59a41fc4638119e3f5f3dfbfffee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/pr124038.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 --param=avoid-fma-max-bits=8 -march=rv64gv 
-fdump-tree-widening_mul" } */
+
+typedef __attribute__((__vector_size__(1))) unsigned char U;
+typedef __attribute__((__vector_size__(1))) signed char V;
+
+U u;
+signed char c;
+
+U
+foo(V v)
+{
+  v *= c;
+  return u + v;
+}
+
+/* { dg-final { scan-tree-dump "FMA" "widening_mul" } } */
diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc
index 
6d69711fffbd5d12f5ef4e216e7db134ba8ee490..bb67dca560b419d2bcbdeb6d3bb626eb1bad73d2
 100644
--- a/gcc/tree-ssa-math-opts.cc
+++ b/gcc/tree-ssa-math-opts.cc
@@ -118,7 +118,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-math-opts.h"
 #include "dbgcnt.h"
 #include "cfghooks.h"
-#include "gimple-match.h"
 
 /* This structure represents one basic block that either computes a
    division, or is a common dominator for basic block that compute a
@@ -3357,26 +3356,6 @@ last_fma_candidate_feeds_initial_phi 
(fma_deferring_state *state,
   return false;
 }
 
-/* If ARG is a convert that only changes the sign then strip the outer
-   conversion away.  It does not strip conversions recursively.  Otherwise
-   return ARG.  */
-
-static tree
-strip_nop_view_converts (tree arg)
-{
-  if (TREE_CODE (arg) != SSA_NAME)
-    return arg;
-
-  gimple *assign = SSA_NAME_DEF_STMT (arg);
-  gimple_match_op res_op;
-  if (gimple_extract_op (assign, &res_op)
-      && (CONVERT_EXPR_CODE_P (res_op.code) || res_op.code == 
VIEW_CONVERT_EXPR)
-      && tree_nop_conversion_p (TREE_TYPE (res_op.ops[0]), TREE_TYPE (arg)))
-    return res_op.ops[0];
-
-  return arg;
-}
-
 /* Combine the multiplication at MUL_STMT with operands MULOP1 and MULOP2
    with uses in additions and subtractions to form fused multiply-add
    operations.  Returns true if successful and MUL_STMT should be removed.
@@ -3642,11 +3621,11 @@ convert_mult_to_fma (gimple *mul_stmt, tree op1, tree 
op2,
            {
              gcc_checking_assert (!state->m_initial_phi);
              gphi *phi;
-             if (strip_nop_view_converts (ops[0]) == result)
+             if (ops[0] == result)
                phi = result_of_phi (ops[1]);
              else
                {
-                 gcc_assert (strip_nop_view_converts (ops[1]) == result);
+                 gcc_assert (ops[1] == result);
                  phi = result_of_phi (ops[0]);
                }
 


-- 
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/pr124038.c b/gcc/testsuite/gcc.target/riscv/rvv/pr124038.c
new file mode 100644
index 0000000000000000000000000000000000000000..0f8075b0fbda59a41fc4638119e3f5f3dfbfffee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/pr124038.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 --param=avoid-fma-max-bits=8 -march=rv64gv -fdump-tree-widening_mul" } */
+
+typedef __attribute__((__vector_size__(1))) unsigned char U;
+typedef __attribute__((__vector_size__(1))) signed char V;
+
+U u;
+signed char c;
+
+U
+foo(V v)
+{
+  v *= c;
+  return u + v;
+}
+
+/* { dg-final { scan-tree-dump "FMA" "widening_mul" } } */
diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc
index 6d69711fffbd5d12f5ef4e216e7db134ba8ee490..bb67dca560b419d2bcbdeb6d3bb626eb1bad73d2 100644
--- a/gcc/tree-ssa-math-opts.cc
+++ b/gcc/tree-ssa-math-opts.cc
@@ -118,7 +118,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-math-opts.h"
 #include "dbgcnt.h"
 #include "cfghooks.h"
-#include "gimple-match.h"
 
 /* This structure represents one basic block that either computes a
    division, or is a common dominator for basic block that compute a
@@ -3357,26 +3356,6 @@ last_fma_candidate_feeds_initial_phi (fma_deferring_state *state,
   return false;
 }
 
-/* If ARG is a convert that only changes the sign then strip the outer
-   conversion away.  It does not strip conversions recursively.  Otherwise
-   return ARG.  */
-
-static tree
-strip_nop_view_converts (tree arg)
-{
-  if (TREE_CODE (arg) != SSA_NAME)
-    return arg;
-
-  gimple *assign = SSA_NAME_DEF_STMT (arg);
-  gimple_match_op res_op;
-  if (gimple_extract_op (assign, &res_op)
-      && (CONVERT_EXPR_CODE_P (res_op.code) || res_op.code == VIEW_CONVERT_EXPR)
-      && tree_nop_conversion_p (TREE_TYPE (res_op.ops[0]), TREE_TYPE (arg)))
-    return res_op.ops[0];
-
-  return arg;
-}
-
 /* Combine the multiplication at MUL_STMT with operands MULOP1 and MULOP2
    with uses in additions and subtractions to form fused multiply-add
    operations.  Returns true if successful and MUL_STMT should be removed.
@@ -3642,11 +3621,11 @@ convert_mult_to_fma (gimple *mul_stmt, tree op1, tree op2,
 	    {
 	      gcc_checking_assert (!state->m_initial_phi);
 	      gphi *phi;
-	      if (strip_nop_view_converts (ops[0]) == result)
+	      if (ops[0] == result)
 		phi = result_of_phi (ops[1]);
 	      else
 		{
-		  gcc_assert (strip_nop_view_converts (ops[1]) == result);
+		  gcc_assert (ops[1] == result);
 		  phi = result_of_phi (ops[0]);
 		}
 

Reply via email to