ajpaverd updated this revision to Diff 223167.
ajpaverd marked 22 inline comments as done.
ajpaverd added a comment.

Improved Control Flow Guard implementation.

As suggested by @rnk, the CFGuard dispatch mechanism now uses a new 
`cfguardtarget` operand bundle to pass the indirect call target. Instruction
selection adds this target as a new ArgListEntry and sets a new 
`isCFGuardTarget` bit. CC_X86_Win64_C puts this argument in RAX.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D65761/new/

https://reviews.llvm.org/D65761

Files:
  clang/include/clang/Driver/CC1Options.td
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Driver/ToolChains/MSVC.cpp
  clang/test/Driver/cl-fallback.c
  llvm/docs/LangRef.rst
  llvm/include/llvm/CodeGen/MachineBasicBlock.h
  llvm/include/llvm/CodeGen/TargetCallingConv.h
  llvm/include/llvm/CodeGen/TargetLowering.h
  llvm/include/llvm/IR/CallingConv.h
  llvm/include/llvm/IR/InstrTypes.h
  llvm/include/llvm/IR/LLVMContext.h
  llvm/include/llvm/Target/TargetCallingConv.td
  llvm/include/llvm/Transforms/CFGuard.h
  llvm/lib/AsmParser/LLLexer.cpp
  llvm/lib/AsmParser/LLParser.cpp
  llvm/lib/AsmParser/LLToken.h
  llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  llvm/lib/CodeGen/AsmPrinter/WinCFGuard.cpp
  llvm/lib/CodeGen/AsmPrinter/WinCFGuard.h
  llvm/lib/CodeGen/CFGuardLongjmp.cpp
  llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
  llvm/lib/CodeGen/MachineBasicBlock.cpp
  llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/IR/AsmWriter.cpp
  llvm/lib/IR/LLVMContext.cpp
  llvm/lib/IR/Verifier.cpp
  llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
  llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
  llvm/lib/Target/ARM/ARMISelLowering.cpp
  llvm/lib/Target/ARM/ARMTargetMachine.cpp
  llvm/lib/Target/X86/CMakeLists.txt
  llvm/lib/Target/X86/X86.h
  llvm/lib/Target/X86/X86CallingConv.td
  llvm/lib/Target/X86/X86FastISel.cpp
  llvm/lib/Target/X86/X86FixupCFGuard.cpp
  llvm/lib/Target/X86/X86RegisterInfo.cpp
  llvm/lib/Target/X86/X86Subtarget.h
  llvm/lib/Target/X86/X86TargetMachine.cpp
  llvm/lib/Transforms/CFGuard/CFGuard.cpp
  llvm/test/Bitcode/calling-conventions.3.2.ll
  llvm/test/Bitcode/operand-bundles-bc-analyzer.ll
  llvm/test/CodeGen/AArch64/cfguard-checks.ll
  llvm/test/CodeGen/AArch64/cfguard-module-flag.ll
  llvm/test/CodeGen/ARM/cfguard-checks.ll
  llvm/test/CodeGen/ARM/cfguard-module-flag.ll
  llvm/test/CodeGen/WinCFGuard/cfguard-setjmp.ll
  llvm/test/CodeGen/X86/cfguard-checks.ll
  llvm/test/CodeGen/X86/cfguard-module-flag.ll

Index: llvm/test/CodeGen/X86/cfguard-module-flag.ll
===================================================================
--- llvm/test/CodeGen/X86/cfguard-module-flag.ll
+++ llvm/test/CodeGen/X86/cfguard-module-flag.ll
@@ -1,9 +1,7 @@
 
 ; RUN: llc < %s -mtriple=i686-pc-windows-msvc | FileCheck %s -check-prefix=X32
 ; RUN: llc < %s -mtriple=x86_64-pc-windows-msvc | FileCheck %s -check-prefix=X64
-
-; This test is disabled on Linux
-; UNSUPPORTED: linux
+; Control Flow Guard is currently only available on Windows
 
 ; Test that Control Flow Guard checks are not added in modules with the 
 ; cfguard=1 flag (emit tables but no checks).
Index: llvm/test/CodeGen/X86/cfguard-checks.ll
===================================================================
--- llvm/test/CodeGen/X86/cfguard-checks.ll
+++ llvm/test/CodeGen/X86/cfguard-checks.ll
@@ -1,8 +1,6 @@
 ; RUN: llc < %s -mtriple=i686-pc-windows-msvc | FileCheck %s -check-prefix=X32
 ; RUN: llc < %s -mtriple=x86_64-pc-windows-msvc | FileCheck %s -check-prefix=X64
-
-; This test is disabled on Linux
-; UNSUPPORTED: linux
+; Control Flow Guard is currently only available on Windows
 
 ; Test that Control Flow Guard checks are correctly added when required.
 
@@ -32,7 +30,8 @@
 attributes #0 = { nocf_check }
 
 
-; Test that Control Flow Guard checks are correctly added as single instructions even at -O0.
+; Test that Control Flow Guard checks are added even at -O0.
+; FIXME Ideally these checks should be added as a single call instruction, as in the optimized case.
 define i32 @func_optnone_cf() #1 {
 entry:
   %func_ptr = alloca i32 ()*, align 8
@@ -46,13 +45,15 @@
 	; X32: 	     leal  _target_func, %eax
 	; X32: 	     movl  %eax, (%esp)
 	; X32: 	     movl  (%esp), %ecx
-	; X32: 	     calll *___guard_check_icall_fptr
+	; X32: 	     movl ___guard_check_icall_fptr, %eax
+	; X32: 	     calll *%eax
 	; X32-NEXT:  calll *%ecx
 
   ; On x86_64, __guard_dispatch_icall_fptr tail calls the function, so there should be only one call instruction.
   ; X64-LABEL: func_optnone_cf
   ; X64:       leaq	target_func(%rip), %rax
-  ; X64:       callq *__guard_dispatch_icall_fptr(%rip)
+  ; X64:       movq __guard_dispatch_icall_fptr(%rip), %rcx
+  ; X64:       callq *%rcx
   ; X64-NOT:   callq
 }
 attributes #1 = { noinline optnone }
@@ -120,5 +121,61 @@
 declare void @h()
 
 
+; Test that Control Flow Guard preserves floating point arguments.
+declare double @target_func_doubles(double, double, double, double)
+
+define double @func_cf_doubles() {
+entry:
+  %func_ptr = alloca double (double, double, double, double)*, align 8
+  store double (double, double, double, double)* @target_func_doubles, double (double, double, double, double)** %func_ptr, align 8
+  %0 = load double (double, double, double, double)*, double (double, double, double, double)** %func_ptr, align 8
+  %1 = call double %0(double 1.000000e+00, double 2.000000e+00, double 3.000000e+00, double 4.000000e+00)
+  ret double %1
+
+  ; On i686, the call to __guard_check_icall_fptr should come immediately before the call to the target function.
+  ; X32-LABEL: func_cf_doubles
+  ; X32: 	     movl  $_target_func_doubles, %esi
+	; X32: 	     movl  $_target_func_doubles, %ecx
+	; X32: 	     calll *___guard_check_icall_fptr
+	; X32:       calll *%esi
+
+
+  ; On x86_64, __guard_dispatch_icall_fptr tail calls the function, so there should be only one call instruction.
+  ; X64-LABEL: func_cf_doubles
+  ; X64:       leaq	target_func_doubles(%rip), %rax
+  ; X64:       movsd __real@3ff0000000000000(%rip), %xmm0
+  ; X64:       movsd __real@4000000000000000(%rip), %xmm1
+  ; X64:       movsd __real@4008000000000000(%rip), %xmm2
+  ; X64:       movsd __real@4010000000000000(%rip), %xmm3
+  ; X64:       callq *__guard_dispatch_icall_fptr(%rip)
+  ; X64-NOT:   callq
+}
+
+
+; Test that Control Flow Guard checks are correctly added for tail calls.
+define i32 @func_cf_tail() {
+entry:
+  %func_ptr = alloca i32 ()*, align 8
+  store i32 ()* @target_func, i32 ()** %func_ptr, align 8
+  %0 = load i32 ()*, i32 ()** %func_ptr, align 8
+  %1 = musttail call i32 %0()
+  ret i32 %1
+
+  ; On i686, the call to __guard_check_icall_fptr should come immediately before the call to the target function.
+  ; X32-LABEL: func_cf_tail
+	; X32: 	     movl  $_target_func, %ecx
+	; X32: 	     calll *___guard_check_icall_fptr
+  ; X32:       movl $_target_func, %eax
+	; X32:       jmpl	*%eax                  # TAILCALL
+  ; X32-NOT:   calll
+
+  ; X64-LABEL: func_cf_tail
+  ; X64:       leaq	target_func(%rip), %rax
+  ; X64:       movq __guard_dispatch_icall_fptr(%rip), %rcx
+  ; X64:       rex64 jmpq *%rcx            # TAILCALL
+  ; X64-NOT:   callq
+}
+
+
 !llvm.module.flags = !{!0}
 !0 = !{i32 2, !"cfguard", i32 2}
\ No newline at end of file
Index: llvm/test/CodeGen/WinCFGuard/cfguard-setjmp.ll
===================================================================
--- llvm/test/CodeGen/WinCFGuard/cfguard-setjmp.ll
+++ llvm/test/CodeGen/WinCFGuard/cfguard-setjmp.ll
@@ -1,8 +1,5 @@
 ; RUN: llc < %s | FileCheck %s
 
-; This test is disabled on Linux
-; UNSUPPORTED: linux
-
 ; Test that longjmp targets have public labels and are included in the .gljmp section.
 
 %struct._SETJMP_FLOAT128 = type { [2 x i64] }
@@ -19,14 +16,21 @@
   %4 = call i32 @_setjmp(i8* bitcast ([16 x %struct._SETJMP_FLOAT128]* @buf1 to i8*), i8* %3) #2
 
   ; CHECK:      callq _setjmp
-  ; CHECK-NEXT: BB0_1:
+  ; CHECK-NEXT: $cfgsj_main0:
+
+  %5 = call i8* @llvm.frameaddress(i32 0)
+  %6 = call i32 @_setjmp(i8* bitcast ([16 x %struct._SETJMP_FLOAT128]* @buf1 to i8*), i8* %5) #3
+
+  ; CHECK:      callq _setjmp
+  ; CHECK-NEXT: $cfgsj_main1:
 
   store i32 1, i32* %2, align 4
-  %5 = load i32, i32* %2, align 4
-  ret i32 %5
+  %7 = load i32, i32* %2, align 4
+  ret i32 %7
 
   ; CHECK:      .section .gljmp$y,"dr"
-  ; CHECK-NEXT: .symidx BB0_1
+  ; CHECK-NEXT: .symidx $cfgsj_main0
+  ; CHECK-NEXT: .symidx $cfgsj_main1
 
 }
 
@@ -39,7 +43,8 @@
 attributes #0 = { noinline nounwind }
 attributes #1 = { nounwind readnone }
 attributes #2 = { returns_twice }
+attributes #3 = { returns_twice }
 
 
 !llvm.module.flags = !{!0}
 !0 = !{i32 2, !"cfguard", i32 2}
\ No newline at end of file
Index: llvm/test/CodeGen/ARM/cfguard-module-flag.ll
===================================================================
--- llvm/test/CodeGen/ARM/cfguard-module-flag.ll
+++ llvm/test/CodeGen/ARM/cfguard-module-flag.ll
@@ -1,8 +1,6 @@
 
 ; RUN: llc < %s -mtriple=arm-pc-windows-msvc | FileCheck %s
-
-; This test is disabled on Linux
-; UNSUPPORTED: linux
+; Control Flow Guard is currently only available on Windows
 
 ; Test that Control Flow Guard checks are not added in modules with the 
 ; cfguard=1 flag (emit tables but no checks).
Index: llvm/test/CodeGen/ARM/cfguard-checks.ll
===================================================================
--- llvm/test/CodeGen/ARM/cfguard-checks.ll
+++ llvm/test/CodeGen/ARM/cfguard-checks.ll
@@ -1,7 +1,5 @@
 ; RUN: llc < %s -mtriple=arm-pc-windows-msvc | FileCheck %s
-
-; This test is disabled on Linux
-; UNSUPPORTED: linux
+; Control Flow Guard is currently only available on Windows
 
 ; Test that Control Flow Guard checks are correctly added when required.
 
@@ -27,7 +25,7 @@
 attributes #0 = { nocf_check "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="cortex-a9" "target-features"="+armv7-a,+dsp,+fp16,+neon,+strict-align,+thumb-mode,+vfp3" "unsafe-fp-math"="false" "use-soft-float"="false"}
 
 
-; Test that Control Flow Guard checks are correctly added as single instructions even at -O0.
+; Test that Control Flow Guard checks are added even at -O0.
 define i32 @func_optnone_cf() #1 {
 entry:
   %func_ptr = alloca i32 ()*, align 8
Index: llvm/test/CodeGen/AArch64/cfguard-module-flag.ll
===================================================================
--- llvm/test/CodeGen/AArch64/cfguard-module-flag.ll
+++ llvm/test/CodeGen/AArch64/cfguard-module-flag.ll
@@ -1,8 +1,6 @@
 
 ; RUN: llc < %s -mtriple=aarch64-pc-windows-msvc | FileCheck %s
-
-; This test is disabled on Linux
-; UNSUPPORTED: linux
+; Control Flow Guard is currently only available on Windows
 
 ; Test that Control Flow Guard checks are not added in modules with the 
 ; cfguard=1 flag (emit tables but no checks).
Index: llvm/test/CodeGen/AArch64/cfguard-checks.ll
===================================================================
--- llvm/test/CodeGen/AArch64/cfguard-checks.ll
+++ llvm/test/CodeGen/AArch64/cfguard-checks.ll
@@ -1,7 +1,5 @@
 ; RUN: llc < %s -mtriple=aarch64-pc-windows-msvc | FileCheck %s
-
-; This test is disabled on Linux
-; UNSUPPORTED: linux
+; Control Flow Guard is currently only available on Windows
 
 ; Test that Control Flow Guard checks are correctly added when required.
 
@@ -27,7 +25,7 @@
 attributes #0 = { nocf_check }
 
 
-; Test that Control Flow Guard checks are correctly added as single instructions even at -O0.
+; Test that Control Flow Guard checks are added even at -O0.
 define i32 @func_optnone_cf() #1 {
 entry:
   %func_ptr = alloca i32 ()*, align 8
Index: llvm/test/Bitcode/operand-bundles-bc-analyzer.ll
===================================================================
--- llvm/test/Bitcode/operand-bundles-bc-analyzer.ll
+++ llvm/test/Bitcode/operand-bundles-bc-analyzer.ll
@@ -6,6 +6,7 @@
 ; CHECK-NEXT:    <OPERAND_BUNDLE_TAG
 ; CHECK-NEXT:    <OPERAND_BUNDLE_TAG
 ; CHECK-NEXT:    <OPERAND_BUNDLE_TAG
+; CHECK-NEXT:    <OPERAND_BUNDLE_TAG
 ; CHECK-NEXT:  </OPERAND_BUNDLE_TAGS_BLOCK
 
 ; CHECK:   <FUNCTION_BLOCK
Index: llvm/test/Bitcode/calling-conventions.3.2.ll
===================================================================
--- llvm/test/Bitcode/calling-conventions.3.2.ll
+++ llvm/test/Bitcode/calling-conventions.3.2.ll
@@ -29,9 +29,6 @@
 declare cfguard_checkcc void @cfguard_checkcc()
 ; CHECK: declare cfguard_checkcc void @cfguard_checkcc
 
-declare cfguard_dispatchcc void @cfguard_dispatchcc()
-; CHECK: declare cfguard_dispatchcc void @cfguard_dispatchcc
-
 declare x86_stdcallcc void @x86_stdcallcc()
 ; CHECK: declare x86_stdcallcc void @x86_stdcallcc 
 
@@ -107,12 +104,6 @@
 ret void
 }
 
-define void @call_cfguard_dispatchcc() {
-; CHECK: call cfguard_dispatchcc void @cfguard_dispatchcc
-call cfguard_dispatchcc void @cfguard_dispatchcc()
-ret void
-}
-
 define void @call_x86_stdcallcc() { 
 ; CHECK: call x86_stdcallcc void @x86_stdcallcc
   call x86_stdcallcc void @x86_stdcallcc()
Index: llvm/lib/Transforms/CFGuard/CFGuard.cpp
===================================================================
--- llvm/lib/Transforms/CFGuard/CFGuard.cpp
+++ llvm/lib/Transforms/CFGuard/CFGuard.cpp
@@ -17,7 +17,6 @@
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/IR/CallingConv.h"
-#include "llvm/IR/Function.h"
 #include "llvm/IR/Instruction.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/InitializePasses.h"
@@ -25,6 +24,8 @@
 
 using namespace llvm;
 
+using OperandBundleDef = OperandBundleDefT<Value *>;
+
 #define DEBUG_TYPE "cfguard"
 
 STATISTIC(CFGuardCounter, "Number of Control Flow Guard checks added");
@@ -33,23 +34,23 @@
 
 /// Adds Control Flow Guard (CFG) checks on indirect function calls/invokes.
 /// These checks ensure that the target address corresponds to the start of an
-/// address-taken function. Different mechanisms are used for specific
-/// architectures (e.g. X86_32 uses cf_check, X86_64 uses cf_dispatch).
-class CFGuard : public ModulePass {
+/// address-taken function. X86_64 targets use the CF_Dispatch mechanism. X86, 
+/// ARM, and AArch64 targets use the CF_Check machanism.
+class CFGuard : public FunctionPass {
 public:
   static char ID;
 
-  enum Mechanism { cf_check, cf_dispatch };
+  enum Mechanism { CF_Check, CF_Dispatch };
 
-  // Default constructor required for the INITIALIZE_PASS macro
-  CFGuard() : ModulePass(ID) {
+  // Default constructor required for the INITIALIZE_PASS macro.
+  CFGuard() : FunctionPass(ID) {
     initializeCFGuardPass(*PassRegistry::getPassRegistry());
-    // By default, use the guard check mechanism
-    GuardMechanism = cf_check;
+    // By default, use the guard check mechanism.
+    GuardMechanism = CF_Check;
   }
 
-  // Recommended constructor used to specify the type of guard mechanism
-  CFGuard(Mechanism Var) : ModulePass(ID) {
+  // Recommended constructor used to specify the type of guard mechanism.
+  CFGuard(Mechanism Var) : FunctionPass(ID) {
     initializeCFGuardPass(*PassRegistry::getPassRegistry());
     GuardMechanism = Var;
   }
@@ -121,8 +122,8 @@
   ///   %func_ptr = alloca i32 ()*, align 8
   ///   store i32 ()* @target_func, i32 ()** %func_ptr, align 8
   ///   %0 = load i32 ()*, i32 ()** %func_ptr, align 8
-  ///   %1 = load i32 (i32 ()*)*, i32 (i32 ()*)** @__guard_dispatch_icall_fptr
-  ///   %2 = call cfguard_dispatchcc i32 %1(i32 ()* %0)
+  ///   %1 = load i32 ()*, i32 ()** @__guard_dispatch_icall_fptr
+  ///   %2 = call i32 %1() [ "cfguardtarget"(i32 ()* %0) ]
   /// \endcode
   ///
   /// For example, the following X86_64 assembly code:
@@ -140,10 +141,13 @@
   /// \param CB indirect call to instrument.
   void insertCFGuardDispatch(CallBase *CB);
 
-  bool runOnModule(Module &M) override;
+  bool doInitialization(Module &M) override;
+  bool runOnFunction(Function &F) override;
 
 private:
-  Mechanism GuardMechanism = cf_check;
+  // Only add checks if the module has the cfguard=2 flag.
+  int cfguard_module_flag = 0;
+  Mechanism GuardMechanism = CF_Check;
   FunctionType *GuardFnType = nullptr;
   PointerType *GuardFnPtrType = nullptr;
   Constant *GuardFnGlobal = nullptr;
@@ -161,7 +165,7 @@
   IRBuilder<> B(CB);
   Value *CalledOperand = CB->getCalledOperand();
 
-  // Load the global symbol as a pointer to the check function
+  // Load the global symbol as a pointer to the check function.
   LoadInst *GuardCheckLoad = B.CreateLoad(GuardFnPtrType, GuardFnGlobal);
 
   // Create new call instruction. The CFGuard check should always be a call,
@@ -171,7 +175,7 @@
                    {B.CreateBitCast(CalledOperand, B.getInt8PtrTy())});
 
   // Ensure that the first argument is passed in the correct register
-  // (e.g. ECX on 32-bit X86 targets)
+  // (e.g. ECX on 32-bit X86 targets).
   GuardCheck->setCallingConv(CallingConv::CFGuard_Check);
 }
 
@@ -184,160 +188,121 @@
 
   IRBuilder<> B(CB);
   Value *CalledOperand = CB->getCalledOperand();
-
   Type *CalledOperandType = CalledOperand->getType();
-  FunctionType *CalledFunctionType = cast<FunctionType>(
-      cast<PointerType>(CalledOperandType)->getElementType());
-
-  // Set up the new function type
-  SmallVector<Type *, 8> ArgTypes;
-  ArgTypes.push_back(CalledOperandType);
-  ArgTypes.append(CalledFunctionType->param_begin(),
-                  CalledFunctionType->param_end());
-  FunctionType *GuardDispatchType =
-      FunctionType::get(CalledFunctionType->getReturnType(), ArgTypes,
-                        CalledFunctionType->isVarArg());
-  PointerType *GuardDispatchPtrType = PointerType::get(GuardDispatchType, 0U);
-
-  // Get or insert the global symbol "__guard_dispatch_icall_fptr"
-  Constant *GuardDispatchGlobal = CB->getModule()->getOrInsertGlobal(
-      "__guard_dispatch_icall_fptr", GuardDispatchPtrType);
-
-  // Load the global symbol as a pointer to a function of the new type
+
+  // Cast the guard dispatch global to the type of the called operand.
+  PointerType *PTy = PointerType::get(CalledOperandType, 0);
+  if (GuardFnGlobal->getType() != PTy)
+    GuardFnGlobal = ConstantExpr::getBitCast(GuardFnGlobal, PTy);
+
+  // Load the global as a pointer to a function of the same type.
   LoadInst *GuardDispatchLoad =
-      B.CreateLoad(GuardDispatchPtrType, GuardDispatchGlobal);
-
-  // Prepare the arguments for the new call
-  SmallVector<Value *, 8> GuardDispatchArgs;
-  GuardDispatchArgs.push_back(CalledOperand);
-  GuardDispatchArgs.append(CB->arg_begin(), CB->arg_end());
-
-  // Depending on the type of the original instruction, create new
-  // call/invoke/callbr instruction
-  CallBase *GuardDispatch;
-  if (CallInst::classof(CB)) {
-    GuardDispatch =
-        B.CreateCall(GuardDispatchType, GuardDispatchLoad, GuardDispatchArgs);
-  } else if (InvokeInst::classof(CB)) {
-    InvokeInst *CBInvoke = cast<InvokeInst>(CB);
-    GuardDispatch = B.CreateInvoke(
-        GuardDispatchType, GuardDispatchLoad, CBInvoke->getNormalDest(),
-        CBInvoke->getUnwindDest(), GuardDispatchArgs);
+      B.CreateLoad(CalledOperandType, GuardFnGlobal);
+
+  // Add the original call target as a cfguardtarget operand bundle.
+  SmallVector<llvm::OperandBundleDef, 1> Bundles;
+  CB->getOperandBundlesAsDefs(Bundles);
+  Bundles.emplace_back("cfguardtarget", CalledOperand);
+  
+  // Create a copy of the call/invoke instruction and add the new bundle.
+  CallBase *NewCB;
+  if (CallInst* CI = dyn_cast<CallInst>(CB)) {
+    NewCB = CallInst::Create(CI, Bundles, CB);
   } else {
-    assert(CallBrInst::classof(CB) && "Unsupported indirect call instruction.");
-    CallBrInst *CBCallBr = cast<CallBrInst>(CB);
-    GuardDispatch = B.CreateCallBr(
-        GuardDispatchType, GuardDispatchLoad, CBCallBr->getDefaultDest(),
-        CBCallBr->getIndirectDests(), GuardDispatchArgs);
+    assert(isa<InvokeInst>(CB) && "Unknown indirect call type");
+    InvokeInst* II = cast<InvokeInst>(CB);
+    NewCB = llvm::InvokeInst::Create(II, Bundles, CB);
   }
 
-  assert(GuardDispatch->getNumArgOperands() == CB->getNumArgOperands() + 1 &&
-         "Incorrect number of arguments!");
-
-  // Create new attribute list and copy function attributes, return attributes,
-  // and parameter attributes (shifting parameter attributes one to the right).
-  AttributeList OldAttrs = CB->getAttributes();
-  AttributeList NewAttrs = GuardDispatch->getAttributes();
-  NewAttrs.addAttributes(CB->getContext(), AttributeList::FunctionIndex,
-                         CB->getAttributes().getFnAttributes());
-  NewAttrs.addAttributes(CB->getContext(), AttributeList::ReturnIndex,
-                         CB->getAttributes().getRetAttributes());
-  for (unsigned int i = 0; i < CB->getNumArgOperands(); i++) {
-    NewAttrs.addParamAttributes(CB->getContext(), i + 1,
-                                OldAttrs.getParamAttributes(i));
-  }
-  GuardDispatch->setAttributes(NewAttrs);
-
-  // Use a custom calling convention to pass the address of the original
-  // function as the first argument to the guard dispatch call in the correct
-  // register (i.e. RAX on 64-bit X86 targets)
-  GuardDispatch->setCallingConv(CallingConv::CFGuard_Dispatch);
-
-  // Replace all uses of the original call/invoke with the new dispatch
-  CB->replaceAllUsesWith(GuardDispatch);
+  // Change the target of the call to be the guard dispatch function.
+  NewCB->setCalledOperand(GuardDispatchLoad);
+  
+  // Replace the original call/invoke with the new instruction.
+  CB->replaceAllUsesWith(NewCB);
 
-  // Delete the original call/invoke
+  // Delete the original call/invoke.
   CB->eraseFromParent();
 }
 
-bool CFGuard::runOnModule(Module &M) {
+bool CFGuard::doInitialization(Module &M) {
 
-  // Only add checks if the module has the cfguard=2 flag
-  int cfguard_flag = 0;
+  // Check if this module has the cfguard flag and read its value.
   if (auto *MD =
           mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("cfguard")))
-    cfguard_flag = MD->getZExtValue();
-  if (cfguard_flag != 2)
+    cfguard_module_flag = MD->getZExtValue();
+
+  // Skip modules for which CFGuard checks have been disabled.
+  if (cfguard_module_flag != 2)
     return false;
 
-  // The guard check function has the same type for every indirect call in the
-  // module, so this can be initialized once per module.
-  if (GuardMechanism == cf_check) {
-    GuardFnType =
-        FunctionType::get(Type::getVoidTy(M.getContext()),
+  // Set up prototypes for the guard check and dispatch functions.
+  GuardFnType = FunctionType::get(Type::getVoidTy(M.getContext()),
                           {Type::getInt8PtrTy(M.getContext())}, false);
-    GuardFnPtrType = PointerType::get(GuardFnType, 0);
-    GuardFnGlobal =
-        M.getOrInsertGlobal("__guard_check_icall_fptr", GuardFnPtrType);
-  }
-
-  for (Function &F : M) {
+  GuardFnPtrType = PointerType::get(GuardFnType, 0);
 
-    bool ChecksAdded = false;
-
-    // Skip functions for which CFG checks have been disabled
-    if (F.hasFnAttribute(Attribute::NoCfCheck))
-      continue;
+  // Get or insert the guard check or dispatch global symbols.
+  if (GuardMechanism == CF_Check) {
+    GuardFnGlobal = M.getOrInsertGlobal(
+      "__guard_check_icall_fptr", GuardFnPtrType);
+  } else {
+    assert(GuardMechanism == CF_Dispatch && "Invalid CFGuard mechanism");
+    GuardFnGlobal = M.getOrInsertGlobal(
+      "__guard_dispatch_icall_fptr", GuardFnPtrType);  
+  }
 
-    // Iterate over the instructions to find all indirect call/invoke/callbr
-    // instructions. Make a separate list of pointers to indirect
-    // call/invoke/callbr instructions because the original instructions will be
-    // deleted as the checks are added
-    SmallVector<CallBase *, 8> IndirectCalls;
-    for (BasicBlock &BB : F.getBasicBlockList()) {
-      for (Instruction &I : BB.getInstList()) {
+  return true;
+}
 
-        auto *CB = dyn_cast<CallBase>(&I);
-        if (!CB) continue;
+bool CFGuard::runOnFunction(Function &F) {
 
-        if (CB->isIndirectCall()) {
-          IndirectCalls.push_back(CB);
-          ChecksAdded = true;
-          CFGuardCounter++;
-        }
+  // Skip modules and functions for which CFGuard checks have been disabled.
+  if (cfguard_module_flag != 2 || F.hasFnAttribute(Attribute::NoCfCheck))
+    return false;
 
+  SmallVector<CallBase *, 8> IndirectCalls;
+
+  // Iterate over the instructions to find all indirect call/invoke/callbr
+  // instructions. Make a separate list of pointers to indirect
+  // call/invoke/callbr instructions because the original instructions will be
+  // deleted as the checks are added.
+  for (BasicBlock &BB : F.getBasicBlockList()) {
+    for (Instruction &I : BB.getInstList()) {
+      auto *CB = dyn_cast<CallBase>(&I);
+      if (CB && CB->isIndirectCall()) {
+        IndirectCalls.push_back(CB);
+        CFGuardCounter++;
       }
     }
+  }
 
-    // For each indirect call/invoke/callbr, add the appropriate dispatch or
-    // check
-    if (GuardMechanism == cf_dispatch) {
-      for (CallBase *CB : IndirectCalls) {
-        insertCFGuardDispatch(CB);
-      }
-    } else {
-      for (CallBase *CB : IndirectCalls) {
-        insertCFGuardCheck(CB);
-      }
-    }
+  // If no checks are needed, return early and add this attribute to indicate
+  // that subsequent CFGuard passes can skip this function.     
+  if (IndirectCalls.empty()) {
+    F.addFnAttr(Attribute::NoCfCheck);
+    return false;
+  }
 
-    // If no checks were added, add this attribute to indicate that subsequent
-    // CFGuard passes do not need to consider this function
-    if (!ChecksAdded)
-      F.addFnAttr(Attribute::NoCfCheck);
+  // For each indirect call/invoke, add the appropriate dispatch or check.
+  if (GuardMechanism == CF_Dispatch) {
+    for (CallBase *CB : IndirectCalls) {
+      insertCFGuardDispatch(CB);
+    }
+  } else {
+    for (CallBase *CB : IndirectCalls) {
+      insertCFGuardCheck(CB);
+    }
   }
 
   return true;
 }
 
-
 char CFGuard::ID = 0;
 INITIALIZE_PASS(CFGuard, "CFGuard", "CFGuard", false, false)
 
-ModulePass *llvm::createCFGuardCheckPass() {
-  return new CFGuard(CFGuard::cf_check);
+FunctionPass *llvm::createCFGuardCheckPass() {
+  return new CFGuard(CFGuard::CF_Check);
 }
 
-ModulePass *llvm::createCFGuardDispatchPass() {
-  return new CFGuard(CFGuard::cf_dispatch);
+FunctionPass *llvm::createCFGuardDispatchPass() {
+  return new CFGuard(CFGuard::CF_Dispatch);
 }
\ No newline at end of file
Index: llvm/lib/Target/X86/X86TargetMachine.cpp
===================================================================
--- llvm/lib/Target/X86/X86TargetMachine.cpp
+++ llvm/lib/Target/X86/X86TargetMachine.cpp
@@ -420,10 +420,9 @@
   // feature enabled.
   addPass(createIndirectBrExpandPass());
 
-  // Add Control Flow Guard checks
+  // Add Control Flow Guard checks.
   const Triple &TT = TM->getTargetTriple();
   if (TT.isOSWindows()) {
-    //addPass(createCFGuardLongjmpFPass());
     if(TT.getArch() == Triple::x86_64) {
       addPass(createCFGuardDispatchPass());
     } else {
@@ -495,11 +494,6 @@
   addPass(createX86SpeculativeLoadHardeningPass());
   addPass(createX86FlagsCopyLoweringPass());
   addPass(createX86WinAllocaExpander());
-  if (TM->getTargetTriple().isOSWindows())
-    // Fixup Control Flow Guard checks.
-    addPass(createX86FixupCFGuardPass());
-    // Emit longjmp targets for Control Flow Guard
-    //addPass(createCFGuardLongjmpPass());
 }
 void X86PassConfig::addMachineSSAOptimization() {
   addPass(createX86DomainReassignmentPass());
@@ -544,7 +538,7 @@
       (!TT.isOSWindows() ||
        MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI))
     addPass(createCFIInstrInserter());
-  // Identify valid longjmp targets for Windows Control Flow Guard
+  // Identify valid longjmp targets for Windows Control Flow Guard.
   if (TT.isOSWindows())
     addPass(createCFGuardLongjmpPass());
 }
Index: llvm/lib/Target/X86/X86Subtarget.h
===================================================================
--- llvm/lib/Target/X86/X86Subtarget.h
+++ llvm/lib/Target/X86/X86Subtarget.h
@@ -815,7 +815,6 @@
     case CallingConv::X86_ThisCall:
     case CallingConv::X86_VectorCall:
     case CallingConv::Intel_OCL_BI:
-    case CallingConv::CFGuard_Dispatch:
       return isTargetWin64();
     // This convention allows using the Win64 convention on other targets.
     case CallingConv::Win64:
Index: llvm/lib/Target/X86/X86RegisterInfo.cpp
===================================================================
--- llvm/lib/Target/X86/X86RegisterInfo.cpp
+++ llvm/lib/Target/X86/X86RegisterInfo.cpp
@@ -353,14 +353,9 @@
     if (!HasSSE)
       return CSR_Win64_NoSSE_SaveList;
     return CSR_Win64_SaveList;
-  case CallingConv::CFGuard_Dispatch:
-    assert(IsWin64 && "CFGuard dispatch mechanism only used on X86_64");
-    if (!HasSSE)
-      return CSR_Win64_NoSSE_SaveList;
-    return CSR_Win64_SaveList;
-  case CallingConv::X86_64_SysV:
-    if (CallsEHReturn)
-      return CSR_64EHRet_SaveList;
+  case CallingConv::X86_64_SysV:
+    if (CallsEHReturn)
+      return CSR_64EHRet_SaveList;
     return CSR_64_SaveList;
   case CallingConv::X86_INTR:
     if (Is64Bit) {
@@ -474,9 +469,6 @@
     break;
   case CallingConv::Win64:
     return CSR_Win64_RegMask;
-  case CallingConv::CFGuard_Dispatch:
-    assert(IsWin64 && "CFGuard dispatch mechanism only used on X86_64");
-    return CSR_Win64_RegMask;
   case CallingConv::X86_64_SysV:
     return CSR_64_RegMask;
   case CallingConv::X86_INTR:
Index: llvm/lib/Target/X86/X86FixupCFGuard.cpp
===================================================================
--- llvm/lib/Target/X86/X86FixupCFGuard.cpp
+++ /dev/null
@@ -1,218 +0,0 @@
-//===-- X86FixupCFGuard.cpp - Control Flow Guard checks ---------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// This file contains the machine instruction transform to fixup the Control
-/// Flow Guard checks inserted by /X86CFGuard.cpp. This pass searches
-/// for such cases and replaces the pair of instructions with a single
-/// call/invoke. For example:
-///
-/// For 32-bit targets, the following assembly code:
-/// \code
-///   movl   ___guard_check_icall_fptr, %eax
-///   calll  *%eax
-/// \endcode
-///
-/// is transformed to:
-/// \code
-///   calll  *___guard_check_icall_fptr
-/// \endcode
-///
-/// For 64-bit targets, the following assembly code:
-/// \code
-///   movq   __guard_dispatch_icall_fptr(%rip), %rcx
-///   callq  *%rcx
-/// \endcode
-///
-/// is transformed to:
-/// \code
-///   callq  *__guard_dispatch_icall_fptr(%rip)
-/// \endcode
-///
-//===----------------------------------------------------------------------===//
-
-#include "X86InstrInfo.h"
-#include "X86Subtarget.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/CodeGen/MachineOperand.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-
-using namespace llvm;
-
-#define DEBUG_TYPE "x86-fixup-cfguard"
-
-STATISTIC(X86CFGuardFixed, "Number of X86 Control Flow Guard checks fixed");
-
-namespace {
-
-/// MachineFunction pass to fix x86 Control Flow Guard checks that have been
-/// generated as separate load and call/invoke instructions.
-class X86FixupCFGuard : public MachineFunctionPass {
-public:
-  static char ID;
-
-  X86FixupCFGuard() : MachineFunctionPass(ID) {}
-
-  StringRef getPassName() const override {
-    return "X86 Fixup Control Flow Guard";
-  }
-
-  /// Check if an instruction is loading a Guard function pointer by comparing
-  /// the instruction's global value to our cached pointers to the Guard
-  /// globals.
-  bool isGuardLoad(MachineInstr &MI);
-
-  /// Given a guard load instruction, find all subsequent calls/invokes of the
-  /// loaded value in the basic block and replace each of these load-call/invoke
-  /// pairs with a single call/invoke. This function returns true if any
-  /// instructions were modified.
-  bool fixupGuardLoad(MachineInstr &LoadMI, const X86InstrInfo *TII);
-
-  bool runOnMachineFunction(MachineFunction &MF) override;
-
-private:
-  const GlobalVariable *GuardCheckGlobal = nullptr;
-  const GlobalVariable *GuardDispatchGlobal = nullptr;
-};
-
-} // end anonymous namespace
-
-FunctionPass *llvm::createX86FixupCFGuardPass() {
-  return new X86FixupCFGuard();
-}
-
-char X86FixupCFGuard::ID = 0;
-
-bool X86FixupCFGuard::isGuardLoad(MachineInstr &MI) {
-  return (MI.getOpcode() == X86::MOV32rm && MI.getNumOperands() > 4 &&
-          MI.getOperand(4).isGlobal() &&
-          MI.getOperand(4).getGlobal() == GuardCheckGlobal) ||
-         (MI.getOpcode() == X86::MOV64rm && MI.getNumOperands() > 4 &&
-          MI.getOperand(4).isGlobal() &&
-          MI.getOperand(4).getGlobal() == GuardDispatchGlobal);
-}
-
-bool X86FixupCFGuard::fixupGuardLoad(MachineInstr &LoadMI,
-                                     const X86InstrInfo *TII) {
-
-  // Select the correct opcodes based on the load instruction
-  unsigned int OldCallOpcode, NewCallOpcode;
-  if (LoadMI.getOpcode() == X86::MOV32rm) {
-    OldCallOpcode = X86::CALL32r;
-    NewCallOpcode = X86::CALL32m;
-  } else if (LoadMI.getOpcode() == X86::MOV64rm) {
-    OldCallOpcode = X86::CALL64r;
-    NewCallOpcode = X86::CALL64m;
-  } else {
-    // Not a supported load instruction
-    return false;
-  }
-
-  // List of call/invoke machine instructions to erase
-  SmallVector<MachineInstr *, 2> MIsToErase;
-
-  // Store the register into which the guard function pointer was loaded
-  unsigned int LoadReg = LoadMI.getOperand(0).getReg();
-  assert(Register::isPhysicalRegister(LoadReg) == false &&
-         "X86CFGuardFixup pass must be run before register allocation.");
-
-  // Get an iterator starting from the load instruction
-  MachineBasicBlock *MBB = LoadMI.getParent();
-  MachineBasicBlock::instr_iterator MIIter = LoadMI.getIterator();
-
-  // Iterate through the remaining instructions in the basic block after the
-  // load instruction
-  for (auto I = LoadMI.getIterator(), E = MBB->instr_end(); I != E; ++I) {
-    MachineInstr &MI = cast<MachineInstr>(*I);
-
-    // Check if the instruction is a call/invoke through the loaded register
-    if (MI.getOpcode() == OldCallOpcode &&
-        MI.getOperand(0).getReg() == LoadReg) {
-
-      // Add new call/invoke instruction with same external symbol as preceding
-      // load. Omit operand 0 of the load instruction (destination register) and
-      // shift other operands one to the left.
-      MachineInstrBuilder B =
-          BuildMI(*MBB, MI, MI.getDebugLoc(), TII->get(NewCallOpcode))
-              .add(LoadMI.getOperand(1))
-              .add(LoadMI.getOperand(2))
-              .add(LoadMI.getOperand(3))
-              .add(LoadMI.getOperand(4))
-              .add(LoadMI.getOperand(5));
-
-      // Copy implicit operands from the original call/invoke. This also copies
-      // the register mask from the original call/invoke.
-      B.copyImplicitOps(MI);
-
-      // Mark original call/invoke instruction to be erased
-      MIsToErase.push_back(&MI);
-
-      // Increment counter of guard calls/invokes fixed
-      X86CFGuardFixed++;
-    }
-  }
-
-  // Instructions have not been changed
-  if (MIsToErase.empty())
-    return false;
-
-  // Erase all marked call/invoke instructions
-  for (MachineInstr *MI : MIsToErase) {
-    MI->eraseFromParent();
-  }
-
-  // Instructions have been changed
-  return true;
-}
-
-bool X86FixupCFGuard::runOnMachineFunction(MachineFunction &MF) {
-
-  // Skip functions that should not have CF checks
-  if (MF.getFunction().hasFnAttribute(Attribute::NoCfCheck))
-    return false;
-
-  // Look up the guard global variables from the parent module
-  GuardCheckGlobal =
-      MF.getFunction().getParent()->getNamedGlobal("__guard_check_icall_fptr");
-  GuardDispatchGlobal = MF.getFunction().getParent()->getNamedGlobal(
-      "__guard_dispatch_icall_fptr");
-
-  // Skip functions that do not contain either of the guard globals
-  if (!GuardCheckGlobal && !GuardDispatchGlobal)
-    return false;
-
-  const X86Subtarget &STI = MF.getSubtarget<X86Subtarget>();
-  const X86InstrInfo *TII = STI.getInstrInfo();
-
-  SmallVector<MachineInstr *, 16> GuardLoads;
-
-  for (MachineBasicBlock &MBB : MF) {
-    for (MachineInstr &MI : MBB) {
-      if (isGuardLoad(MI))
-        GuardLoads.push_back(&MI);
-    }
-  }
-
-  if (GuardLoads.empty())
-    return false;
-
-  for (MachineInstr *LoadMI : GuardLoads) {
-    fixupGuardLoad(*LoadMI, TII);
-
-    assert(MF.getRegInfo().use_empty(LoadMI->getOperand(0).getReg()) &&
-           "Register containing guard function pointer is still in use.");
-
-    LoadMI->eraseFromParent();
-  }
-
-  return true;
-}
\ No newline at end of file
Index: llvm/lib/Target/X86/X86FastISel.cpp
===================================================================
--- llvm/lib/Target/X86/X86FastISel.cpp
+++ llvm/lib/Target/X86/X86FastISel.cpp
@@ -1164,7 +1164,6 @@
       CC != CallingConv::X86_StdCall &&
       CC != CallingConv::X86_ThisCall &&
       CC != CallingConv::X86_64_SysV &&
-      CC != CallingConv::CFGuard_Dispatch &&
       CC != CallingConv::Win64)
     return false;
 
@@ -3217,7 +3216,6 @@
   case CallingConv::Win64:
   case CallingConv::X86_64_SysV:
   case CallingConv::CFGuard_Check:
-  case CallingConv::CFGuard_Dispatch:
     break;
   }
 
Index: llvm/lib/Target/X86/X86CallingConv.td
===================================================================
--- llvm/lib/Target/X86/X86CallingConv.td
+++ llvm/lib/Target/X86/X86CallingConv.td
@@ -457,7 +457,6 @@
 
   // Handle explicit CC selection
   CCIfCC<"CallingConv::Win64", CCDelegateTo<RetCC_X86_Win64_C>>,
-  CCIfCC<"CallingConv::CFGuard_Dispatch", CCDelegateTo<RetCC_X86_Win64_C>>,
   CCIfCC<"CallingConv::X86_64_SysV", CCDelegateTo<RetCC_X86_64_C>>,
 
   // Handle Vectorcall CC
@@ -607,6 +606,9 @@
   // A SwiftError is passed in R12.
   CCIfSwiftError<CCIfType<[i64], CCAssignToReg<[R12]>>>,
 
+  // The 'CFGuardTarget' parameter, if any, is passed in RAX.
+  CCIfCFGuardTarget<CCAssignToReg<[RAX]>>,
+
   // 128 bit vectors are passed by pointer
   CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], CCPassIndirect<i64>>,
 
@@ -650,14 +652,6 @@
   CCIfType<[i8, i16, i32, i64, f32, f64], CCAssignToStack<8, 8>>
 ]>;
 
-def CC_X86_Win64_CFGuard_Dispatch : CallingConv<[
-  // The function address (i.e. first integer argument) is passed in RAX
-  CCIfType<[i64], CCAssignToReg<[RAX]>>,
-
-  // Otherwise, same as everything else.
-  CCDelegateTo<CC_X86_Win64_C>
-]>;
-
 def CC_X86_Win64_VectorCall : CallingConv<[
   CCCustom<"CC_X86_64_VectorCall">,
 
@@ -1032,7 +1026,6 @@
   CCIfCC<"CallingConv::WebKit_JS", CCDelegateTo<CC_X86_64_WebKit_JS>>,
   CCIfCC<"CallingConv::AnyReg", CCDelegateTo<CC_X86_64_AnyReg>>,
   CCIfCC<"CallingConv::Win64", CCDelegateTo<CC_X86_Win64_C>>,
-  CCIfCC<"CallingConv::CFGuard_Dispatch", CCDelegateTo<CC_X86_Win64_CFGuard_Dispatch>>,
   CCIfCC<"CallingConv::X86_64_SysV", CCDelegateTo<CC_X86_64_C>>,
   CCIfCC<"CallingConv::X86_VectorCall", CCDelegateTo<CC_X86_Win64_VectorCall>>,
   CCIfCC<"CallingConv::HHVM", CCDelegateTo<CC_X86_64_HHVM>>,
Index: llvm/lib/Target/X86/X86.h
===================================================================
--- llvm/lib/Target/X86/X86.h
+++ llvm/lib/Target/X86/X86.h
@@ -123,10 +123,6 @@
 /// This pass applies profiling information to insert cache prefetches.
 FunctionPass *createX86InsertPrefetchPass();
 
-/// This pass fixes up Control Flow Guard checks by merging a load and 
-/// subsequent call into a single call instruction. See X86FixupCFGuard.cpp
-FunctionPass *createX86FixupCFGuardPass();
-
 InstructionSelector *createX86InstructionSelector(const X86TargetMachine &TM,
                                                   X86Subtarget &,
                                                   X86RegisterBankInfo &);
@@ -147,7 +143,6 @@
 void initializeX86ExecutionDomainFixPass(PassRegistry &);
 void initializeX86FlagsCopyLoweringPassPass(PassRegistry &);
 void initializeX86SpeculativeLoadHardeningPassPass(PassRegistry &);
-void initializeX86CFGuardPass(PassRegistry &);
 
 } // End llvm namespace
 
Index: llvm/lib/Target/X86/CMakeLists.txt
===================================================================
--- llvm/lib/Target/X86/CMakeLists.txt
+++ llvm/lib/Target/X86/CMakeLists.txt
@@ -33,7 +33,6 @@
   X86ExpandPseudo.cpp
   X86FastISel.cpp
   X86FixupBWInsts.cpp
-  X86FixupCFGuard.cpp
   X86FixupLEAs.cpp
   X86AvoidStoreForwardingBlocks.cpp
   X86FixupSetCC.cpp
Index: llvm/lib/Target/ARM/ARMTargetMachine.cpp
===================================================================
--- llvm/lib/Target/ARM/ARMTargetMachine.cpp
+++ llvm/lib/Target/ARM/ARMTargetMachine.cpp
@@ -421,8 +421,8 @@
   if (TM->getOptLevel() != CodeGenOpt::None)
     addPass(createInterleavedAccessPass());
 
-  // Add Control Flow Guard checks
-  if (TM->getTargetTriple().isOSWindows())
+  // Add Control Flow Guard checks.
+  if (TM->getTargetTriple().isOSWindows())
     addPass(createCFGuardCheckPass());
 }
 
Index: llvm/lib/Target/ARM/ARMISelLowering.cpp
===================================================================
--- llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -1798,7 +1798,6 @@
 ARMTargetLowering::getEffectiveCallingConv(CallingConv::ID CC,
                                            bool isVarArg) const {
   switch (CC) {
-  case CallingConv::CFGuard_Dispatch:
   default:
     report_fatal_error("Unsupported calling convention");
   case CallingConv::ARM_AAPCS:
Index: llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
+++ llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
@@ -451,7 +451,7 @@
 
   addPass(createAArch64StackTaggingPass());
   
-  // Add Control Flow Guard checks
+  // Add Control Flow Guard checks.
   if (TM->getTargetTriple().isOSWindows())
     addPass(createCFGuardCheckPass());
 }
Index: llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -3048,7 +3048,6 @@
 CCAssignFn *AArch64TargetLowering::CCAssignFnForCall(CallingConv::ID CC,
                                                      bool IsVarArg) const {
   switch (CC) {
-  case CallingConv::CFGuard_Dispatch:
   default:
     report_fatal_error("Unsupported calling convention.");
   case CallingConv::WebKit_JS:
Index: llvm/lib/IR/Verifier.cpp
===================================================================
--- llvm/lib/IR/Verifier.cpp
+++ llvm/lib/IR/Verifier.cpp
@@ -2958,10 +2958,10 @@
     if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID())
       visitIntrinsicCall(ID, Call);
 
-  // Verify that a callsite has at most one "deopt", at most one "funclet" and
-  // at most one "gc-transition" operand bundle.
+  // Verify that a callsite has at most one "deopt", at most one "funclet", at
+  // most one "gc-transition", and at most one "cfguardtarget" operand bundle.
   bool FoundDeoptBundle = false, FoundFuncletBundle = false,
-       FoundGCTransitionBundle = false;
+       FoundGCTransitionBundle = false, FoundCFGuardTargetBundle = false;
   for (unsigned i = 0, e = Call.getNumOperandBundles(); i < e; ++i) {
     OperandBundleUse BU = Call.getOperandBundleAt(i);
     uint32_t Tag = BU.getTagID();
@@ -2980,6 +2980,12 @@
       Assert(isa<FuncletPadInst>(BU.Inputs.front()),
              "Funclet bundle operands should correspond to a FuncletPadInst",
              Call);
+    } else if (Tag == LLVMContext::OB_cfguardtarget) {
+      Assert(!FoundCFGuardTargetBundle, 
+             "Multiple CFGuardTarget operand bundles", Call);
+      FoundCFGuardTargetBundle = true;
+      Assert(BU.Inputs.size() == 1,
+             "Expected exactly one cfguardtarget bundle operand", Call);
     }
   }
 
Index: llvm/lib/IR/LLVMContext.cpp
===================================================================
--- llvm/lib/IR/LLVMContext.cpp
+++ llvm/lib/IR/LLVMContext.cpp
@@ -62,6 +62,11 @@
          "gc-transition operand bundle id drifted!");
   (void)GCTransitionEntry;
 
+  auto *CFGuardTargetEntry = pImpl->getOrInsertBundleTag("cfguardtarget");
+  assert(CFGuardTargetEntry->second == LLVMContext::OB_cfguardtarget &&
+         "cfguardtarget operand bundle id drifted!");
+  (void)CFGuardTargetEntry;
+
   SyncScope::ID SingleThreadSSID =
       pImpl->getOrInsertSyncScopeID("singlethread");
   assert(SingleThreadSSID == SyncScope::SingleThread &&
Index: llvm/lib/IR/AsmWriter.cpp
===================================================================
--- llvm/lib/IR/AsmWriter.cpp
+++ llvm/lib/IR/AsmWriter.cpp
@@ -353,7 +353,6 @@
   case CallingConv::CXX_FAST_TLS:  Out << "cxx_fast_tlscc"; break;
   case CallingConv::GHC:           Out << "ghccc"; break;
   case CallingConv::CFGuard_Check: Out << "cfguard_checkcc"; break;
-  case CallingConv::CFGuard_Dispatch: Out << "cfguard_dispatchcc"; break;
   case CallingConv::X86_StdCall:   Out << "x86_stdcallcc"; break;
   case CallingConv::X86_FastCall:  Out << "x86_fastcallcc"; break;
   case CallingConv::X86_ThisCall:  Out << "x86_thiscallcc"; break;
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===================================================================
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -2741,7 +2741,7 @@
   // Deopt bundles are lowered in LowerCallSiteWithDeoptBundle, and we don't
   // have to do anything here to lower funclet bundles.
   assert(!I.hasOperandBundlesOtherThan(
-             {LLVMContext::OB_deopt, LLVMContext::OB_funclet}) &&
+             {LLVMContext::OB_deopt, LLVMContext::OB_funclet, LLVMContext::OB_cfguardtarget}) &&
          "Cannot lower invokes with arbitrary operand bundles yet!");
 
   const Value *Callee(I.getCalledValue());
@@ -7100,6 +7100,18 @@
       isTailCall = false;
   }
 
+  // If call site has a cfguardtarget operand bundle, create and add an 
+  // additional ArgListEntry. 
+  if (auto Bundle = CS.getOperandBundle(LLVMContext::OB_cfguardtarget)) {
+    TargetLowering::ArgListEntry Entry;
+    Value *V = Bundle->Inputs[0];
+    SDValue ArgNode = getValue(V);
+    Entry.Node = ArgNode; 
+    Entry.Ty = V->getType();
+    Entry.IsCFGuardTarget = true;
+    Args.push_back(Entry);
+  }
+
   // Check if target-independent constraints permit a tail call here.
   // Target-dependent constraints are checked within TLI->LowerCallTo.
   if (isTailCall && !isInTailCallPosition(CS, DAG.getTarget()))
@@ -7641,8 +7653,9 @@
 
   // Deopt bundles are lowered in LowerCallSiteWithDeoptBundle, and we don't
   // have to do anything here to lower funclet bundles.
+  // CFGuardTarget bundles are lowered in LowerCallTo.
   assert(!I.hasOperandBundlesOtherThan(
-             {LLVMContext::OB_deopt, LLVMContext::OB_funclet}) &&
+             {LLVMContext::OB_deopt, LLVMContext::OB_funclet, LLVMContext::OB_cfguardtarget}) &&
          "Cannot lower calls with arbitrary operand bundles!");
 
   SDValue Callee = getValue(I.getCalledValue());
@@ -8985,6 +8998,7 @@
     Entry.IsReturned = false;
     Entry.IsSwiftSelf = false;
     Entry.IsSwiftError = false;
+    Entry.IsCFGuardTarget = false;
     Entry.Alignment = Align;
     CLI.getArgs().insert(CLI.getArgs().begin(), Entry);
     CLI.NumFixedArgs += 1;
@@ -9097,6 +9111,8 @@
         Flags.setSwiftSelf();
       if (Args[i].IsSwiftError)
         Flags.setSwiftError();
+      if (Args[i].IsCFGuardTarget)
+        Flags.setCFGuardTarget();
       if (Args[i].IsByVal)
         Flags.setByVal();
       if (Args[i].IsInAlloca) {
Index: llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
===================================================================
--- llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -1190,6 +1190,8 @@
       Flags.setSwiftSelf();
     if (Arg.IsSwiftError)
       Flags.setSwiftError();
+    if (Arg.IsCFGuardTarget)
+      Flags.setCFGuardTarget();
     if (Arg.IsByVal)
       Flags.setByVal();
     if (Arg.IsInAlloca) {
Index: llvm/lib/CodeGen/MachineBasicBlock.cpp
===================================================================
--- llvm/lib/CodeGen/MachineBasicBlock.cpp
+++ llvm/lib/CodeGen/MachineBasicBlock.cpp
@@ -54,8 +54,7 @@
   if (!CachedMCSymbol) {
     const MachineFunction *MF = getParent();
     MCContext &Ctx = MF->getContext();
-    auto Prefix =
-        LabelIsPublic ? "" : Ctx.getAsmInfo()->getPrivateLabelPrefix();
+    auto Prefix = Ctx.getAsmInfo()->getPrivateLabelPrefix();
     assert(getNumber() >= 0 && "cannot get label for unreachable MBB");
     CachedMCSymbol = Ctx.getOrCreateSymbol(Twine(Prefix) + "BB" +
                                            Twine(MF->getFunctionNumber()) +
Index: llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
===================================================================
--- llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -1553,6 +1553,10 @@
   if (F && F->hasDLLImportStorageClass())
     return false;
 
+  // FIXME: support control flow guard targets.
+  if (CI.countOperandBundlesOfType(LLVMContext::OB_cfguardtarget))
+    return false;
+
   if (CI.isInlineAsm())
     return translateInlineAsm(CI, MIRBuilder);
 
@@ -1657,6 +1661,10 @@
   if (I.countOperandBundlesOfType(LLVMContext::OB_deopt))
     return false;
 
+  // FIXME: support control flow guard targets.
+  if (I.countOperandBundlesOfType(LLVMContext::OB_cfguardtarget))
+    return false;
+
   // FIXME: support Windows exception handling.
   if (!isa<LandingPadInst>(EHPadBB->front()))
     return false;
Index: llvm/lib/CodeGen/CFGuardLongjmp.cpp
===================================================================
--- llvm/lib/CodeGen/CFGuardLongjmp.cpp
+++ llvm/lib/CodeGen/CFGuardLongjmp.cpp
@@ -59,12 +59,12 @@
 
 bool CFGuardLongjmp::runOnMachineFunction(MachineFunction &MF) {
 
-  // Skip modules for which the cfguard flag is not set
+  // Skip modules for which the cfguard flag is not set.
   if (!mdconst::extract_or_null<ConstantInt>(
           MF.getMMI().getModule()->getModuleFlag("cfguard")))
     return false;
 
-  // Skip functions that do not have calls to _setjmp
+  // Skip functions that do not have calls to _setjmp.
   if (!MF.getFunction().callsFunctionThatReturnsTwice())
     return false;
 
@@ -75,7 +75,7 @@
   for (MachineBasicBlock &MBB : MF) {
     for (MachineInstr &MI : MBB) {
 
-      // Skip instructions that are not calls to global functions
+      // Skip instructions that are not calls to global functions.
       if (!MI.isCall() || MI.getNumOperands() < 1 || !MI.getOperand(0).isGlobal())
         continue;
 
@@ -94,25 +94,20 @@
   if (SetjmpCalls.empty())
     return false;
 
-  // For each possible target, split the basic block after the call to setjmp.
-  // Ensure that the label of the second basic block will be emitted and does
-  // not have a private prefix. Add this label to the function's list of longjmp
-  // targets.
+  unsigned SetjmpNum = 0;
+
+  // For each possible target, create a new symbol and insert it immediately 
+  // after the call to setjmp. Add this symbol to the MachineFunction's list 
+  // of longjmp targets.
   for (MachineInstr *Setjmp : SetjmpCalls) {
-    MachineBasicBlock *OldMBB = Setjmp->getParent();
-    MachineBasicBlock *NewMBB =
-        MF.CreateMachineBasicBlock(OldMBB->getBasicBlock());
-    NewMBB->setLabelIsPublic();
-    NewMBB->setLabelMustBeEmitted();
-    MF.insert(++OldMBB->getIterator(), NewMBB);
-    NewMBB->splice(NewMBB->begin(), OldMBB,
-                   std::next(MachineBasicBlock::iterator(Setjmp)),
-                   OldMBB->end());
-    NewMBB->transferSuccessorsAndUpdatePHIs(OldMBB);
-    OldMBB->addSuccessor(NewMBB);
-    MF.addLongjmpTarget(NewMBB->getSymbol());
-    CFGuardLongjmpTargets++;
+    SmallString<128> SymbolName;
+    raw_svector_ostream(SymbolName) << "$cfgsj_" << MF.getName() << SetjmpNum++;
+    MCSymbol *SjSymbol = MF.getContext().getOrCreateSymbol(SymbolName);
+
+    Setjmp->setPostInstrSymbol(MF, SjSymbol);
+    MF.addLongjmpTarget(SjSymbol);
+    CFGuardLongjmpTargets++;  
   }
 
   return true;
 }
\ No newline at end of file
Index: llvm/lib/CodeGen/AsmPrinter/WinCFGuard.h
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/WinCFGuard.h
+++ llvm/lib/CodeGen/AsmPrinter/WinCFGuard.h
@@ -31,7 +31,7 @@
 
   void setSymbolSize(const MCSymbol *Sym, uint64_t Size) override {}
 
-  /// Emit the Control Flow Guard function ID table
+  /// Emit the Control Flow Guard function ID table.
   void endModule() override;
 
   /// Gather pre-function debug information.
Index: llvm/lib/CodeGen/AsmPrinter/WinCFGuard.cpp
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/WinCFGuard.cpp
+++ llvm/lib/CodeGen/AsmPrinter/WinCFGuard.cpp
@@ -32,11 +32,11 @@
 
 void WinCFGuard::endFunction(const MachineFunction *MF) {
 
-  // Skip functions without any longjmp targets
+  // Skip functions without any longjmp targets.
   if (MF->getLongjmpTargets().empty())
     return;
 
-  // Copy the function's longjmp targets to a module-level list
+  // Copy the function's longjmp targets to a module-level list.
   LongjmpTargets.insert(LongjmpTargets.end(), MF->getLongjmpTargets().begin(),
                         MF->getLongjmpTargets().end());
 }
@@ -54,7 +54,7 @@
   for (const Function *F : Functions)
     OS.EmitCOFFSymbolIndex(Asm->getSymbol(F));
 
-  // Emit the symbol index of each longjmp target
+  // Emit the symbol index of each longjmp target.
   OS.SwitchSection(Asm->OutContext.getObjectFileInfo()->getGLJMPSection());
   for (const MCSymbol *S : LongjmpTargets) {
     OS.EmitCOFFSymbolIndex(S);
Index: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -378,7 +378,7 @@
                           EHTimerDescription, DWARFGroupName,
                           DWARFGroupDescription);
 
-  // Emit tables for any value of cfguard flag (i.e. cfguard=1 or cfguard=2)
+  // Emit tables for any value of cfguard flag (i.e. cfguard=1 or cfguard=2).
   if (mdconst::extract_or_null<ConstantInt>(
           MMI->getModule()->getModuleFlag("cfguard")))
     Handlers.emplace_back(llvm::make_unique<WinCFGuard>(this), CFGuardName,
Index: llvm/lib/AsmParser/LLToken.h
===================================================================
--- llvm/lib/AsmParser/LLToken.h
+++ llvm/lib/AsmParser/LLToken.h
@@ -133,7 +133,6 @@
   kw_coldcc,
   kw_intel_ocl_bicc,
   kw_cfguard_checkcc,
-  kw_cfguard_dispatchcc,
   kw_x86_stdcallcc,
   kw_x86_fastcallcc,
   kw_x86_thiscallcc,
Index: llvm/lib/AsmParser/LLParser.cpp
===================================================================
--- llvm/lib/AsmParser/LLParser.cpp
+++ llvm/lib/AsmParser/LLParser.cpp
@@ -1921,7 +1921,6 @@
 ///   ::= 'intel_ocl_bicc'
 ///   ::= 'coldcc'
 ///   ::= 'cfguard_checkcc'
-///   ::= 'cfguard_dispatchcc'
 ///   ::= 'x86_stdcallcc'
 ///   ::= 'x86_fastcallcc'
 ///   ::= 'x86_thiscallcc'
@@ -1966,7 +1965,6 @@
   case lltok::kw_fastcc:         CC = CallingConv::Fast; break;
   case lltok::kw_coldcc:         CC = CallingConv::Cold; break;
   case lltok::kw_cfguard_checkcc: CC = CallingConv::CFGuard_Check; break;
-  case lltok::kw_cfguard_dispatchcc: CC = CallingConv::CFGuard_Dispatch; break;
   case lltok::kw_x86_stdcallcc:  CC = CallingConv::X86_StdCall; break;
   case lltok::kw_x86_fastcallcc: CC = CallingConv::X86_FastCall; break;
   case lltok::kw_x86_regcallcc:  CC = CallingConv::X86_RegCall; break;
Index: llvm/lib/AsmParser/LLLexer.cpp
===================================================================
--- llvm/lib/AsmParser/LLLexer.cpp
+++ llvm/lib/AsmParser/LLLexer.cpp
@@ -586,7 +586,6 @@
   KEYWORD(fastcc);
   KEYWORD(coldcc);
   KEYWORD(cfguard_checkcc);
-  KEYWORD(cfguard_dispatchcc);
   KEYWORD(x86_stdcallcc);
   KEYWORD(x86_fastcallcc);
   KEYWORD(x86_thiscallcc);
Index: llvm/include/llvm/Transforms/CFGuard.h
===================================================================
--- llvm/include/llvm/Transforms/CFGuard.h
+++ llvm/include/llvm/Transforms/CFGuard.h
@@ -13,13 +13,13 @@
 
 namespace llvm {
 
-class ModulePass;
+class FunctionPass;
 
 /// Insert Control FLow Guard checks on indirect function calls.
-ModulePass *createCFGuardCheckPass();
+FunctionPass *createCFGuardCheckPass();
 
 /// Insert Control FLow Guard dispatches on indirect function calls.
-ModulePass *createCFGuardDispatchPass();
+FunctionPass *createCFGuardDispatchPass();
 
 }
 
Index: llvm/include/llvm/Target/TargetCallingConv.td
===================================================================
--- llvm/include/llvm/Target/TargetCallingConv.td
+++ llvm/include/llvm/Target/TargetCallingConv.td
@@ -51,6 +51,11 @@
 class CCIfSwiftError<CCAction A> : CCIf<"ArgFlags.isSwiftError()", A> {
 }
 
+/// CCIfCFGuardTarget - If the current argument has cfguardtarget parameter 
+/// attribute, apply Action A.
+class CCIfCFGuardTarget<CCAction A> : CCIf<"ArgFlags.isCFGuardTarget()", A> {
+}
+
 /// CCIfConsecutiveRegs - If the current argument has InConsecutiveRegs
 /// parameter attribute, apply Action A.
 class CCIfConsecutiveRegs<CCAction A> : CCIf<"ArgFlags.isInConsecutiveRegs()", A> {
Index: llvm/include/llvm/IR/LLVMContext.h
===================================================================
--- llvm/include/llvm/IR/LLVMContext.h
+++ llvm/include/llvm/IR/LLVMContext.h
@@ -85,6 +85,7 @@
     OB_deopt = 0,         // "deopt"
     OB_funclet = 1,       // "funclet"
     OB_gc_transition = 2, // "gc-transition"
+    OB_cfguardtarget = 3, // "cfguardtarget"
   };
 
   /// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
Index: llvm/include/llvm/IR/InstrTypes.h
===================================================================
--- llvm/include/llvm/IR/InstrTypes.h
+++ llvm/include/llvm/IR/InstrTypes.h
@@ -1039,6 +1039,11 @@
     return getTagID() == LLVMContext::OB_funclet;
   }
 
+  /// Return true if this is a "cfguardtarget" operand bundle.
+  bool isCFGuardTargetOperandBundle() const {
+    return getTagID() == LLVMContext::OB_cfguardtarget;
+  }
+
 private:
   /// Pointer to an entry in LLVMContextImpl::getOrInsertBundleTag.
   StringMapEntry<uint32_t> *Tag;
Index: llvm/include/llvm/IR/CallingConv.h
===================================================================
--- llvm/include/llvm/IR/CallingConv.h
+++ llvm/include/llvm/IR/CallingConv.h
@@ -76,17 +76,11 @@
     CXX_FAST_TLS = 17,
 
     /// Special calling convention on Windows for calling the Control
-    /// Guard Check ICall funtion. The function take exactly one argument
+    /// Guard Check ICall funtion. The function takes exactly one argument
     /// (address of the target function) passed in the first argument register,
     /// and has no return value. All register values are preserved.
     CFGuard_Check = 18,
 
-    /// Special calling convention on Windows for calling the Control
-    /// Guard Dispatch ICall funtion. The address of the target function to
-    /// tail-call is passed in a register (RAX on X86_64 targets), and all other
-    /// arguments are the same as if they were calling the target function.
-    CFGuard_Dispatch = 19,
-
     // Target - This is the start of the target-specific calling conventions,
     // e.g. fastcall and thiscall on X86.
     FirstTargetCC = 64,
Index: llvm/include/llvm/CodeGen/TargetLowering.h
===================================================================
--- llvm/include/llvm/CodeGen/TargetLowering.h
+++ llvm/include/llvm/CodeGen/TargetLowering.h
@@ -188,13 +188,14 @@
     bool IsReturned : 1;
     bool IsSwiftSelf : 1;
     bool IsSwiftError : 1;
+    bool IsCFGuardTarget : 1;
     uint16_t Alignment = 0;
     Type *ByValType = nullptr;
 
     ArgListEntry()
         : IsSExt(false), IsZExt(false), IsInReg(false), IsSRet(false),
           IsNest(false), IsByVal(false), IsInAlloca(false), IsReturned(false),
-          IsSwiftSelf(false), IsSwiftError(false) {}
+          IsSwiftSelf(false), IsSwiftError(false), IsCFGuardTarget(false) {}
 
     void setAttributes(const CallBase *Call, unsigned ArgIdx);
 
Index: llvm/include/llvm/CodeGen/TargetCallingConv.h
===================================================================
--- llvm/include/llvm/CodeGen/TargetCallingConv.h
+++ llvm/include/llvm/CodeGen/TargetCallingConv.h
@@ -38,6 +38,7 @@
     unsigned IsSplitEnd : 1;   ///< Last part of a split
     unsigned IsSwiftSelf : 1;  ///< Swift self parameter
     unsigned IsSwiftError : 1; ///< Swift error parameter
+    unsigned IsCFGuardTarget : 1; ///< Control Flow Guard target
     unsigned IsHva : 1;        ///< HVA field for
     unsigned IsHvaStart : 1;   ///< HVA structure start
     unsigned IsSecArgPass : 1; ///< Second argument
@@ -56,8 +57,8 @@
     ArgFlagsTy()
         : IsZExt(0), IsSExt(0), IsInReg(0), IsSRet(0), IsByVal(0), IsNest(0),
           IsReturned(0), IsSplit(0), IsInAlloca(0), IsSplitEnd(0),
-          IsSwiftSelf(0), IsSwiftError(0), IsHva(0), IsHvaStart(0),
-          IsSecArgPass(0), ByValAlign(0), OrigAlign(0),
+          IsSwiftSelf(0), IsSwiftError(0), IsCFGuardTarget(0), IsHva(0), 
+          IsHvaStart(0), IsSecArgPass(0), ByValAlign(0), OrigAlign(0),
           IsInConsecutiveRegsLast(0), IsInConsecutiveRegs(0),
           IsCopyElisionCandidate(0), IsPointer(0), ByValSize(0),
           PointerAddrSpace(0) {
@@ -88,6 +89,9 @@
     bool isSwiftError() const { return IsSwiftError; }
     void setSwiftError() { IsSwiftError = 1; }
 
+    bool isCFGuardTarget() const { return IsCFGuardTarget; }
+    void setCFGuardTarget() { IsCFGuardTarget = 1; }
+
     bool isHva() const { return IsHva; }
     void setHva() { IsHva = 1; }
 
Index: llvm/include/llvm/CodeGen/MachineBasicBlock.h
===================================================================
--- llvm/include/llvm/CodeGen/MachineBasicBlock.h
+++ llvm/include/llvm/CodeGen/MachineBasicBlock.h
@@ -118,10 +118,6 @@
   /// whether the flow just falls-through to it.
   bool LabelMustBeEmitted = false;
 
-  /// Indicate that this basic block's symbol will not have a private label 
-  /// prefix, and will thus be included in the symbol table.
-  bool LabelIsPublic = false;
-
   /// Indicate that this basic block is the entry block of an EH scope, i.e.,
   /// the block that used to have a catchpad or cleanuppad instruction in the
   /// LLVM IR.
@@ -173,12 +169,6 @@
   /// its label be emitted.
   void setLabelMustBeEmitted() { LabelMustBeEmitted = true; }
 
-  /// Set this block to reflect that its label will not have a private prefix.
-  void setLabelIsPublic() { 
-    assert((!CachedMCSymbol || LabelIsPublic == true) && "Cannot set label to public after it has been accessed.");
-    LabelIsPublic = true; 
-  }
-
   /// Return the MachineFunction containing this basic block.
   const MachineFunction *getParent() const { return xParent; }
   MachineFunction *getParent() { return xParent; }
Index: llvm/docs/LangRef.rst
===================================================================
--- llvm/docs/LangRef.rst
+++ llvm/docs/LangRef.rst
@@ -438,24 +438,15 @@
     - On iOS platforms, we use AAPCS-VFP calling convention.
 "``cfguard_checkcc``" - Windows Control Flow Guard (Check mechanism)
     This calling convention is used for the Control Flow Guard check function,
-	which can be inserted before indirect calls to check that the call target 
-	is a valid function address. The check function has no return value, but
-	it will trigger an OS-level error if the address is not a valid target.
-	The set of registers preserved by the check function, and the register 
-	containing the target address are architecture-specific.
+    calls to which can be inserted before indirect calls to check that the call
+    target is a valid function address. The check function has no return value,
+    but it will trigger an OS-level error if the address is not a valid target.
+    The set of registers preserved by the check function, and the register 
+    containing the target address are architecture-specific.
 
-    - On X86_32 the target address is passed in ECX.
+    - On X86 the target address is passed in ECX.
     - On ARM the target address is passed in R0.
     - On Aarch64 the target address is passed in X15.
-"``cfguard_dispatchcc``" - Windows Control Flow Guard (Dispatch mechanism)
-    This calling convention is used for the Control Flow Guard dispatch 
-    function, which can be inserted in place of indirect calls to check 
-    that the call target is a valid function address and then tail-call the 
-    function. It passes the target address in the appropriate 
-    (architecture-specific) register. All other function arguments are 
-	passed as usual.
-
-    - On X86-64 the target address is passed in RAX.
 "``cc <n>``" - Numbered convention
     Any calling convention may be specified by number, allowing
     target-specific calling conventions to be used. Target specific
Index: clang/test/Driver/cl-fallback.c
===================================================================
--- clang/test/Driver/cl-fallback.c
+++ clang/test/Driver/cl-fallback.c
@@ -2,7 +2,7 @@
 // command-line option, e.g. on Mac where %s is commonly under /Users.
 
 // RUN: %clang_cl --target=i686-pc-win32 /fallback /Dfoo=bar /Ubaz /Ifoo /O0 /Ox /GR /GR- /GS /GS- /Gy /Gy- \
-// RUN:   /Gw /Gw- /LD /LDd /EHs /EHs- /Zl /MD /MDd /MTd /MT /FImyheader.h /Zi \
+// RUN:   /Gw /Gw- /guard:cf /guard:cf- /LD /LDd /EHs /EHs- /Zl /MD /MDd /MTd /MT /FImyheader.h /Zi \
 // RUN:   -garbage -moregarbage \
 // RUN:   -### -- %s 2>&1 \
 // RUN:   | FileCheck %s
@@ -25,6 +25,7 @@
 // CHECK: "/GS-"
 // CHECK: "/Gy-"
 // CHECK: "/Gw-"
+// CHECK: "/guard:cf-"
 // CHECK: "/Z7"
 // CHECK: "/FImyheader.h"
 // CHECK: "/LD"
Index: clang/lib/Driver/ToolChains/MSVC.cpp
===================================================================
--- clang/lib/Driver/ToolChains/MSVC.cpp
+++ clang/lib/Driver/ToolChains/MSVC.cpp
@@ -416,8 +416,17 @@
   }
 
   Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
-  // Flags that can simply be passed through.
-  Args.AddAllArgs(CmdArgs, options::OPT__SLASH_guard);
+
+  if (Arg *A = Args.getLastArg(options::OPT__SLASH_guard)) {
+    StringRef GuardArgs = A->getValue();
+    if (GuardArgs.equals_lower("cf") || GuardArgs.equals_lower("cf,nochecks")) {
+      // MSVC doesn't yet support the "nochecks" modifier.
+      CmdArgs.push_back("-guard:cf");
+    }
+    else if (GuardArgs.equals_lower("cf-")) {
+      CmdArgs.push_back("-guard:cf-");
+    }
+  }
 
   if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
                    options::OPT_fno_openmp, false)) {
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -5951,30 +5951,24 @@
   }
 
   if (Arg *A = Args.getLastArg(options::OPT__SLASH_guard)) {
-    SmallVector<StringRef, 1> SplitArgs;
-    StringRef(A->getValue()).split(SplitArgs, ",");
-    bool Instrument = false;
-    bool NoChecks = false;
-    for (StringRef Arg : SplitArgs) {
-      if (Arg.equals_lower("cf"))
-        Instrument = true;
-      else if (Arg.equals_lower("cf-"))
-        Instrument = false;
-      else if (Arg.equals_lower("nochecks"))
-        NoChecks = true;
-      else if (Arg.equals_lower("nochecks-"))
-        NoChecks = false;
-      else
-        D.Diag(diag::err_drv_invalid_value) << A->getSpelling() << Arg;
-    }
-
-    if (Instrument && !NoChecks)
-      //Emit CFG instrumentation and the table of address-taken functions.
+    StringRef GuardArgs = A->getValue();
+    // The only valid options are "cf", "cf,nochecks", and "cf-".
+    if (GuardArgs.equals_lower("cf")) {
+      // Emit CFG instrumentation and the table of address-taken functions.
       CmdArgs.push_back("-cfguard");
-    else if (NoChecks)
-      //Emit only the table of address-taken functions.
+    }
+    else if (GuardArgs.equals_lower("cf,nochecks")) {
+      // Emit only the table of address-taken functions.
       CmdArgs.push_back("-cfguard-no-checks");
+    }
+    else if (GuardArgs.equals_lower("cf-")) {
+      // Do nothing, but we might want to emit a security warning in future.
+    }
+    else {
+      D.Diag(diag::err_drv_invalid_value) << A->getSpelling() << GuardArgs;
+    }
   }
+  
 }
 
 visualstudio::Compiler *Clang::getCLFallback() const {
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -486,14 +486,14 @@
   if (CodeGenOpts.CodeViewGHash) {
     getModule().addModuleFlag(llvm::Module::Warning, "CodeViewGHash", 1);
   }
-  if (CodeGenOpts.ControlFlowGuardNoChecks) {
-    // Function ID tables for Control Flow Guard (cfguard=1).
-    getModule().addModuleFlag(llvm::Module::Warning, "cfguard", 1);
-  }
   if (CodeGenOpts.ControlFlowGuard) {
     // Function ID tables and checks for Control Flow Guard (cfguard=2).
     getModule().addModuleFlag(llvm::Module::Warning, "cfguard", 2);
   }
+  else if (CodeGenOpts.ControlFlowGuardNoChecks) {
+    // Function ID tables for Control Flow Guard (cfguard=1).
+    getModule().addModuleFlag(llvm::Module::Warning, "cfguard", 1);
+  }
   if (CodeGenOpts.OptimizationLevel > 0 && CodeGenOpts.StrictVTablePointers) {
     // We don't support LTO with 2 with different StrictVTablePointers
     // FIXME: we could support it by stripping all the information introduced
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -497,10 +497,6 @@
 def bundle__loader : Separate<["-"], "bundle_loader">;
 def bundle : Flag<["-"], "bundle">;
 def b : JoinedOrSeparate<["-"], "b">, Flags<[Unsupported]>;
-def cfguard_no_checks : Flag<["-"], "cfguard-no-checks">, Flags<[CC1Option]>,
-  HelpText<"Emit Windows Control Flow Guard tables only (no checks).">;
-def cfguard : Flag<["-"], "cfguard">, Flags<[CC1Option]>,
-  HelpText<"Emit Windows Control Flow Guard tables and checks.">;
 def cl_opt_disable : Flag<["-"], "cl-opt-disable">, Group<opencl_Group>, Flags<[CC1Option]>,
   HelpText<"OpenCL only. This option disables all optimizations. By default optimizations are enabled.">;
 def cl_strict_aliasing : Flag<["-"], "cl-strict-aliasing">, Group<opencl_Group>, Flags<[CC1Option]>,
Index: clang/include/clang/Driver/CC1Options.td
===================================================================
--- clang/include/clang/Driver/CC1Options.td
+++ clang/include/clang/Driver/CC1Options.td
@@ -399,6 +399,10 @@
     Values<"a_key,b_key">;
 def mbranch_target_enforce : Flag<["-"], "mbranch-target-enforce">;
 def fno_dllexport_inlines : Flag<["-"], "fno-dllexport-inlines">;
+def cfguard_no_checks : Flag<["-"], "cfguard-no-checks">,
+    HelpText<"Emit Windows Control Flow Guard tables only (no checks)">;
+def cfguard : Flag<["-"], "cfguard">,
+    HelpText<"Emit Windows Control Flow Guard tables and checks">;
 
 //===----------------------------------------------------------------------===//
 // Dependency Output Options
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to