Index: clang/lib/Driver/ToolChains/Clang.cpp
--- clang/lib/Driver/ToolChains/Clang.cpp.orig
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -1610,6 +1610,13 @@ static void CollectARMPACBTIOptions(const ToolChain &T
         Args.MakeArgString(Twine("-msign-return-address-key=") + Key));
   if (IndirectBranches)
     CmdArgs.push_back("-mbranch-target-enforce");
+  else {
+    if (Triple.isOSOpenBSD()) {
+      CmdArgs.push_back("-msign-return-address=non-leaf");
+      CmdArgs.push_back("-msign-return-address-key=a_key");
+      CmdArgs.push_back("-mbranch-target-enforce");
+    }
+  }
 }
 
 void Clang::AddARMTargetArgs(const llvm::Triple &Triple, const ArgList &Args,
@@ -2536,6 +2543,11 @@ static void CollectArgsForIntegratedAssembler(Compilat
           CmdArgs.push_back("-soft-float");
           continue;
         }
+        if (Value.startswith("-mfix-loongson2f-btb")) {
+          CmdArgs.push_back("-mllvm");
+          CmdArgs.push_back("-fix-loongson2f-btb");
+          continue;
+        }
 
         MipsTargetFeature = llvm::StringSwitch<const char *>(Value)
                                 .Case("-mips1", "+mips1")
@@ -5289,9 +5301,12 @@ void Clang::ConstructJob(Compilation &C, const JobActi
       OFastEnabled ? options::OPT_Ofast : options::OPT_fstrict_aliasing;
   // We turn strict aliasing off by default if we're in CL mode, since MSVC
   // doesn't do any TBAA.
-  bool TBAAOnByDefault = !D.IsCLMode();
+  bool StrictAliasingDefault = !D.IsCLMode();
+  // We also turn off strict aliasing on OpenBSD.
+  if (getToolChain().getTriple().isOSOpenBSD())
+    StrictAliasingDefault = false;
   if (!Args.hasFlag(options::OPT_fstrict_aliasing, StrictAliasingAliasOption,
-                    options::OPT_fno_strict_aliasing, TBAAOnByDefault))
+                    options::OPT_fno_strict_aliasing, StrictAliasingDefault))
     CmdArgs.push_back("-relaxed-aliasing");
   if (!Args.hasFlag(options::OPT_fstruct_path_tbaa,
                     options::OPT_fno_struct_path_tbaa, true))
@@ -6321,7 +6336,8 @@ void Clang::ConstructJob(Compilation &C, const JobActi
                                       options::OPT_fno_strict_overflow)) {
     if (A->getOption().matches(options::OPT_fno_strict_overflow))
       CmdArgs.push_back("-fwrapv");
-  }
+  } else if (getToolChain().getTriple().isOSOpenBSD())
+    CmdArgs.push_back("-fwrapv");
 
   if (Arg *A = Args.getLastArg(options::OPT_freroll_loops,
                                options::OPT_fno_reroll_loops))
@@ -6342,7 +6358,48 @@ void Clang::ConstructJob(Compilation &C, const JobActi
   Args.addOptInFlag(CmdArgs, options::OPT_mspeculative_load_hardening,
                     options::OPT_mno_speculative_load_hardening);
 
-  RenderSSPOptions(D, TC, Args, CmdArgs, KernelOrKext);
+  // -ret-protector
+  unsigned RetProtector = 1;
+  if (Arg *A = Args.getLastArg(options::OPT_fno_ret_protector,
+        options::OPT_fret_protector)) {
+    if (A->getOption().matches(options::OPT_fno_ret_protector))
+      RetProtector = 0;
+    else if (A->getOption().matches(options::OPT_fret_protector))
+      RetProtector = 1;
+  }
+
+  if (RetProtector &&
+      ((getToolChain().getArch() == llvm::Triple::x86_64) ||
+       (getToolChain().getArch() == llvm::Triple::mips64) ||
+       (getToolChain().getArch() == llvm::Triple::mips64el) ||
+       (getToolChain().getArch() == llvm::Triple::ppc) ||
+       (getToolChain().getArch() == llvm::Triple::ppc64) ||
+       (getToolChain().getArch() == llvm::Triple::ppc64le) ||
+       (getToolChain().getArch() == llvm::Triple::aarch64)) &&
+      !Args.hasArg(options::OPT_fno_stack_protector) &&
+      !Args.hasArg(options::OPT_pg)) {
+    CmdArgs.push_back(Args.MakeArgString("-D_RET_PROTECTOR"));
+    CmdArgs.push_back(Args.MakeArgString("-ret-protector"));
+    // Consume the stack protector arguments to prevent warning
+    Args.getLastArg(options::OPT_fstack_protector_all,
+        options::OPT_fstack_protector_strong,
+        options::OPT_fstack_protector,
+        options::OPT__param); // ssp-buffer-size
+  } else {
+    // If we're not using retguard, then do the usual stack protector
+    RenderSSPOptions(D, TC, Args, CmdArgs, KernelOrKext);
+  }
+
+  // -fixup-gadgets
+  if (Arg *A = Args.getLastArg(options::OPT_fno_fixup_gadgets,
+                               options::OPT_ffixup_gadgets)) {
+    CmdArgs.push_back(Args.MakeArgString(Twine("-mllvm")));
+    if (A->getOption().matches(options::OPT_fno_fixup_gadgets))
+      CmdArgs.push_back(Args.MakeArgString(Twine("-x86-fixup-gadgets=false")));
+    else if (A->getOption().matches(options::OPT_ffixup_gadgets))
+      CmdArgs.push_back(Args.MakeArgString(Twine("-x86-fixup-gadgets=true")));
+  }
+
   RenderSCPOptions(TC, Args, CmdArgs);
   RenderTrivialAutoVarInitOptions(D, TC, Args, CmdArgs);
 
@@ -6417,6 +6474,11 @@ void Clang::ConstructJob(Compilation &C, const JobActi
   if (Arg *A = Args.getLastArg(options::OPT_fcf_protection_EQ)) {
     CmdArgs.push_back(
         Args.MakeArgString(Twine("-fcf-protection=") + A->getValue()));
+  } else if (Triple.isOSOpenBSD() && Triple.getArch() == llvm::Triple::x86_64) {
+    // Emit IBT endbr64 instructions by default
+    CmdArgs.push_back("-fcf-protection=branch");
+    // jump-table can generate indirect jumps, which are not permitted
+    CmdArgs.push_back("-fno-jump-tables");
   }
 
   if (Arg *A = Args.getLastArg(options::OPT_mfunction_return_EQ))
@@ -6895,6 +6957,18 @@ void Clang::ConstructJob(Compilation &C, const JobActi
                                      options::OPT_fno_rewrite_imports, false);
   if (RewriteImports)
     CmdArgs.push_back("-frewrite-imports");
+
+  // Disable some builtins on OpenBSD because they are just not
+  // right...
+  if (getToolChain().getTriple().isOSOpenBSD()) {
+    CmdArgs.push_back("-fno-builtin-malloc");
+    CmdArgs.push_back("-fno-builtin-calloc");
+    CmdArgs.push_back("-fno-builtin-realloc");
+    CmdArgs.push_back("-fno-builtin-valloc");
+    CmdArgs.push_back("-fno-builtin-free");
+    CmdArgs.push_back("-fno-builtin-strdup");
+    CmdArgs.push_back("-fno-builtin-strndup");
+  }
 
   Args.addOptInFlag(CmdArgs, options::OPT_fdirectives_only,
                     options::OPT_fno_directives_only);
