aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr98302.c22
-rw-r--r--gcc/tree-vect-patterns.c13
2 files changed, 33 insertions, 2 deletions
diff --git a/gcc/testsuite/gcc.dg/vect/pr98302.c b/gcc/testsuite/gcc.dg/vect/pr98302.c
new file mode 100644
index 0000000..dec6016
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr98302.c
@@ -0,0 +1,22 @@
+#include "tree-vect.h"
+
+int c = 1705;
+char a;
+long f = 50887638;
+unsigned long long *h(unsigned long long *k, unsigned long long *l) {
+ return *k ? k : l;
+}
+void aa() {}
+int main() {
+ check_vect ();
+
+ long d = f;
+ for (char g = 0; g < (char)c - 10; g += 2) {
+ unsigned long long i = d, j = 4;
+ a = *h(&i, &j) << ((d ? 169392992 : 0) - 169392955LL);
+ }
+ if (a)
+ __builtin_abort();
+
+ return 0;
+}
diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
index ff1358a..081ae80 100644
--- a/gcc/tree-vect-patterns.c
+++ b/gcc/tree-vect-patterns.c
@@ -4961,10 +4961,19 @@ vect_determine_precisions_from_users (stmt_vec_info stmt_info, gassign *stmt)
unsigned int const_shift = TREE_INT_CST_LOW (shift);
if (code == LSHIFT_EXPR)
{
+ /* Avoid creating an undefined shift.
+
+ ??? We could instead use min_output_precision as-is and
+ optimize out-of-range shifts to zero. However, only
+ degenerate testcases shift away all their useful input data,
+ and it isn't natural to drop input operations in the middle
+ of vectorization. This sort of thing should really be
+ handled before vectorization. */
+ operation_precision = MAX (stmt_info->min_output_precision,
+ const_shift + 1);
/* We need CONST_SHIFT fewer bits of the input. */
- operation_precision = stmt_info->min_output_precision;
min_input_precision = (MAX (operation_precision, const_shift)
- - const_shift);
+ - const_shift);
}
else
{