diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c118e4ddca982c1a733ba4d98d6d70682d87faef..892f7aa5ef1c7357fc7c9b9b309c0c4eca9eec69 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2019-08-05  Martin Liska  <mliska@suse.cz>
+
+	PR c++/91334
+	* tree-ssa-dce.c (propagate_necessity): Handle new operators
+	with not arguments.
+	(eliminate_unnecessary_stmts): Likewise.
+
 2019-08-05  Richard Biener  <rguenther@suse.de>
 
 	PR middle-end/91169
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5dc9d11140b99b145b41dd4c9c96db6fb7b56d25..cff940e0b28883c6c707e414ba7f4547c8fc80a6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2019-08-05  Martin Liska  <mliska@suse.cz>
+
+	PR c++/91334
+	* g++.dg/torture/pr91334.C: New test.
+
 2019-08-05  Richard Biener  <rguenther@suse.de>
 
 	PR middle-end/91169
diff --git a/gcc/testsuite/g++.dg/torture/pr91334.C b/gcc/testsuite/g++.dg/torture/pr91334.C
new file mode 100644
index 0000000000000000000000000000000000000000..ba79d712b0793eae5607edea1abde42b533342ef
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr91334.C
@@ -0,0 +1,14 @@
+/* PR c++/91334.  */
+/* { dg-do compile } */
+
+#include <new>
+#include <stdlib.h>
+
+struct A {
+  A() { throw 0; }
+  void* operator new(size_t size, double = 0.0) { return ::operator new(size);}
+  void operator delete(void* p, double) { exit(0); }
+  void operator delete(void* p) { abort(); }
+};
+
+int main() { try { new A; } catch(...) {} }
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
index 80d5f5c30f7f4bbe209db5357414ff443ee88b5f..afb7bd9dedc622112bcc56c9f0b9f6a06e4e4a9f 100644
--- a/gcc/tree-ssa-dce.c
+++ b/gcc/tree-ssa-dce.c
@@ -810,6 +810,11 @@ propagate_necessity (bool aggressive)
 	  if (is_delete_operator
 	      || gimple_call_builtin_p (stmt, BUILT_IN_FREE))
 	    {
+	      /* It can happen that a user delete operator has the pointer
+		 argument optimized out already.  */
+	      if (gimple_call_num_args (stmt) == 0)
+		continue;
+
 	      tree ptr = gimple_call_arg (stmt, 0);
 	      gimple *def_stmt;
 	      tree def_callee;
@@ -1323,13 +1328,18 @@ eliminate_unnecessary_stmts (void)
 		  || (is_gimple_call (stmt)
 		      && gimple_call_operator_delete_p (as_a <gcall *> (stmt)))))
 	    {
-	      tree ptr = gimple_call_arg (stmt, 0);
-	      if (TREE_CODE (ptr) == SSA_NAME)
+	      /* It can happen that a user delete operator has the pointer
+		 argument optimized out already.  */
+	      if (gimple_call_num_args (stmt) > 0)
 		{
-		  gimple *def_stmt = SSA_NAME_DEF_STMT (ptr);
-		  if (!gimple_nop_p (def_stmt)
-		      && !gimple_plf (def_stmt, STMT_NECESSARY))
-		    gimple_set_plf (stmt, STMT_NECESSARY, false);
+		  tree ptr = gimple_call_arg (stmt, 0);
+		  if (TREE_CODE (ptr) == SSA_NAME)
+		    {
+		      gimple *def_stmt = SSA_NAME_DEF_STMT (ptr);
+		      if (!gimple_nop_p (def_stmt)
+			  && !gimple_plf (def_stmt, STMT_NECESSARY))
+			gimple_set_plf (stmt, STMT_NECESSARY, false);
+		    }
 		}
 	    }