--- /dev/null
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+/* { dg-options "-O2 -msve-vector-bits=256 -march=armv8.2-a+sve -fdump-tree-optimized" { target aarch64*-*-* } } */
+
+unsigned int
+f1 (unsigned int a, unsigned int b, unsigned int c) {
+ unsigned int d = a * b;
+ return d + ((c + d) >> 1);
+}
+
+unsigned int
+g1 (unsigned int a, unsigned int b, unsigned int c) {
+ return a * b + c;
+}
+
+__Uint32x4_t
+f2 (__Uint32x4_t a, __Uint32x4_t b, __Uint32x4_t c) {
+ __Uint32x4_t d = a * b;
+ return d + ((c + d) >> 1);
+}
+
+__Uint32x4_t
+g2 (__Uint32x4_t a, __Uint32x4_t b, __Uint32x4_t c) {
+ return a * b + c;
+}
+
+typedef unsigned int vec __attribute__((vector_size(32))); vec
+f3 (vec a, vec b, vec c)
+{
+ vec d = a * b;
+ return d + ((c + d) >> 1);
+}
+
+vec
+g3 (vec a, vec b, vec c)
+{
+ return a * b + c;
+}
+
+/* { dg-final { scan-tree-dump-times {\.FMA } 1 "optimized" { target aarch64*-*-* } } } */
param_avoid_fma_max_bits));
bool defer = check_defer;
bool seen_negate_p = false;
+
+ /* There is no numerical difference between fused and unfused integer FMAs,
+ and the assumption below that FMA is as cheap as addition is unlikely
+ to be true, especially if the multiplication occurs multiple times on
+ the same chain. E.g., for something like:
+
+ (((a * b) + c) >> 1) + (a * b)
+
+ we do not want to duplicate the a * b into two additions, not least
+ because the result is not a natural FMA chain. */
+ if (ANY_INTEGRAL_TYPE_P (type)
+ && !has_single_use (mul_result))
+ return false;
+
/* Make sure that the multiplication statement becomes dead after
the transformation, thus that all uses are transformed to FMAs.
This means we assume that an FMA operation has the same cost