aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/range-op.cc4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr107541.c16
2 files changed, 19 insertions, 1 deletions
diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 5e94c3d..2b5db0c 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -1953,7 +1953,9 @@ operator_div::fold_range (irange &r, tree type,
return true;
tree t;
- if (rh.singleton_p (&t))
+ if (code == TRUNC_DIV_EXPR
+ && rh.singleton_p (&t)
+ && !wi::neg_p (lh.lower_bound ()))
{
wide_int wi = wi::to_wide (t);
int shift = wi::exact_log2 (wi);
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr107541.c b/gcc/testsuite/gcc.dg/tree-ssa/pr107541.c
new file mode 100644
index 0000000..4751421
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr107541.c
@@ -0,0 +1,16 @@
+// { dg-do run }
+// { dg-options "-O1" }
+
+unsigned char a = 1;
+char b, e;
+long c;
+short d;
+int main() {
+ a = ~(1 && a);
+ c = ~((~a / 8 | -2) & 11007578330939886389LLU);
+ e = -c;
+ d = ~c / e;
+ if (d < 2000)
+ __builtin_abort();
+ return 0;
+}