--- /dev/null
+// { dg-do compile }
+// { dg-require-effective-target vect_int }
+// { dg-additional-options "-std=gnu++20" }
+
+#include <algorithm>
+#include <array>
+#include <ranges>
+
+std::array<int, 16> foo(std::array<int, 16> u, std::array<int, 16> const &v)
+{
+ std::ranges::transform(u, v, u.begin(), std::plus<int>());
+ return u;
+}
+
+// { dg-final { scan-tree-dump "optimized: loop vectorized" "vect" } }
+// { dg-final { scan-tree-dump-not "Loop being analyzed as uncounted" "vect" } }
#include "attribs.h"
#include "asan.h"
#include "bitmap.h"
+#include "cfgloop.h"
#ifndef LOGICAL_OP_NON_SHORT_CIRCUIT
#define LOGICAL_OP_NON_SHORT_CIRCUIT \
if (!outer_cond)
return false;
+ /* niter analysis does not cope with boolean typed loop exit conditions.
+ Avoid turning an analyzable exit into an unanalyzable one. */
+ if (inner_cond_bb->loop_father == outer_cond_bb->loop_father
+ && loop_exits_from_bb_p (inner_cond_bb->loop_father, inner_cond_bb)
+ && loop_exits_from_bb_p (outer_cond_bb->loop_father, outer_cond_bb))
+ {
+ tree outer_type = TREE_TYPE (gimple_cond_lhs (outer_cond));
+ tree inner_type = TREE_TYPE (gimple_cond_lhs (inner_cond));
+ if (TREE_CODE (outer_type) == INTEGER_TYPE
+ || POINTER_TYPE_P (outer_type)
+ || TREE_CODE (inner_type) == INTEGER_TYPE
+ || POINTER_TYPE_P (inner_type))
+ return false;
+ }
+
/* See if we test a single bit of the same name in both tests. In
that case remove the outer test, merging both else edges,
and change the inner one to test for