Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp	(revision 223983)
+++ lib/CodeGen/CodeGenModule.cpp	(working copy)
@@ -725,7 +725,8 @@
   }
 
   if (D->hasAttr<ColdAttr>()) {
-    B.addAttribute(llvm::Attribute::OptimizeForSize);
+    if (!D->hasAttr<OptimizeNoneAttr>())
+      B.addAttribute(llvm::Attribute::OptimizeForSize);
     B.addAttribute(llvm::Attribute::Cold);
   }
 
@@ -766,7 +767,9 @@
     F->addFnAttr(llvm::Attribute::NoInline);
 
     // OptimizeNone wins over OptimizeForSize, MinSize, AlwaysInline.
-    F->removeFnAttr(llvm::Attribute::OptimizeForSize);
+    assert(!F->hasFnAttribute(llvm::Attribute::OptimizeForSize) &&
+           "OptimizeNone and OptimizeForSize on same function!");
+    // FIXME: Change these to asserts.
     F->removeFnAttr(llvm::Attribute::MinSize);
     F->removeFnAttr(llvm::Attribute::AlwaysInline);
 
Index: lib/CodeGen/CGCall.cpp
===================================================================
--- lib/CodeGen/CGCall.cpp	(revision 223983)
+++ lib/CodeGen/CGCall.cpp	(working copy)
@@ -1340,6 +1340,7 @@
                                            bool AttrOnCallSite) {
   llvm::AttrBuilder FuncAttrs;
   llvm::AttrBuilder RetAttrs;
+  bool HasOptnone = false;
 
   CallingConv = FI.getEffectiveCallingConvention();
 
@@ -1380,12 +1381,18 @@
       RetAttrs.addAttribute(llvm::Attribute::NoAlias);
     if (TargetDecl->hasAttr<ReturnsNonNullAttr>())
       RetAttrs.addAttribute(llvm::Attribute::NonNull);
+
+    HasOptnone = TargetDecl->hasAttr<OptimizeNoneAttr>();
   }
 
-  if (CodeGenOpts.OptimizeSize)
-    FuncAttrs.addAttribute(llvm::Attribute::OptimizeForSize);
-  if (CodeGenOpts.OptimizeSize == 2)
-    FuncAttrs.addAttribute(llvm::Attribute::MinSize);
+  // OptimizeNoneAttr takes precedence over -Os or -Oz. No warning needed.
+  if (!HasOptnone) {
+    if (CodeGenOpts.OptimizeSize)
+      FuncAttrs.addAttribute(llvm::Attribute::OptimizeForSize);
+    if (CodeGenOpts.OptimizeSize == 2)
+      FuncAttrs.addAttribute(llvm::Attribute::MinSize);
+  }
+
   if (CodeGenOpts.DisableRedZone)
     FuncAttrs.addAttribute(llvm::Attribute::NoRedZone);
   if (CodeGenOpts.NoImplicitFloat)
Index: test/CodeGen/attr-optnone.c
===================================================================
--- test/CodeGen/attr-optnone.c	(revision 223985)
+++ test/CodeGen/attr-optnone.c	(working copy)
@@ -4,10 +4,14 @@
 // RUN: %clang_cc1 -emit-llvm -Os < %s > %t
 // RUN: FileCheck %s --check-prefix=PRESENT < %t
 // RUN: FileCheck %s --check-prefix=OPTSIZE < %t
+// RUN: %clang_cc1 -emit-llvm -Oz < %s > %t
+// RUN: FileCheck %s --check-prefix=PRESENT < %t
+// RUN: FileCheck %s --check-prefix=MINSIZE < %t
 
 __attribute__((always_inline))
 int test2() { return 0; }
 // OPTSIZE: @test2{{.*}}[[ATTR2:#[0-9]+]]
+// MINSIZE: @test2{{.*}}[[ATTR2:#[0-9]+]]
 
 __attribute__((optnone))
 int test3() { return 0; }
@@ -31,3 +35,8 @@
 // OPTSIZE-NOT: optsize
 // OPTSIZE: attributes [[ATTR2]] = { {{.*}}optsize{{.*}} }
 // OPTSIZE-NOT: optsize
+
+// With -Oz, check that 'minsize' appears only on test2.
+// MINSIZE-NOT: minsize
+// MINSIZE: attributes [[ATTR2]] = { {{.*}}minsize{{.*}} }
+// MINSIZE-NOT: minsize
Index: test/SemaCXX/pragma-optimize.cpp
===================================================================
--- test/SemaCXX/pragma-optimize.cpp	(revision 223985)
+++ test/SemaCXX/pragma-optimize.cpp	(working copy)
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -I %S/Inputs -x c++ -std=c++11 -triple x86_64-unknown-linux -emit-llvm -O2 < %s | FileCheck %s
+// RUN: %clang_cc1 -I %S/Inputs -x c++ -std=c++11 -triple x86_64-unknown-linux -emit-llvm -Os < %s | FileCheck %s
+// RUN: %clang_cc1 -I %S/Inputs -x c++ -std=c++11 -triple x86_64-unknown-linux -emit-llvm -Oz < %s | FileCheck %s
 
 #pragma clang optimize off
 
