Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -2880,11 +2880,16 @@
       return false;
     }
 
+    bool VisitIfStmt(const IfStmt *S) {
+      bool Then = S->getThen() && this->Visit(S->getThen());
+      bool Else = S->getElse() && this->Visit(S->getElse());
+      return Then && Else;
+    }
+
     bool VisitStmt(const Stmt *S) {
-      for (const Stmt *Child : S->children())
-        if (Child && this->Visit(Child))
-          return true;
-      return false;
+      return llvm::any_of(S->children(), [this](const Stmt *Child) {
+        return Child && this->Visit(Child);
+      });
     }
   };
 
@@ -2952,7 +2957,7 @@
   };
 }
 
-// isTriviallyRecursive - Check if this function calls another
+// isTriviallyRecursive - Check if this function always calls another
 // decl that, because of the asm attribute or the other decl being a builtin,
 // ends up pointing to itself.
 bool
Index: clang/test/CodeGen/memmove-always-inline-definition-used.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/memmove-always-inline-definition-used.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s
+//
+// Verifies that even at O0, the inline definition of memmove has precedence
+// over the builtin
+
+typedef unsigned long size_t;
+
+#define AVAILABLE_EXTERNALLY extern inline __attribute__((always_inline)) \
+__attribute__((gnu_inline))
+
+AVAILABLE_EXTERNALLY void *memmove(void *a, const void *b, size_t c) {
+  if (c == 1 && a != b) {
+    return __builtin_memcpy(a, b, c);
+  } else
+    return __builtin_memmove(a, b, c);
+}
+
+// CHECK-LABEL: define void @foo
+void foo(void *a, const void *b, size_t c) {
+  // Clang should use the inline definition of memmove here.
+  // CHECK: call void @llvm.memcpy
+  // CHECK: call void @llvm.memmove
+  memmove(a, b, c);
+}
+
+// CHECK-NOT: nobuiltin
Index: llvm/include/llvm/Analysis/InlineCost.h
===================================================================
--- llvm/include/llvm/Analysis/InlineCost.h
+++ llvm/include/llvm/Analysis/InlineCost.h
@@ -272,6 +272,8 @@
 
 /// Minimal filter to detect invalid constructs for inlining.
 InlineResult isInlineViable(Function &Callee);
+/// AlwaysInline allows inlining of recursive function
+InlineResult isAlwaysInlineViable(Function &Callee);
 
 // This pass is used to annotate instructions during the inline process for
 // debugging and analysis. The main purpose of the pass is to see and test
Index: llvm/lib/Analysis/InlineCost.cpp
===================================================================
--- llvm/lib/Analysis/InlineCost.cpp
+++ llvm/lib/Analysis/InlineCost.cpp
@@ -2430,7 +2430,7 @@
   return llvm::InlineCost::get(CA.getCost(), CA.getThreshold());
 }
 
-InlineResult llvm::isInlineViable(Function &F) {
+static InlineResult isInlineViableImpl(Function &F, bool RecursiveIsViable) {
   bool ReturnsTwice = F.hasFnAttribute(Attribute::ReturnsTwice);
   for (BasicBlock &BB : F) {
     // Disallow inlining of functions which contain indirect branches.
@@ -2449,8 +2449,8 @@
       if (!Call)
         continue;
 
-      // Disallow recursive calls.
       Function *Callee = Call->getCalledFunction();
+      // Disallow recursive calls.
       if (&F == Callee)
         return InlineResult::failure("recursive call");
 
@@ -2486,6 +2486,14 @@
   return InlineResult::success();
 }
 
+InlineResult llvm::isInlineViable(Function &F) {
+  return isInlineViableImpl(F, false /* disallow recursive call */);
+}
+
+InlineResult llvm::isAlwaysInlineViable(Function &F) {
+  return isInlineViableImpl(F, true /* allow recursive call */);
+}
+
 // APIs to create InlineParams based on command line flags and/or other
 // parameters.
 
Index: llvm/lib/Transforms/IPO/AlwaysInliner.cpp
===================================================================
--- llvm/lib/Transforms/IPO/AlwaysInliner.cpp
+++ llvm/lib/Transforms/IPO/AlwaysInliner.cpp
@@ -189,7 +189,7 @@
   if (!CB.hasFnAttr(Attribute::AlwaysInline))
     return InlineCost::getNever("no alwaysinline attribute");
 
-  auto IsViable = isInlineViable(*Callee);
+  auto IsViable = isAlwaysInlineViable(*Callee);
   if (!IsViable.isSuccess())
     return InlineCost::getNever(IsViable.getFailureReason());