diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr123898.c b/gcc/testsuite/gcc.target/aarch64/sve/pr123898.c
new file mode 100644
index 0000000000000000000000000000000000000000..a5741d5058e81b8c34bcfacca5f456bc015308a1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/pr123898.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 --param avoid-fma-max-bits=512 -march=armv9-a -msve-vector-bits=256 -fdump-tree-widening_mul" } */
+
+typedef __attribute__((__vector_size__(32))) char A;
+typedef __attribute__((__vector_size__(32))) signed char D;
+
+A c;
+char x;
+
+void
+foo(D d)
+{
+  d *= x;
+  c += (A)d;
+}
+
+/* { dg-final { scan-tree-dump-times "\.FMA" 1 "widening_mul" } } */
diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc
index b1fa38a832af889972913553d75305a9420b7b53..b8fcb43ae2a1b0e4e11d055eeae6f5d907e6b7e3 100644
--- a/gcc/tree-ssa-math-opts.cc
+++ b/gcc/tree-ssa-math-opts.cc
@@ -3353,6 +3353,28 @@ 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);
+  tree var;
+  if (gimple_assign_cast_p (assign)
+      && (var = gimple_assign_rhs1 (assign))
+      && TREE_CODE (var) != SSA_NAME
+      && (var = TREE_OPERAND (var, 0))
+      && tree_nop_conversion_p (TREE_TYPE (var), TREE_TYPE (arg)))
+    return var;
+
+  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.
@@ -3613,11 +3635,11 @@ convert_mult_to_fma (gimple *mul_stmt, tree op1, tree op2,
 	    {
 	      gcc_checking_assert (!state->m_initial_phi);
 	      gphi *phi;
-	      if (ops[0] == result)
+	      if (strip_nop_view_converts (ops[0]) == result)
 		phi = result_of_phi (ops[1]);
 	      else
 		{
-		  gcc_assert (ops[1] == result);
+		  gcc_assert (strip_nop_view_converts (ops[1]) == result);
 		  phi = result_of_phi (ops[0]);
 		}
 
