diff --git a/mlir/lib/Transforms/Inliner.cpp b/mlir/lib/Transforms/Inliner.cpp
--- a/mlir/lib/Transforms/Inliner.cpp
+++ b/mlir/lib/Transforms/Inliner.cpp
@@ -457,6 +457,8 @@
   // here as more calls may be added during inlining.
   bool inlinedAnyCalls = false;
   for (unsigned i = 0; i != calls.size(); ++i) {
+    if (llvm::find(deadNodes, calls[i].sourceNode) != deadNodes.end())
+      continue;
     ResolvedCall it = calls[i];
     bool doInline = shouldInline(it);
     CallOpInterface call = it.call;
diff --git a/mlir/test/Transforms/inlining-repeated-use.mlir b/mlir/test/Transforms/inlining-repeated-use.mlir
new file mode 100644
--- /dev/null
+++ b/mlir/test/Transforms/inlining-repeated-use.mlir
@@ -0,0 +1,48 @@
+// RUN: mlir-opt -inline %s | FileCheck %s
+
+// This could crash the inliner, make sure it does not.
+
+func @A() {
+  call @B() { inA } : () -> ()
+  return
+}
+
+func @B() {
+  call @E() : () -> ()
+  return
+}
+
+func @C() {
+  call @D() : () -> ()
+  return
+}
+
+func private @D() {
+  call @B() { inD } : () -> ()
+  return
+}
+
+func @E() {
+  call @fabsf() : () -> ()
+  return
+}
+
+func private @fabsf()
+
+// CHECK: func @A() {
+// CHECK:   call @fabsf() : () -> ()
+// CHECK:   return
+// CHECK: }
+// CHECK: func @B() {
+// CHECK:   call @fabsf() : () -> ()
+// CHECK:   return
+// CHECK: }
+// CHECK: func @C() {
+// CHECK:   call @fabsf() : () -> ()
+// CHECK:   return
+// CHECK: }
+// CHECK: func @E() {
+// CHECK:   call @fabsf() : () -> ()
+// CHECK:   return
+// CHECK: }
+// CHECK: func private @fabsf()