aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/match.pd8
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr96930.C10
2 files changed, 16 insertions, 2 deletions
diff --git a/gcc/match.pd b/gcc/match.pd
index 56fb583..c286a54 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -321,7 +321,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(unsigned long long) (1 << 31) is -2147483648ULL, not 2147483648ULL,
so it is valid only if A >> 31 is zero. */
(simplify
- (trunc_div @0 (convert? (lshift integer_onep@1 @2)))
+ (trunc_div (convert?@0 @3) (convert2? (lshift integer_onep@1 @2)))
(if ((TYPE_UNSIGNED (type) || tree_expr_nonnegative_p (@0))
&& (!VECTOR_TYPE_P (type)
|| target_supports_op_p (type, RSHIFT_EXPR, optab_vector)
@@ -336,7 +336,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
& wi::mask (element_precision (TREE_TYPE (@1)) - 1,
true,
element_precision (type))) == 0)))))
- (rshift @0 @2)))
+ (if (!VECTOR_TYPE_P (type)
+ && useless_type_conversion_p (TREE_TYPE (@3), TREE_TYPE (@1))
+ && element_precision (TREE_TYPE (@3)) < element_precision (type))
+ (convert (rshift @3 @2))
+ (rshift @0 @2))))
/* Preserve explicit divisions by 0: the C++ front-end wants to detect
undefined behavior in constexpr evaluation, and assuming that the division
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr96930.C b/gcc/testsuite/g++.dg/tree-ssa/pr96930.C
new file mode 100644
index 0000000..3d4d098
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr96930.C
@@ -0,0 +1,10 @@
+// PR tree-optimization/96930
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-optimized" }
+// { dg-final { scan-tree-dump " = a_\[0-9]\\\(D\\\) >> b_\[0-9]\\\(D\\\);" "optimized" } }
+
+unsigned
+foo (unsigned a, unsigned b)
+{
+ return a / (unsigned long long) (1U << b);
+}