Call infer_non_null() directly when checking for non-null.
authorAndrew MacLeod <amacleod@redhat.com>
Wed, 28 Oct 2020 20:41:15 +0000 (16:41 -0400)
committerAndrew MacLeod <amacleod@redhat.com>
Thu, 29 Oct 2020 02:02:45 +0000 (22:02 -0400)
Simply call infer_non_null directly and avoid uneccessary checks of
the statement being modified.

gcc/
PR tree-optimization/97609
* gimple-range-cache.cc (non_null_ref::process_name): Call
infer_nonnull_range directly instead of infer_value_range.
gcc/testsuite/
* g++.dg/pr97609.C: New.

gcc/gimple-range-cache.cc
gcc/testsuite/g++.dg/pr97609.C [new file with mode: 0644]

index 13b9933cc019813add3297cdbab8c9c2ab362f49..bc9243c1279af95059e7e2ee6ea3a67cdcfe4bf9 100644 (file)
@@ -91,19 +91,15 @@ non_null_ref::process_name (tree name)
     {
       gimple *s = USE_STMT (use_p);
       unsigned index = gimple_bb (s)->index;
-      tree value;
-      enum tree_code comp_code;
 
       // If bit is already set for this block, dont bother looking again.
       if (bitmap_bit_p (b, index))
        continue;
 
-      // If we can infer a != 0 range, then set the bit for this BB
-      if (infer_value_range (s, name, &comp_code, &value))
-       {
-         if (comp_code == NE_EXPR && integer_zerop (value))
-           bitmap_set_bit (b, index);
-       }
+      // If we can infer a nonnull range, then set the bit for this BB
+      if (!SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name)
+         && infer_nonnull_range (s, name))
+       bitmap_set_bit (b, index);
     }
 
   m_nn[v] = b;
diff --git a/gcc/testsuite/g++.dg/pr97609.C b/gcc/testsuite/g++.dg/pr97609.C
new file mode 100644 (file)
index 0000000..8e582c9
--- /dev/null
@@ -0,0 +1,46 @@
+// PR tree-optimization/97609
+// { dg-do compile { target c++11 } }
+// { dg-options "-O2 -fno-tree-fre -fnon-call-exceptions" }
+
+struct _Fwd_list_node_base {
+  _Fwd_list_node_base *_M_next;
+  void _M_transfer_after() { _Fwd_list_node_base *__keep = _M_next = __keep; }
+};
+struct _Fwd_list_const_iterator {
+  _Fwd_list_const_iterator(_Fwd_list_node_base *__n) : _M_node(__n) {}
+  _Fwd_list_const_iterator(int);
+  _Fwd_list_node_base *_M_node;
+};
+template <typename, typename> struct forward_list {
+  _Fwd_list_node_base _M_head;
+  template <typename _InputIterator>
+  forward_list(_InputIterator, _InputIterator);
+  forward_list(int);
+  _Fwd_list_const_iterator cbefore_begin() { return &_M_head; }
+  void splice_after(_Fwd_list_const_iterator) noexcept;
+  void splice_after(_Fwd_list_const_iterator __pos, forward_list &) {
+    splice_after(__pos, 0);
+  }
+  using __remove_return_type = void;
+  __remove_return_type unique() { unique(0); }
+  template <typename _BinPred> __remove_return_type unique(_BinPred);
+};
+template <typename _Tp, typename _Alloc>
+void forward_list<_Tp, _Alloc>::splice_after(_Fwd_list_const_iterator __pos)
+  noexcept {
+  __pos._M_node->_M_transfer_after();
+}
+template <typename _Tp, typename _Alloc>
+template <typename _BinPred>
+auto forward_list<_Tp, _Alloc>::unique(_BinPred) -> __remove_return_type {
+  forward_list __to_destroy(0);
+  splice_after(__to_destroy.cbefore_begin());
+}
+
+void
+foo ()
+{
+  forward_list<int, int> c1 (0, 0);
+  c1.unique ();
+}
+