diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.h b/clang/lib/Driver/ToolChains/Arch/RISCV.h
--- a/clang/lib/Driver/ToolChains/Arch/RISCV.h
+++ b/clang/lib/Driver/ToolChains/Arch/RISCV.h
@@ -26,6 +26,8 @@
                       const llvm::Triple &Triple);
 StringRef getRISCVArch(const llvm::opt::ArgList &Args,
                        const llvm::Triple &Triple);
+std::string getRISCVTuneCPU(const llvm::opt::ArgList &Args,
+                            const llvm::Triple &Triple);
 std::string getRISCVTargetCPU(const llvm::opt::ArgList &Args,
                               const llvm::Triple &Triple);
 } // end namespace riscv
diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
--- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -305,6 +305,24 @@
   }
 }
 
+std::string riscv::getRISCVTuneCPU(const llvm::opt::ArgList &Args,
+                                   const llvm::Triple &Triple) {
+  assert(Triple.isRISCV() && "Unexpected triple");
+
+  if (const Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) {
+    if (strcmp(A->getValue(), "native") == 0)
+      return llvm::sys::getHostCPUName().str();
+
+    return A->getValue();
+  }
+
+  std::string CPU = getRISCVTargetCPU(Args, Triple);
+  if (!CPU.empty())
+    return CPU;
+
+  return std::string();
+}
+
 std::string riscv::getRISCVTargetCPU(const llvm::opt::ArgList &Args,
                                      const llvm::Triple &Triple) {
   std::string CPU;
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -2099,12 +2099,12 @@
                     options::OPT_mno_implicit_float, true))
     CmdArgs.push_back("-no-implicit-float");
 
-  if (const Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) {
+  std::string TuneCpu =
+      riscv::getRISCVTuneCPU(Args, getToolChain().getTriple());
+
+  if (!TuneCpu.empty()) {
     CmdArgs.push_back("-tune-cpu");
-    if (strcmp(A->getValue(), "native") == 0)
-      CmdArgs.push_back(Args.MakeArgString(llvm::sys::getHostCPUName()));
-    else
-      CmdArgs.push_back(A->getValue());
+    CmdArgs.push_back(Args.MakeArgString(TuneCpu));
   }
 }
 
@@ -7815,6 +7815,14 @@
 
   CmdArgs.push_back("-target-abi");
   CmdArgs.push_back(ABIName.data());
+
+  std::string TuneCpu =
+      riscv::getRISCVTuneCPU(Args, getToolChain().getTriple());
+
+  if (!TuneCpu.empty()) {
+    CmdArgs.push_back("-tune-cpu");
+    CmdArgs.push_back(Args.MakeArgString(TuneCpu));
+  }
 }
 
 void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -421,7 +421,8 @@
       return "ck810";
   case llvm::Triple::riscv32:
   case llvm::Triple::riscv64:
-    return riscv::getRISCVTargetCPU(Args, T);
+    // RISC-V will handle -target-cpu option in different way.
+    return "";
 
   case llvm::Triple::bpfel:
   case llvm::Triple::bpfeb:
diff --git a/clang/test/Driver/riscv-cpus.c b/clang/test/Driver/riscv-cpus.c
--- a/clang/test/Driver/riscv-cpus.c
+++ b/clang/test/Driver/riscv-cpus.c
@@ -1,21 +1,21 @@
 // Check target CPUs are correctly passed.
 
 // RUN: %clang --target=riscv32 -### -c %s 2>&1 -mcpu=rocket-rv32 | FileCheck -check-prefix=MCPU-ROCKET32 %s
-// MCPU-ROCKET32: "-nostdsysteminc" "-target-cpu" "rocket-rv32"
+// MCPU-ROCKET32: "-tune-cpu" "rocket-rv32"
 
 // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=rocket-rv64 | FileCheck -check-prefix=MCPU-ROCKET64 %s
-// MCPU-ROCKET64: "-nostdsysteminc" "-target-cpu" "rocket-rv64"
 // MCPU-ROCKET64: "-target-feature" "+64bit"
+// MCPU-ROCKET64: "-tune-cpu" "rocket-rv64"
 
 // RUN: %clang --target=riscv32 -### -c %s 2>&1 -mcpu=syntacore-scr1-base | FileCheck -check-prefix=MCPU-SYNTACORE-SCR1-BASE %s
-// MCPU-SYNTACORE-SCR1-BASE: "-target-cpu" "syntacore-scr1-base"
 // MCPU-SYNTACORE-SCR1-BASE: "-target-feature" "+c" "-target-feature" "-64bit"
 // MCPU-SYNTACORE-SCR1-BASE: "-target-abi" "ilp32"
+// MCPU-SYNTACORE-SCR1-BASE: "-tune-cpu" "syntacore-scr1-base"
 
 // RUN: %clang --target=riscv32 -### -c %s 2>&1 -mcpu=syntacore-scr1-max | FileCheck -check-prefix=MCPU-SYNTACORE-SCR1-MAX %s
-// MCPU-SYNTACORE-SCR1-MAX: "-target-cpu" "syntacore-scr1-max"
 // MCPU-SYNTACORE-SCR1-MAX: "-target-feature" "+m" "-target-feature" "+c" "-target-feature" "-64bit"
 // MCPU-SYNTACORE-SCR1-MAX: "-target-abi" "ilp32"
+// MCPU-SYNTACORE-SCR1-MAX: "-tune-cpu" "syntacore-scr1-max"
 
 // We cannot check much for -mcpu=native, but it should be replaced by a valid CPU string.
 // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=native | FileCheck -check-prefix=MCPU-NATIVE %s
@@ -52,90 +52,91 @@
 
 // mcpu with default march
 // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-e20 | FileCheck -check-prefix=MCPU-SIFIVE-E20 %s
-// MCPU-SIFIVE-E20: "-nostdsysteminc" "-target-cpu" "sifive-e20"
 // MCPU-SIFIVE-E20: "-target-feature" "+m" "-target-feature" "+c"
 // MCPU-SIFIVE-E20: "-target-abi" "ilp32"
+// MCPU-SIFIVE-E20: "-tune-cpu" "sifive-e20"
 
 // mcpu with default march
 // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-e21 | FileCheck -check-prefix=MCPU-SIFIVE-E21 %s
-// MCPU-SIFIVE-E21: "-nostdsysteminc" "-target-cpu" "sifive-e21"
 // MCPU-SIFIVE-E21: "-target-feature" "+m" "-target-feature" "+a" "-target-feature" "+c"
 // MCPU-SIFIVE-E21: "-target-abi" "ilp32"
+// MCPU-SIFIVE-E21: "-tune-cpu" "sifive-e21"
 
 // mcpu with default march
 // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-e24 | FileCheck -check-prefix=MCPU-SIFIVE-E24 %s
-// MCPU-SIFIVE-E24: "-nostdsysteminc" "-target-cpu" "sifive-e24"
 // MCPU-SIFIVE-E24: "-target-feature" "+m" "-target-feature" "+a" "-target-feature" "+f"
 // MCPU-SIFIVE-E24: "-target-feature" "+c"
 // MCPU-SIFIVE-E24: "-target-abi" "ilp32"
+// MCPU-SIFIVE-E24: "-tune-cpu" "sifive-e24"
 
 // mcpu with default march
 // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-e34 | FileCheck -check-prefix=MCPU-SIFIVE-E34 %s
-// MCPU-SIFIVE-E34: "-nostdsysteminc" "-target-cpu" "sifive-e34"
 // MCPU-SIFIVE-E34: "-target-feature" "+m" "-target-feature" "+a" "-target-feature" "+f"
 // MCPU-SIFIVE-E34: "-target-feature" "+c"
 // MCPU-SIFIVE-E34: "-target-abi" "ilp32"
+// MCPU-SIFIVE-E34: "-tune-cpu" "sifive-e34"
 
 // mcpu with mabi option
 // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-s21 -mabi=lp64 | FileCheck -check-prefix=MCPU-ABI-SIFIVE-S21 %s
-// MCPU-ABI-SIFIVE-S21: "-nostdsysteminc" "-target-cpu" "sifive-s21"
 // MCPU-ABI-SIFIVE-S21: "-target-feature" "+m" "-target-feature" "+a"
 // MCPU-ABI-SIFIVE-S21: "-target-feature" "+c" "-target-feature" "+64bit"
 // MCPU-ABI-SIFIVE-S21: "-target-abi" "lp64"
+// MCPU-ABI-SIFIVE-S21: "-tune-cpu" "sifive-s21"
 
 // mcpu with mabi option
 // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-s51 -mabi=lp64 | FileCheck -check-prefix=MCPU-ABI-SIFIVE-S51 %s
-// MCPU-ABI-SIFIVE-S51: "-nostdsysteminc" "-target-cpu" "sifive-s51"
 // MCPU-ABI-SIFIVE-S51: "-target-feature" "+m" "-target-feature" "+a"
 // MCPU-ABI-SIFIVE-S51: "-target-feature" "+c" "-target-feature" "+64bit"
 // MCPU-ABI-SIFIVE-S51: "-target-abi" "lp64"
+// MCPU-ABI-SIFIVE-S51: "-tune-cpu" "sifive-s51"
 
 // mcpu with default march
 // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-s54 | FileCheck -check-prefix=MCPU-SIFIVE-S54 %s
-// MCPU-SIFIVE-S54: "-nostdsysteminc" "-target-cpu" "sifive-s54"
 // MCPU-SIFIVE-S54: "-target-feature" "+m" "-target-feature" "+a" "-target-feature" "+f" "-target-feature" "+d"
 // MCPU-SIFIVE-S54: "-target-feature" "+c" "-target-feature" "+64bit"
 // MCPU-SIFIVE-S54: "-target-abi" "lp64d"
+// MCPU-SIFIVE-S54: "-tune-cpu" "sifive-s54"
 
 // mcpu with mabi option
 // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-s76 | FileCheck -check-prefix=MCPU-SIFIVE-S76 %s
-// MCPU-SIFIVE-S76: "-nostdsysteminc" "-target-cpu" "sifive-s76"
 // MCPU-SIFIVE-S76: "-target-feature" "+m" "-target-feature" "+a" "-target-feature" "+f" "-target-feature" "+d"
 // MCPU-SIFIVE-S76: "-target-feature" "+c" "-target-feature" "+64bit"
 // MCPU-SIFIVE-S76: "-target-abi" "lp64d"
+// MCPU-SIFIVE-S76: "-tune-cpu" "sifive-s76"
 
 // mcpu with default march
 // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-u54 | FileCheck -check-prefix=MCPU-SIFIVE-U54 %s
-// MCPU-SIFIVE-U54: "-nostdsysteminc" "-target-cpu" "sifive-u54"
 // MCPU-SIFIVE-U54: "-target-feature" "+m" "-target-feature" "+a" "-target-feature" "+f" "-target-feature" "+d"
 // MCPU-SIFIVE-U54: "-target-feature" "+c" "-target-feature" "+64bit"
 // MCPU-SIFIVE-U54: "-target-abi" "lp64d"
+// MCPU-SIFIVE-U54: "-tune-cpu" "sifive-u54"
 
 // mcpu with mabi option
 // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-u54 -mabi=lp64 | FileCheck -check-prefix=MCPU-ABI-SIFIVE-U54 %s
-// MCPU-ABI-SIFIVE-U54: "-nostdsysteminc" "-target-cpu" "sifive-u54"
 // MCPU-ABI-SIFIVE-U54: "-target-feature" "+m" "-target-feature" "+a" "-target-feature" "+f" "-target-feature" "+d"
 // MCPU-ABI-SIFIVE-U54: "-target-feature" "+c" "-target-feature" "+64bit"
 // MCPU-ABI-SIFIVE-U54: "-target-abi" "lp64"
+// MCPU-ABI-SIFIVE-U54: "-tune-cpu" "sifive-u54"
 
 // mcpu with default march
 // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-e76 | FileCheck -check-prefix=MCPU-SIFIVE-E76 %s
-// MCPU-SIFIVE-E76: "-nostdsysteminc" "-target-cpu" "sifive-e76"
 // MCPU-SIFIVE-E76: "-target-feature" "+m" "-target-feature" "+a" "-target-feature" "+f"
 // MCPU-SIFIVE-E76: "-target-feature" "+c"
 // MCPU-SIFIVE-E76: "-target-abi" "ilp32"
+// MCPU-SIFIVE-E76: "-tune-cpu" "sifive-e76"
 
 // mcpu with mabi option
 // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-u74 -mabi=lp64 | FileCheck -check-prefix=MCPU-ABI-SIFIVE-U74 %s
-// MCPU-ABI-SIFIVE-U74: "-nostdsysteminc" "-target-cpu" "sifive-u74"
 // MCPU-ABI-SIFIVE-U74: "-target-feature" "+m" "-target-feature" "+a" "-target-feature" "+f" "-target-feature" "+d"
 // MCPU-ABI-SIFIVE-U74: "-target-feature" "+c" "-target-feature" "+64bit"
 // MCPU-ABI-SIFIVE-U74: "-target-abi" "lp64"
+// MCPU-ABI-SIFIVE-U74: "-tune-cpu" "sifive-u74"
 
 // march overwrite mcpu's default march
 // RUN: %clang --target=riscv32 -### -c %s 2>&1 -mcpu=sifive-e31 -march=rv32imc | FileCheck -check-prefix=MCPU-MARCH %s
-// MCPU-MARCH: "-nostdsysteminc" "-target-cpu" "sifive-e31" "-target-feature" "+m" "-target-feature" "+c"
+// MCPU-MARCH: "-target-feature" "+m" "-target-feature" "+c"
 // MCPU-MARCH: "-target-abi" "ilp32"
+// MCPU-MARCH: "-tune-cpu" "sifive-e31"
 
 // Check interaction between mcpu and mtune, mtune won't affect arch related
 // target feature, but mcpu will.
@@ -144,9 +145,8 @@
 // should not enabled.
 //
 // RUN: %clang --target=riscv32 -### -c %s 2>&1 -mcpu=sifive-e31 -mtune=sifive-e76 | FileCheck -check-prefix=MTUNE-E31-MCPU-E76 %s
-// MTUNE-E31-MCPU-E76: "-target-cpu" "sifive-e31"
 // MTUNE-E31-MCPU-E76-NOT: "-target-feature" "+f"
-// MTUNE-E31-MCPU-E76-SAME: "-target-feature" "+m"
+// MTUNE-E31-MCPU-E76: "-target-feature" "+m"
 // MTUNE-E31-MCPU-E76-SAME: "-target-feature" "+a"
 // MTUNE-E31-MCPU-E76-SAME: "-target-feature" "+c"
 // MTUNE-E31-MCPU-E76-SAME: "-tune-cpu" "sifive-e76"
diff --git a/clang/test/Driver/riscv-march-mcpu-mtune.c b/clang/test/Driver/riscv-march-mcpu-mtune.c
new file mode 100644
--- /dev/null
+++ b/clang/test/Driver/riscv-march-mcpu-mtune.c
@@ -0,0 +1,82 @@
+// Check the priority between -mcpu, -mtune and -march
+
+// sifive-e76 is rv32imafc and sifive-e31 is rv32imac
+
+// -mcpu, -mtune and -march are not given, pipeline model and arch ext. use
+// default setting.
+// RUN: %clang --target=riscv32-elf -### -c %s 2>&1 \
+// RUN:     | FileCheck -check-prefix=CHECK-DEFAULT %s
+// CHECK-DEFAULT: "-target-feature" "+m" "-target-feature" "+a"
+// CHECK-DEFAULT: "-target-feature" "+c"
+// CHECK-DEFAULT: "-tune-cpu" "generic-rv32"
+// CHECK-DEFAULT-NOT: "-target-cpu"
+
+// -mtune is given, pipeline model take from -mtune, arch ext. use
+// default setting.
+// RUN: %clang --target=riscv32 -mtune=sifive-e76 -### -c %s 2>&1 \
+// RUN:     | FileCheck -check-prefix=MTUNE-E76 %s
+// MTUNE-E76: "-target-feature" "+m" "-target-feature" "+a"
+// MTUNE-E76: "-target-feature" "+c"
+// MTUNE-E76: "-tune-cpu" "sifive-e76"
+// MTUNE-E76-NOT: "-target-cpu"
+// MTUNE-E76-NOT: "-target-feature" "+f"
+
+// -march is given, arch ext. take from -march, pipeline model use
+// default setting.
+// RUN: %clang --target=riscv32 -### -c %s -march=rv32imafdc 2>&1 \
+// RUN:     | FileCheck -check-prefix=MARCH-RV32IMAFDC %s
+// MARCH-RV32IMAFDC: "-target-feature" "+m" "-target-feature" "+a"
+// MARCH-RV32IMAFDC: "-target-feature" "+f" "-target-feature" "+d"
+// MARCH-RV32IMAFDC: "-target-feature" "+c"
+// MARCH-RV32IMAFDC: "-tune-cpu" "generic-rv32"
+// MARCH-RV32IMAFDC-NOT: "-target-cpu"
+
+// -mcpu is given, pipeline model and arch ext. from -mcpu.
+// RUN: %clang --target=riscv32 -### -c %s -mcpu=sifive-e76 2>&1 \
+// RUN:     | FileCheck -check-prefix=MCPU-E76 %s
+// MCPU-E76: "-target-feature" "+m" "-target-feature" "+a"
+// MCPU-E76: "-target-feature" "+f" "-target-feature" "+c"
+// MCPU-E76: "-tune-cpu" "sifive-e76"
+// MCPU-E76-NOT: "-target-cpu"
+
+// -mcpu and -mtune are given, so pipeline model take from -mtune, and arch ext.
+// take from -mcpu since -march is not given.
+// RUN: %clang --target=riscv32 -### -c %s -mcpu=sifive-e76 -mtune=sifive-e31 2>&1 \
+// RUN:     | FileCheck -check-prefix=MCPU-E76-MTUNE-E31 %s
+// MCPU-E76-MTUNE-E31: "-target-feature" "+m" "-target-feature" "+a"
+// MCPU-E76-MTUNE-E31: "-target-feature" "+f" "-target-feature" "+c"
+// MCPU-E76-MTUNE-E31: "-tune-cpu" "sifive-e31"
+// MCPU-E76-MTUNE-E31-NOT: "-tune-cpu" "sifive-e76"
+// MCPU-E76-MTUNE-E31-NOT: "-target-cpu"
+
+// RUN: %clang --target=riscv32 -### -c %s -mtune=sifive-e76 -mcpu=sifive-e31 2>&1 \
+// RUN:     | FileCheck -check-prefix=MTUNE-E76-MCPU-E31 %s
+// MTUNE-E76-MCPU-E31: "-target-feature" "+m" "-target-feature" "+a"
+// MTUNE-E76-MCPU-E31: "-target-feature" "+c"
+// MTUNE-E76-MCPU-E31: "-tune-cpu" "sifive-e76"
+// MTUNE-E76-MCPU-E31-NOT: "-tune-cpu" "sifive-e31"
+// MTUNE-E76-MCPU-E31-NOT: "-target-cpu"
+// MTUNE-E76-MCPU-E31-NOT: "-target-feature" "+f"
+
+// -mcpu and -march are given, so pipeline model take from -mcpu since -mtune is
+// not given, and arch ext. take from -march.
+// RUN: %clang --target=riscv32 -### -c %s -mcpu=sifive-e31 -march=rv32ic 2>&1 \
+// RUN:     | FileCheck -check-prefix=MCPU-E31-MARCH-RV32I %s
+// MCPU-E31-MARCH-RV32I: "-target-feature" "+c"
+// MCPU-E31-MARCH-RV32I: "-tune-cpu" "sifive-e31"
+// MCPU-E31-MARCH-RV32I-NOT: "-target-cpu"
+// MCPU-E31-MARCH-RV32I-NOT: "-target-feature" "+m"
+// MCPU-E31-MARCH-RV32I-NOT: "-target-feature" "+a"
+// MCPU-E31-MARCH-RV32I-NOT: "-target-feature" "+f"
+
+// -mcpu, -march and -mtune are given, so pipeline model take from -mtune
+// and arch ext. take from -march, -mcpu is unused.
+// RUN: %clang --target=riscv32 -### -c %s -mcpu=sifive-e31 -mtune=sifive-e76 -march=rv32ic 2>&1 \
+// RUN:     | FileCheck -check-prefix=MCPU-E31-MTUNE-E76-MARCH-RV32I %s
+// MCPU-E31-MTUNE-E76-MARCH-RV32I: "-target-feature" "+c"
+// MCPU-E31-MTUNE-E76-MARCH-RV32I: "-tune-cpu" "sifive-e76"
+// MCPU-E31-MTUNE-E76-MARCH-RV32I-NOT: "-target-cpu"
+// MCPU-E31-MTUNE-E76-MARCH-RV32I-NOT: "-tune-cpu" "sifive-e31"
+// MCPU-E31-MTUNE-E76-MARCH-RV32I-NOT: "-target-feature" "+m"
+// MCPU-E31-MTUNE-E76-MARCH-RV32I-NOT: "-target-feature" "+a"
+// MCPU-E31-MTUNE-E76-MARCH-RV32I-NOT: "-target-feature" "+f"