[clang] [llvm] security check cookie execute only when needed (PR #95904)

via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 18 12:26:23 PDT 2024


https://github.com/mahesh-attarde updated https://github.com/llvm/llvm-project/pull/95904

>From 6d6619f8f7a37906ac45791487a4d63b51a48ad1 Mon Sep 17 00:00:00 2001
From: mahesh-attarde <mahesh.attarde at intel.com>
Date: Wed, 12 Jun 2024 06:15:51 -0700
Subject: [PATCH 1/4] added regcall strct by reg support

---
 clang/lib/CodeGen/Targets/X86.cpp | 20 ++++++++++++
 clang/test/CodeGen/regcall3.c     | 53 +++++++++++++++++++++++++++++++
 2 files changed, 73 insertions(+)
 create mode 100644 clang/test/CodeGen/regcall3.c

diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp
index 43dadf5e724ac..506d106ad65b0 100644
--- a/clang/lib/CodeGen/Targets/X86.cpp
+++ b/clang/lib/CodeGen/Targets/X86.cpp
@@ -148,6 +148,7 @@ class X86_32ABIInfo : public ABIInfo {
 
   Class classify(QualType Ty) const;
   ABIArgInfo classifyReturnType(QualType RetTy, CCState &State) const;
+
   ABIArgInfo classifyArgumentType(QualType RetTy, CCState &State,
                                   unsigned ArgIndex) const;
 
@@ -1306,6 +1307,8 @@ class X86_64ABIInfo : public ABIInfo {
                                            unsigned &NeededSSE,
                                            unsigned &MaxVectorWidth) const;
 
+  bool DoesRegcallStructFitInReg(QualType Ty) const;
+
   bool IsIllegalVectorType(QualType Ty) const;
 
   /// The 0.98 ABI revision clarified a lot of ambiguities,
@@ -2830,6 +2833,20 @@ X86_64ABIInfo::classifyArgumentType(QualType Ty, unsigned freeIntRegs,
   return ABIArgInfo::getDirect(ResType);
 }
 
+bool X86_64ABIInfo::DoesRegcallStructFitInReg(QualType Ty) const {
+  auto RT = Ty->castAs<RecordType>();
+  // For Integer class, Max GPR Size is 64
+  if (getContext().getTypeSize(Ty) > 64)
+    return false;
+  // Struct At hand must not have other non Builtin types
+  for (const auto *FD : RT->getDecl()->fields()) {
+    QualType MTy = FD->getType();
+    if (!MTy->isBuiltinType())
+      return false;
+  }
+  return true;
+}
+
 ABIArgInfo
 X86_64ABIInfo::classifyRegCallStructTypeImpl(QualType Ty, unsigned &NeededInt,
                                              unsigned &NeededSSE,
@@ -2837,6 +2854,9 @@ X86_64ABIInfo::classifyRegCallStructTypeImpl(QualType Ty, unsigned &NeededInt,
   auto RT = Ty->getAs<RecordType>();
   assert(RT && "classifyRegCallStructType only valid with struct types");
 
+  if (DoesRegcallStructFitInReg(Ty))
+    return classifyArgumentType(Ty, UINT_MAX, NeededInt, NeededSSE, true, true);
+
   if (RT->getDecl()->hasFlexibleArrayMember())
     return getIndirectReturnResult(Ty);
 
diff --git a/clang/test/CodeGen/regcall3.c b/clang/test/CodeGen/regcall3.c
new file mode 100644
index 0000000000000..1c83407220861
--- /dev/null
+++ b/clang/test/CodeGen/regcall3.c
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -S %s -o - -ffreestanding -triple=x86_64-unknown-linux-gnu | FileCheck %s --check-prefixes=LINUX64
+
+#include <xmmintrin.h>
+struct struct1 { int x; int y; };
+void __regcall v6(int a, float b, struct struct1 c) {}
+
+void v6_caller(){
+    struct struct1 c0;
+    c0.x = 0xa0a0; c0.y = 0xb0b0;
+    int x= 0xf0f0, y = 0x0f0f;
+    v6(x,y,c0);
+}
+
+// LINUX64-LABEL: __regcall3__v6
+// LINUX64: movq	%rcx, -8(%rsp)
+// LINUX64: movl	%eax, -12(%rsp)
+// LINUX64: movss	%xmm0, -16(%rsp)
+
+// LINUX64-LABEL: v6_caller
+// LINUX64: movl	$41120, 16(%rsp)                # imm = 0xA0A0
+// LINUX64: movl	$45232, 20(%rsp)                # imm = 0xB0B0
+// LINUX64: movl	$61680, 12(%rsp)                # imm = 0xF0F0
+// LINUX64: movl	$3855, 8(%rsp)                  # imm = 0xF0F
+// LINUX64: movl	12(%rsp), %eax
+// LINUX64: cvtsi2ssl	8(%rsp), %xmm0
+// LINUX64: movq	16(%rsp), %rcx
+// LINUX64: callq	.L__regcall3__v6$local
+
+
+struct struct2 { int x; float y; };
+void __regcall v31(int a, float b, struct struct2 c) {}
+
+void v31_caller(){
+    struct struct2 c0;
+    c0.x = 0xa0a0; c0.y = 0xb0b0;
+    int x= 0xf0f0, y = 0x0f0f;
+    v31(x,y,c0);
+}
+
+// LINUX64: __regcall3__v31:                        # @__regcall3__v31
+// LINUX64: 	movq	%rcx, -8(%rsp)
+// LINUX64: 	movl	%eax, -12(%rsp)
+// LINUX64: 	movss	%xmm0, -16(%rsp)
+// LINUX64: v31_caller:                             # @v31_caller
+// LINUX64: 	movl	$41120, 16(%rsp)                # imm = 0xA0A0
+// LINUX64: 	movss	.LCPI3_0(%rip), %xmm0           # xmm0 = [4.5232E+4,0.0E+0,0.0E+0,0.0E+0]
+// LINUX64: 	movss	%xmm0, 20(%rsp)
+// LINUX64: 	movl	$61680, 12(%rsp)                # imm = 0xF0F0
+// LINUX64: 	movl	$3855, 8(%rsp)                  # imm = 0xF0F
+// LINUX64: 	movl	12(%rsp), %eax
+// LINUX64: 	cvtsi2ssl	8(%rsp), %xmm0
+// LINUX64: 	movq	16(%rsp), %rcx
+// LINUX64: 	callq	.L__regcall3__v31$local

>From 8bdd245edd8dca9477d6541401737f2aeaf6e820 Mon Sep 17 00:00:00 2001
From: mahesh-attarde <mahesh.attarde at intel.com>
Date: Tue, 18 Jun 2024 03:33:02 -0700
Subject: [PATCH 2/4] selectively call security cookie check

---
 llvm/lib/Target/X86/CMakeLists.txt            |   1 +
 llvm/lib/Target/X86/X86.h                     |   4 +
 .../lib/Target/X86/X86FixupStackProtector.cpp | 249 ++++++++++++++++++
 llvm/lib/Target/X86/X86TargetMachine.cpp      |   1 +
 llvm/test/CodeGen/X86/opt-pipeline.ll         |   1 +
 llvm/test/CodeGen/X86/stack-protector-msvc.ll |  22 +-
 llvm/test/CodeGen/X86/tailcc-ssp.ll           |  27 +-
 7 files changed, 296 insertions(+), 9 deletions(-)
 create mode 100644 llvm/lib/Target/X86/X86FixupStackProtector.cpp

diff --git a/llvm/lib/Target/X86/CMakeLists.txt b/llvm/lib/Target/X86/CMakeLists.txt
index 44a54c8ec62cb..5303758ff8a2e 100644
--- a/llvm/lib/Target/X86/CMakeLists.txt
+++ b/llvm/lib/Target/X86/CMakeLists.txt
@@ -48,6 +48,7 @@ set(sources
   X86AvoidStoreForwardingBlocks.cpp
   X86DynAllocaExpander.cpp
   X86FixupSetCC.cpp
+  X86FixupStackProtector.cpp
   X86FlagsCopyLowering.cpp
   X86FloatingPoint.cpp
   X86FrameLowering.cpp
diff --git a/llvm/lib/Target/X86/X86.h b/llvm/lib/Target/X86/X86.h
index fdb9e4cad5e89..b4432f45987cd 100644
--- a/llvm/lib/Target/X86/X86.h
+++ b/llvm/lib/Target/X86/X86.h
@@ -73,6 +73,9 @@ FunctionPass *createX86OptimizeLEAs();
 /// Return a pass that transforms setcc + movzx pairs into xor + setcc.
 FunctionPass *createX86FixupSetCC();
 
+/// Return a pass that transform inline stack protector into seperate bb
+FunctionPass *createX86FixupStackProtectorPass();
+
 /// Return a pass that avoids creating store forward block issues in the hardware.
 FunctionPass *createX86AvoidStoreForwardingBlocks();
 
@@ -186,6 +189,7 @@ void initializeX86ExpandPseudoPass(PassRegistry &);
 void initializeX86FastPreTileConfigPass(PassRegistry &);
 void initializeX86FastTileConfigPass(PassRegistry &);
 void initializeX86FixupSetCCPassPass(PassRegistry &);
+void initializeX86FixupStackProtectorPassPass(PassRegistry &);
 void initializeX86FlagsCopyLoweringPassPass(PassRegistry &);
 void initializeX86LoadValueInjectionLoadHardeningPassPass(PassRegistry &);
 void initializeX86LoadValueInjectionRetHardeningPassPass(PassRegistry &);
diff --git a/llvm/lib/Target/X86/X86FixupStackProtector.cpp b/llvm/lib/Target/X86/X86FixupStackProtector.cpp
new file mode 100644
index 0000000000000..f1355c62cc2c1
--- /dev/null
+++ b/llvm/lib/Target/X86/X86FixupStackProtector.cpp
@@ -0,0 +1,249 @@
+//===---- X86FixupStackProtector.cpp Fix Stack Protector Call ----------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+// Stack Protector implementation inserts platform specific callback into code.
+// For windows __security_check_cookie call gets call everytime function is
+// return without fixup. Since this function is defined in runtime library, it
+// incures cost of call in dll which simply does comparison and returns most
+// time. With Fixup, We selective move to call in DLL only if comparison fails.
+//===----------------------------------------------------------------------===//
+
+#include "X86.h"
+#include "X86FrameLowering.h"
+#include "X86InstrInfo.h"
+#include "X86Subtarget.h"
+#include "llvm/CodeGen/LivePhysRegs.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/IR/Module.h"
+#include <iterator>
+
+using namespace llvm;
+
+#define DEBUG_TYPE "x86-fixup-spcall"
+
+namespace {
+
+class X86FixupStackProtectorPass : public MachineFunctionPass {
+public:
+  static char ID;
+
+  X86FixupStackProtectorPass() : MachineFunctionPass(ID) {}
+
+  StringRef getPassName() const override { return "X86 Fixup Stack Protector"; }
+
+  bool runOnMachineFunction(MachineFunction &MF) override;
+
+  std::pair<MachineBasicBlock *, MachineInstr *>
+  getSecurityCheckerBasicBlock(MachineFunction &MF);
+
+  void getGuardCheckSequence(MachineBasicBlock *CurMBB, MachineInstr *CheckCall,
+                             MachineInstr *SeqMI[5]);
+ 
+  void SplitBasicBlock(MachineBasicBlock *CurMBB, MachineBasicBlock *NewRetMBB,
+                       MachineBasicBlock::iterator SplitIt);
+
+  void FinishBlock(MachineBasicBlock *MBB);
+
+  void FinishFunction(MachineBasicBlock *FailMBB, MachineBasicBlock *NewRetMBB);
+
+  std::pair<MachineInstr *, MachineInstr *>
+  CreateFailCheckSequence(MachineBasicBlock *CurMBB, MachineBasicBlock *FailMBB,
+                          MachineInstr *SeqMI[5]);
+};
+} // end anonymous namespace
+
+char X86FixupStackProtectorPass::ID = 0;
+
+INITIALIZE_PASS(X86FixupStackProtectorPass, DEBUG_TYPE, DEBUG_TYPE, false,
+                false)
+
+FunctionPass *llvm::createX86FixupStackProtectorPass() {
+  return new X86FixupStackProtectorPass();
+}
+
+void X86FixupStackProtectorPass::SplitBasicBlock(
+    MachineBasicBlock *CurMBB, MachineBasicBlock *NewRetMBB,
+    MachineBasicBlock::iterator SplitIt) {
+  NewRetMBB->splice(NewRetMBB->end(), CurMBB, SplitIt, CurMBB->end());
+}
+
+std::pair<MachineBasicBlock *, MachineInstr *>
+X86FixupStackProtectorPass::getSecurityCheckerBasicBlock(MachineFunction &MF) {
+  MachineBasicBlock::reverse_iterator RBegin, REnd;
+
+  for (auto &MBB : llvm::reverse(MF)) {
+    for (RBegin = MBB.rbegin(), REnd = MBB.rend(); RBegin != REnd; RBegin++) {
+      auto &MI = *RBegin;
+      if (MI.getOpcode() == X86::CALL64pcrel32 &&
+          MI.getNumExplicitOperands() == 1) {
+        auto MO = MI.getOperand(0);
+        if (MO.isGlobal()) {
+          auto Callee = dyn_cast<Function>(MO.getGlobal());
+          if (Callee && Callee->getName() == "__security_check_cookie") {
+            return std::make_pair(&MBB, &MI);
+            break;
+          }
+        }
+      }
+    }
+  }
+  return std::make_pair(nullptr, nullptr);
+}
+
+void X86FixupStackProtectorPass::getGuardCheckSequence(
+    MachineBasicBlock *CurMBB, MachineInstr *CheckCall,
+    MachineInstr *SeqMI[5]) {
+
+  MachineBasicBlock::iterator UIt(CheckCall);
+  MachineBasicBlock::reverse_iterator DIt(CheckCall);
+  // Seq From StackUp to Stack Down Is fixed.
+  // ADJCALLSTACKUP64
+  UIt++;
+  SeqMI[4] = &*UIt;
+
+  // CALL __security_check_cookie
+  SeqMI[3] = CheckCall;
+
+  // COPY function slot cookie
+  DIt++;
+  SeqMI[2] = &*DIt;
+
+  // ADJCALLSTACKDOWN64
+  DIt++;
+  SeqMI[1] = &*DIt;
+
+  MachineBasicBlock::reverse_iterator XIt(SeqMI[1]);
+  for (; XIt != CurMBB->rbegin(); XIt++) {
+    auto &CI = *XIt;
+    if ((CI.getOpcode() == X86::XOR64_FP) || (CI.getOpcode() == X86::XOR32_FP))
+      break;
+  }
+  SeqMI[0] = &*XIt;
+}
+
+std::pair<MachineInstr *, MachineInstr *>
+X86FixupStackProtectorPass::CreateFailCheckSequence(MachineBasicBlock *CurMBB,
+                                                    MachineBasicBlock *FailMBB,
+                                                    MachineInstr *SeqMI[5]) {
+
+  auto MF = CurMBB->getParent();
+
+  Module &M = *MF->getFunction().getParent();
+  GlobalVariable *GV = M.getGlobalVariable("__security_cookie");
+  assert(GV && " Security Cookie was not installed!");
+
+  MachineRegisterInfo &MRI = MF->getRegInfo();
+  const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
+
+  MachineInstr *GuardXor = SeqMI[0];
+  MachineBasicBlock::iterator InsertPt(GuardXor);
+  InsertPt++;
+  unsigned DestReg = MRI.createVirtualRegister(&X86::GR64RegClass);
+  // MOV security_cookie value into register
+  auto CMI =
+      BuildMI(*CurMBB, InsertPt, DebugLoc(), TII->get(X86::MOV64rm), DestReg)
+          .addReg(X86::RIP)
+          .addImm(1)
+          .addReg(X86::NoRegister)
+          .addGlobalAddress(GV)
+          .addReg(X86::NoRegister);
+
+  // Compare security_Cookie with XOR_Val, if not same, we have violation
+  BuildMI(*CurMBB, InsertPt, DebugLoc(), TII->get(X86::CMP64rr))
+      .addReg(DestReg)
+      .addReg(GuardXor->getOperand(0).getReg());
+
+  BuildMI(*CurMBB, InsertPt, DebugLoc(), TII->get(X86::JCC_1))
+      .addMBB(FailMBB)
+      .addImm(X86::COND_NE);
+
+  auto JMI = BuildMI(*CurMBB, InsertPt, DebugLoc(), TII->get(X86::JMP_1));
+
+  return std::make_pair(CMI.getInstr(), JMI.getInstr());
+}
+
+void X86FixupStackProtectorPass::FinishBlock(MachineBasicBlock *MBB) {
+  LivePhysRegs LiveRegs;
+  computeAndAddLiveIns(LiveRegs, *MBB);
+}
+
+void X86FixupStackProtectorPass::FinishFunction(MachineBasicBlock *FailMBB,
+                                                MachineBasicBlock *NewRetMBB) {
+  FailMBB->getParent()->RenumberBlocks();
+  // FailMBB includes call to MSCV RT  where is __security_check_cookie
+  // function is called. This function uses regcall and it expects cookie
+  // value from stack slot.( even if this is modified)
+  // Before going further we compute back livein for this block to make sure
+  // it is live and provided.
+  FinishBlock(FailMBB);
+  FinishBlock(NewRetMBB);
+}
+
+bool X86FixupStackProtectorPass::runOnMachineFunction(MachineFunction &MF) {
+  bool Changed = false;
+  const X86Subtarget &STI = MF.getSubtarget<X86Subtarget>();
+
+  if (!(STI.isTargetWindowsItanium() || STI.isTargetWindowsMSVC()))
+    return Changed;
+
+  // Check if security cookie was installed or not
+  Module &M = *MF.getFunction().getParent();
+  GlobalVariable *GV = M.getGlobalVariable("__security_cookie");
+  if (!GV)
+    return Changed;
+
+  const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
+
+  // Check if security check cookie was installed or not
+  auto [CurMBB, CheckCall] = getSecurityCheckerBasicBlock(MF);
+
+  if (!CheckCall)
+    return Changed;
+
+  MachineBasicBlock *FailMBB = MF.CreateMachineBasicBlock();
+  MachineBasicBlock *NewRetMBB = MF.CreateMachineBasicBlock();
+
+  MF.insert(MF.end(), NewRetMBB);
+  MF.insert(MF.end(), FailMBB);
+
+  MachineInstr *SeqMI[5];
+  getGuardCheckSequence(CurMBB, CheckCall, SeqMI);
+  // MachineInstr * GuardXor  = SeqMI[0];
+
+  auto FailSeqRange = CreateFailCheckSequence(CurMBB, FailMBB, SeqMI);
+  MachineInstrBuilder JMI(MF, FailSeqRange.second);
+
+  // After Inserting JMP_1, we can not have two terminators
+  // in same block, split CurrentMBB after JMP_1
+  MachineBasicBlock::iterator SplitIt(SeqMI[4]);
+  SplitIt++;
+  SplitBasicBlock(CurMBB, NewRetMBB, SplitIt);
+
+  // Fill up Failure Routine, move Fail Check Squence from CurMBB to FailMBB
+  MachineBasicBlock::iterator U1It(SeqMI[1]);
+  MachineBasicBlock::iterator U2It(SeqMI[4]);
+  U2It++;
+  FailMBB->splice(FailMBB->end(), CurMBB, U1It, U2It);
+  BuildMI(*FailMBB, FailMBB->end(), DebugLoc(), TII->get(X86::INT3));
+
+  // Move left over instruction after StackUp
+  // from Current Basic BLocks into New Return Block
+  JMI.addMBB(NewRetMBB);
+  MachineBasicBlock::iterator SplicePt(JMI.getInstr());
+  SplicePt++;
+  if (SplicePt != CurMBB->end())
+    NewRetMBB->splice(NewRetMBB->end(), CurMBB, SplicePt);
+
+  // Restructure Basic Blocks
+  CurMBB->addSuccessor(NewRetMBB);
+  CurMBB->addSuccessor(FailMBB);
+
+  FinishFunction(FailMBB, NewRetMBB);
+  return !Changed;
+}
diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp
index d4e642c7df9cf..b245e80ad18dc 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.cpp
+++ b/llvm/lib/Target/X86/X86TargetMachine.cpp
@@ -550,6 +550,7 @@ bool X86PassConfig::addPreISel() {
 void X86PassConfig::addPreRegAlloc() {
   if (getOptLevel() != CodeGenOptLevel::None) {
     addPass(&LiveRangeShrinkID);
+    addPass(createX86FixupStackProtectorPass());
     addPass(createX86FixupSetCC());
     addPass(createX86OptimizeLEAs());
     addPass(createX86CallFrameOptimization());
diff --git a/llvm/test/CodeGen/X86/opt-pipeline.ll b/llvm/test/CodeGen/X86/opt-pipeline.ll
index 15c496bfb7f66..631f955ee6cc0 100644
--- a/llvm/test/CodeGen/X86/opt-pipeline.ll
+++ b/llvm/test/CodeGen/X86/opt-pipeline.ll
@@ -119,6 +119,7 @@
 ; CHECK-NEXT:       Peephole Optimizations
 ; CHECK-NEXT:       Remove dead machine instructions
 ; CHECK-NEXT:       Live Range Shrink
+; CHECK-NEXT:       X86 Fixup Stack Protector
 ; CHECK-NEXT:       X86 Fixup SetCC
 ; CHECK-NEXT:       Lazy Machine Block Frequency Analysis
 ; CHECK-NEXT:       X86 LEA Optimize
diff --git a/llvm/test/CodeGen/X86/stack-protector-msvc.ll b/llvm/test/CodeGen/X86/stack-protector-msvc.ll
index d0b6585f40ffe..f8eb47663fb18 100644
--- a/llvm/test/CodeGen/X86/stack-protector-msvc.ll
+++ b/llvm/test/CodeGen/X86/stack-protector-msvc.ll
@@ -38,8 +38,13 @@ return:    ; preds = %entry
 ; MSVC-X64: callq strcpy
 ; MSVC-X64: movq [[SLOT]](%rsp), %rcx
 ; MSVC-X64: xorq %rsp, %rcx
-; MSVC-X64: callq __security_check_cookie
+; MSVC-X64: movq	__security_cookie(%rip), %rax
+; MSVC-X64: cmpq	%rcx, %rax
+; MSVC-X64: jne	.LBB0_2
 ; MSVC-X64: retq
+; MSVC-X64: LBB0_2:
+; MSVC-X64: callq __security_check_cookie
+; MSVC-X64: int3
 
 ; MSVC-X86-O0-LABEL: _test:
 ; MSVC-X86-O0: movl ___security_cookie, %[[REG1:[^ ]*]]
@@ -97,9 +102,13 @@ define void @test_vla(i32 %n) nounwind ssp {
 ; MSVC-X64: callq escape
 ; MSVC-X64: movq [[SLOT]](%rbp), %rcx
 ; MSVC-X64: xorq %rbp, %rcx
-; MSVC-X64: callq __security_check_cookie
+; MSVC-X64:	movq	__security_cookie(%rip), %rax
+; MSVC-X64:	cmpq	%rcx, %rax
+; MSVC-X64:	jne	.LBB1_2
 ; MSVC-X64: retq
-
+; MSVC-X64: LBB1_2
+; MSVC-X64: callq __security_check_cookie
+; MSVC-X64: int3
 
 ; This case is interesting because we address local variables with RBX but XOR
 ; the guard value with RBP. That's fine, either value will do, as long as they
@@ -148,11 +157,14 @@ define void @test_vla_realign(i32 %n) nounwind ssp {
 ; MSVC-X64: callq escape
 ; MSVC-X64: movq [[SLOT]](%rbx), %rcx
 ; MSVC-X64: xorq %rbp, %rcx
+; MSVC-X64: movq	__security_cookie(%rip), %rax
+; MSVC-X64: cmpq	%rcx, %rax
+; MSVC-X64: jne	.LBB2_2
+; MSVC-X64: retq 
 ; MSVC-X64: callq __security_check_cookie
-; MSVC-X64: retq
+; MSVC-X64: int3
 
 
 declare ptr @strcpy(ptr, ptr) nounwind
 
 declare i32 @printf(ptr, ...) nounwind
-
diff --git a/llvm/test/CodeGen/X86/tailcc-ssp.ll b/llvm/test/CodeGen/X86/tailcc-ssp.ll
index bb9b4429c0761..ad9f4b9d6a4b6 100644
--- a/llvm/test/CodeGen/X86/tailcc-ssp.ll
+++ b/llvm/test/CodeGen/X86/tailcc-ssp.ll
@@ -5,9 +5,20 @@ declare void @h(ptr, i64, ptr)
 
 define tailcc void @tailcall_frame(ptr %0, i64 %1) sspreq {
 ; WINDOWS-LABEL: tailcall_frame:
-; WINDOWS: callq __security_check_cookie
+; WINDOWS: movq	__security_cookie(%rip), %rax
+; WINDOWS: xorq	%rsp, %rax
+; WINDOWS: movq	%rax, {{[0-9]*}}(%rsp)
+; WINDOWS: movq	 {{[0-9]*}}(%rsp), %rcx
+; WINDOWS: xorq	%rsp, %rcx
+; WINDOWS: movq	__security_cookie(%rip), %rax
+; WINDOWS: cmpq	%rcx, %rax
+; WINDOWS: jne	.LBB0_1
 ; WINDOWS: xorl %ecx, %ecx
 ; WINDOWS: jmp h
+; WINDOWS: .LBB0_1
+; WINDOWS: callq __security_check_cookie
+; WINDOWS: int3
+
 
 ; LINUX-LABEL: tailcall_frame:
 ; LINUX: jne
@@ -22,10 +33,18 @@ declare void @bar()
 define void @tailcall_unrelated_frame() sspreq {
 ; WINDOWS-LABEL: tailcall_unrelated_frame:
 ; WINDOWS: subq [[STACK:\$.*]], %rsp
+; WINDOWS: movq	__security_cookie(%rip), %rax
+; WINDOWS: xorq	%rsp, %rax
 ; WINDOWS: callq bar
-; WINDOWS: callq __security_check_cookie
-; WINDOWS: addq [[STACK]], %rsp
-; WINDOWS: jmp bar
+; WINDOWS: movq	 {{[0-9]*}}(%rsp), %rcx
+; WINDOWS: xorq	%rsp, %rcx
+; WINDOWS: movq	__security_cookie(%rip), %rax
+; WINDOWS: cmpq	%rcx, %rax
+; WINDOWS: jne	.LBB1_1
+; WINDOWS: jmp	bar
+; WINDOWS: .LBB1_1
+; WINDOWS: callq	__security_check_cookie
+; WINDOWS: int3
 
 ; LINUX-LABEL: tailcall_unrelated_frame:
 ; LINUX: callq bar

>From 116978cb3ae8e69077da121f5b85464de5435ad7 Mon Sep 17 00:00:00 2001
From: mahesh-attarde <mahesh.attarde at intel.com>
Date: Tue, 18 Jun 2024 08:03:06 -0700
Subject: [PATCH 3/4] Revert "added regcall strct by reg support"

This reverts commit 6d6619f8f7a37906ac45791487a4d63b51a48ad1.
---
 clang/lib/CodeGen/Targets/X86.cpp | 20 ------------
 clang/test/CodeGen/regcall3.c     | 53 -------------------------------
 2 files changed, 73 deletions(-)
 delete mode 100644 clang/test/CodeGen/regcall3.c

diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp
index 506d106ad65b0..43dadf5e724ac 100644
--- a/clang/lib/CodeGen/Targets/X86.cpp
+++ b/clang/lib/CodeGen/Targets/X86.cpp
@@ -148,7 +148,6 @@ class X86_32ABIInfo : public ABIInfo {
 
   Class classify(QualType Ty) const;
   ABIArgInfo classifyReturnType(QualType RetTy, CCState &State) const;
-
   ABIArgInfo classifyArgumentType(QualType RetTy, CCState &State,
                                   unsigned ArgIndex) const;
 
@@ -1307,8 +1306,6 @@ class X86_64ABIInfo : public ABIInfo {
                                            unsigned &NeededSSE,
                                            unsigned &MaxVectorWidth) const;
 
-  bool DoesRegcallStructFitInReg(QualType Ty) const;
-
   bool IsIllegalVectorType(QualType Ty) const;
 
   /// The 0.98 ABI revision clarified a lot of ambiguities,
@@ -2833,20 +2830,6 @@ X86_64ABIInfo::classifyArgumentType(QualType Ty, unsigned freeIntRegs,
   return ABIArgInfo::getDirect(ResType);
 }
 
-bool X86_64ABIInfo::DoesRegcallStructFitInReg(QualType Ty) const {
-  auto RT = Ty->castAs<RecordType>();
-  // For Integer class, Max GPR Size is 64
-  if (getContext().getTypeSize(Ty) > 64)
-    return false;
-  // Struct At hand must not have other non Builtin types
-  for (const auto *FD : RT->getDecl()->fields()) {
-    QualType MTy = FD->getType();
-    if (!MTy->isBuiltinType())
-      return false;
-  }
-  return true;
-}
-
 ABIArgInfo
 X86_64ABIInfo::classifyRegCallStructTypeImpl(QualType Ty, unsigned &NeededInt,
                                              unsigned &NeededSSE,
@@ -2854,9 +2837,6 @@ X86_64ABIInfo::classifyRegCallStructTypeImpl(QualType Ty, unsigned &NeededInt,
   auto RT = Ty->getAs<RecordType>();
   assert(RT && "classifyRegCallStructType only valid with struct types");
 
-  if (DoesRegcallStructFitInReg(Ty))
-    return classifyArgumentType(Ty, UINT_MAX, NeededInt, NeededSSE, true, true);
-
   if (RT->getDecl()->hasFlexibleArrayMember())
     return getIndirectReturnResult(Ty);
 
diff --git a/clang/test/CodeGen/regcall3.c b/clang/test/CodeGen/regcall3.c
deleted file mode 100644
index 1c83407220861..0000000000000
--- a/clang/test/CodeGen/regcall3.c
+++ /dev/null
@@ -1,53 +0,0 @@
-// RUN: %clang_cc1 -S %s -o - -ffreestanding -triple=x86_64-unknown-linux-gnu | FileCheck %s --check-prefixes=LINUX64
-
-#include <xmmintrin.h>
-struct struct1 { int x; int y; };
-void __regcall v6(int a, float b, struct struct1 c) {}
-
-void v6_caller(){
-    struct struct1 c0;
-    c0.x = 0xa0a0; c0.y = 0xb0b0;
-    int x= 0xf0f0, y = 0x0f0f;
-    v6(x,y,c0);
-}
-
-// LINUX64-LABEL: __regcall3__v6
-// LINUX64: movq	%rcx, -8(%rsp)
-// LINUX64: movl	%eax, -12(%rsp)
-// LINUX64: movss	%xmm0, -16(%rsp)
-
-// LINUX64-LABEL: v6_caller
-// LINUX64: movl	$41120, 16(%rsp)                # imm = 0xA0A0
-// LINUX64: movl	$45232, 20(%rsp)                # imm = 0xB0B0
-// LINUX64: movl	$61680, 12(%rsp)                # imm = 0xF0F0
-// LINUX64: movl	$3855, 8(%rsp)                  # imm = 0xF0F
-// LINUX64: movl	12(%rsp), %eax
-// LINUX64: cvtsi2ssl	8(%rsp), %xmm0
-// LINUX64: movq	16(%rsp), %rcx
-// LINUX64: callq	.L__regcall3__v6$local
-
-
-struct struct2 { int x; float y; };
-void __regcall v31(int a, float b, struct struct2 c) {}
-
-void v31_caller(){
-    struct struct2 c0;
-    c0.x = 0xa0a0; c0.y = 0xb0b0;
-    int x= 0xf0f0, y = 0x0f0f;
-    v31(x,y,c0);
-}
-
-// LINUX64: __regcall3__v31:                        # @__regcall3__v31
-// LINUX64: 	movq	%rcx, -8(%rsp)
-// LINUX64: 	movl	%eax, -12(%rsp)
-// LINUX64: 	movss	%xmm0, -16(%rsp)
-// LINUX64: v31_caller:                             # @v31_caller
-// LINUX64: 	movl	$41120, 16(%rsp)                # imm = 0xA0A0
-// LINUX64: 	movss	.LCPI3_0(%rip), %xmm0           # xmm0 = [4.5232E+4,0.0E+0,0.0E+0,0.0E+0]
-// LINUX64: 	movss	%xmm0, 20(%rsp)
-// LINUX64: 	movl	$61680, 12(%rsp)                # imm = 0xF0F0
-// LINUX64: 	movl	$3855, 8(%rsp)                  # imm = 0xF0F
-// LINUX64: 	movl	12(%rsp), %eax
-// LINUX64: 	cvtsi2ssl	8(%rsp), %xmm0
-// LINUX64: 	movq	16(%rsp), %rcx
-// LINUX64: 	callq	.L__regcall3__v31$local

>From fbb566b1633150d3e3702f4abc18b53599ccda88 Mon Sep 17 00:00:00 2001
From: mahesh-attarde <mahesh.attarde at intel.com>
Date: Tue, 18 Jun 2024 12:26:05 -0700
Subject: [PATCH 4/4] address review comments for mov

---
 .../lib/Target/X86/X86FixupStackProtector.cpp |  20 +-
 llvm/test/CodeGen/X86/stack-protector-msvc.ll | 335 +++++++++++++++++-
 llvm/test/CodeGen/X86/tailcc-ssp.ll           | 114 ++++--
 3 files changed, 420 insertions(+), 49 deletions(-)

diff --git a/llvm/lib/Target/X86/X86FixupStackProtector.cpp b/llvm/lib/Target/X86/X86FixupStackProtector.cpp
index f1355c62cc2c1..d8c31e544d348 100644
--- a/llvm/lib/Target/X86/X86FixupStackProtector.cpp
+++ b/llvm/lib/Target/X86/X86FixupStackProtector.cpp
@@ -138,26 +138,20 @@ X86FixupStackProtectorPass::CreateFailCheckSequence(MachineBasicBlock *CurMBB,
   GlobalVariable *GV = M.getGlobalVariable("__security_cookie");
   assert(GV && " Security Cookie was not installed!");
 
-  MachineRegisterInfo &MRI = MF->getRegInfo();
   const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
 
   MachineInstr *GuardXor = SeqMI[0];
   MachineBasicBlock::iterator InsertPt(GuardXor);
   InsertPt++;
-  unsigned DestReg = MRI.createVirtualRegister(&X86::GR64RegClass);
-  // MOV security_cookie value into register
-  auto CMI =
-      BuildMI(*CurMBB, InsertPt, DebugLoc(), TII->get(X86::MOV64rm), DestReg)
-          .addReg(X86::RIP)
-          .addImm(1)
-          .addReg(X86::NoRegister)
-          .addGlobalAddress(GV)
-          .addReg(X86::NoRegister);
 
   // Compare security_Cookie with XOR_Val, if not same, we have violation
-  BuildMI(*CurMBB, InsertPt, DebugLoc(), TII->get(X86::CMP64rr))
-      .addReg(DestReg)
-      .addReg(GuardXor->getOperand(0).getReg());
+  auto CMI = BuildMI(*CurMBB, InsertPt, DebugLoc(), TII->get(X86::CMP64rm))
+                 .addReg(GuardXor->getOperand(0).getReg())
+                 .addReg(X86::RIP)
+                 .addImm(1)
+                 .addReg(X86::NoRegister)
+                 .addGlobalAddress(GV)
+                 .addReg(X86::NoRegister);
 
   BuildMI(*CurMBB, InsertPt, DebugLoc(), TII->get(X86::JCC_1))
       .addMBB(FailMBB)
diff --git a/llvm/test/CodeGen/X86/stack-protector-msvc.ll b/llvm/test/CodeGen/X86/stack-protector-msvc.ll
index f8eb47663fb18..75f8b613b1b95 100644
--- a/llvm/test/CodeGen/X86/stack-protector-msvc.ll
+++ b/llvm/test/CodeGen/X86/stack-protector-msvc.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
 ; RUN: llc -mtriple=i386-pc-windows-msvc < %s -o - | FileCheck -check-prefix=MSVC-X86 %s
 ; RUN: llc -mtriple=x86_64-pc-windows-msvc < %s -o - | FileCheck -check-prefix=MSVC-X64 %s
 
@@ -8,6 +9,100 @@
 @"\01LC" = internal constant [11 x i8] c"buf == %s\0A\00"    ; <ptr> [#uses=1]
 
 define void @test(ptr %a) nounwind ssp {
+; MSVC-X86-LABEL: test:
+; MSVC-X86:       # %bb.0: # %entry
+; MSVC-X86-NEXT:    pushl %esi
+; MSVC-X86-NEXT:    subl $12, %esp
+; MSVC-X86-NEXT:    movl ___security_cookie, %eax
+; MSVC-X86-NEXT:    xorl %esp, %eax
+; MSVC-X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; MSVC-X86-NEXT:    movl %esp, %esi
+; MSVC-X86-NEXT:    pushl {{[0-9]+}}(%esp)
+; MSVC-X86-NEXT:    pushl %esi
+; MSVC-X86-NEXT:    calll _strcpy
+; MSVC-X86-NEXT:    addl $8, %esp
+; MSVC-X86-NEXT:    pushl %esi
+; MSVC-X86-NEXT:    pushl $LC
+; MSVC-X86-NEXT:    calll _printf
+; MSVC-X86-NEXT:    addl $8, %esp
+; MSVC-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; MSVC-X86-NEXT:    xorl %esp, %ecx
+; MSVC-X86-NEXT:    calll @__security_check_cookie at 4
+; MSVC-X86-NEXT:    addl $12, %esp
+; MSVC-X86-NEXT:    popl %esi
+; MSVC-X86-NEXT:    retl
+;
+; MSVC-X64-LABEL: test:
+; MSVC-X64:       # %bb.0: # %entry
+; MSVC-X64-NEXT:    pushq %rsi
+; MSVC-X64-NEXT:    subq $64, %rsp
+; MSVC-X64-NEXT:    movq %rcx, %rdx
+; MSVC-X64-NEXT:    movq __security_cookie(%rip), %rax
+; MSVC-X64-NEXT:    xorq %rsp, %rax
+; MSVC-X64-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
+; MSVC-X64-NEXT:    movq %rcx, {{[0-9]+}}(%rsp)
+; MSVC-X64-NEXT:    leaq {{[0-9]+}}(%rsp), %rsi
+; MSVC-X64-NEXT:    movq %rsi, %rcx
+; MSVC-X64-NEXT:    callq strcpy
+; MSVC-X64-NEXT:    leaq LC(%rip), %rcx
+; MSVC-X64-NEXT:    movq %rsi, %rdx
+; MSVC-X64-NEXT:    callq printf
+; MSVC-X64-NEXT:    movq {{[0-9]+}}(%rsp), %rcx
+; MSVC-X64-NEXT:    xorq %rsp, %rcx
+; MSVC-X64-NEXT:    cmpq __security_cookie(%rip), %rcx
+; MSVC-X64-NEXT:    jne .LBB0_2
+; MSVC-X64-NEXT:  # %bb.1:
+; MSVC-X64-NEXT:    addq $64, %rsp
+; MSVC-X64-NEXT:    popq %rsi
+; MSVC-X64-NEXT:    retq
+; MSVC-X64-NEXT:  .LBB0_2:
+; MSVC-X64-NEXT:    callq __security_check_cookie
+; MSVC-X64-NEXT:    int3
+;
+; MSVC-X86-O0-LABEL: test:
+; MSVC-X86-O0:       # %bb.0: # %entry
+; MSVC-X86-O0-NEXT:    subl $20, %esp
+; MSVC-X86-O0-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; MSVC-X86-O0-NEXT:    movl ___security_cookie, %eax
+; MSVC-X86-O0-NEXT:    xorl %esp, %eax
+; MSVC-X86-O0-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; MSVC-X86-O0-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; MSVC-X86-O0-NEXT:    movl %esp, %eax
+; MSVC-X86-O0-NEXT:    movl %ecx, 4(%eax)
+; MSVC-X86-O0-NEXT:    leal {{[0-9]+}}(%esp), %ecx
+; MSVC-X86-O0-NEXT:    movl %ecx, (%eax)
+; MSVC-X86-O0-NEXT:    calll _strcpy
+; MSVC-X86-O0-NEXT:    leal LC, %ecx
+; MSVC-X86-O0-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; MSVC-X86-O0-NEXT:    movl %ecx, (%esp)
+; MSVC-X86-O0-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; MSVC-X86-O0-NEXT:    calll _printf
+; MSVC-X86-O0-NEXT:  # %bb.1: # %return
+; MSVC-X86-O0-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; MSVC-X86-O0-NEXT:    xorl %esp, %ecx
+; MSVC-X86-O0-NEXT:    calll @__security_check_cookie at 4
+; MSVC-X86-O0-NEXT:    addl $20, %esp
+; MSVC-X86-O0-NEXT:    retl
+;
+; MSVC-X64-O0-LABEL: test:
+; MSVC-X64-O0:       # %bb.0: # %entry
+; MSVC-X64-O0-NEXT:    subq $56, %rsp
+; MSVC-X64-O0-NEXT:    movq __security_cookie(%rip), %rax
+; MSVC-X64-O0-NEXT:    xorq %rsp, %rax
+; MSVC-X64-O0-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
+; MSVC-X64-O0-NEXT:    movq %rcx, {{[0-9]+}}(%rsp)
+; MSVC-X64-O0-NEXT:    movq {{[0-9]+}}(%rsp), %rdx
+; MSVC-X64-O0-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; MSVC-X64-O0-NEXT:    callq strcpy
+; MSVC-X64-O0-NEXT:    leaq LC(%rip), %rcx
+; MSVC-X64-O0-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
+; MSVC-X64-O0-NEXT:    callq printf
+; MSVC-X64-O0-NEXT:  # %bb.1: # %return
+; MSVC-X64-O0-NEXT:    movq {{[0-9]+}}(%rsp), %rcx
+; MSVC-X64-O0-NEXT:    xorq %rsp, %rcx
+; MSVC-X64-O0-NEXT:    callq __security_check_cookie
+; MSVC-X64-O0-NEXT:    addq $56, %rsp
+; MSVC-X64-O0-NEXT:    retq
 entry:
  %a_addr = alloca ptr    ; <ptr> [#uses=2]
  %buf = alloca [8 x i8]    ; <ptr> [#uses=2]
@@ -70,6 +165,107 @@ return:    ; preds = %entry
 declare void @escape(ptr)
 
 define void @test_vla(i32 %n) nounwind ssp {
+; MSVC-X86-LABEL: test_vla:
+; MSVC-X86:       # %bb.0:
+; MSVC-X86-NEXT:    pushl %ebp
+; MSVC-X86-NEXT:    movl %esp, %ebp
+; MSVC-X86-NEXT:    pushl %eax
+; MSVC-X86-NEXT:    movl 8(%ebp), %eax
+; MSVC-X86-NEXT:    movl ___security_cookie, %ecx
+; MSVC-X86-NEXT:    xorl %ebp, %ecx
+; MSVC-X86-NEXT:    movl %ecx, -4(%ebp)
+; MSVC-X86-NEXT:    shll $2, %eax
+; MSVC-X86-NEXT:    calll __chkstk
+; MSVC-X86-NEXT:    movl %esp, %eax
+; MSVC-X86-NEXT:    pushl %eax
+; MSVC-X86-NEXT:    calll _escape
+; MSVC-X86-NEXT:    addl $4, %esp
+; MSVC-X86-NEXT:    movl -4(%ebp), %ecx
+; MSVC-X86-NEXT:    xorl %ebp, %ecx
+; MSVC-X86-NEXT:    calll @__security_check_cookie at 4
+; MSVC-X86-NEXT:    movl %ebp, %esp
+; MSVC-X86-NEXT:    popl %ebp
+; MSVC-X86-NEXT:    retl
+;
+; MSVC-X64-LABEL: test_vla:
+; MSVC-X64:       # %bb.0:
+; MSVC-X64-NEXT:    pushq %rbp
+; MSVC-X64-NEXT:    subq $16, %rsp
+; MSVC-X64-NEXT:    leaq {{[0-9]+}}(%rsp), %rbp
+; MSVC-X64-NEXT:    movq __security_cookie(%rip), %rax
+; MSVC-X64-NEXT:    xorq %rbp, %rax
+; MSVC-X64-NEXT:    movq %rax, -8(%rbp)
+; MSVC-X64-NEXT:    movl %ecx, %eax
+; MSVC-X64-NEXT:    leaq 15(,%rax,4), %rax
+; MSVC-X64-NEXT:    andq $-16, %rax
+; MSVC-X64-NEXT:    callq __chkstk
+; MSVC-X64-NEXT:    subq %rax, %rsp
+; MSVC-X64-NEXT:    movq %rsp, %rcx
+; MSVC-X64-NEXT:    subq $32, %rsp
+; MSVC-X64-NEXT:    callq escape
+; MSVC-X64-NEXT:    addq $32, %rsp
+; MSVC-X64-NEXT:    movq -8(%rbp), %rcx
+; MSVC-X64-NEXT:    xorq %rbp, %rcx
+; MSVC-X64-NEXT:    cmpq __security_cookie(%rip), %rcx
+; MSVC-X64-NEXT:    jne .LBB1_2
+; MSVC-X64-NEXT:  # %bb.1:
+; MSVC-X64-NEXT:    movq %rbp, %rsp
+; MSVC-X64-NEXT:    popq %rbp
+; MSVC-X64-NEXT:    retq
+; MSVC-X64-NEXT:  .LBB1_2:
+; MSVC-X64-NEXT:    subq $32, %rsp
+; MSVC-X64-NEXT:    callq __security_check_cookie
+; MSVC-X64-NEXT:    addq $32, %rsp
+; MSVC-X64-NEXT:    int3
+;
+; MSVC-X86-O0-LABEL: test_vla:
+; MSVC-X86-O0:       # %bb.0:
+; MSVC-X86-O0-NEXT:    pushl %ebp
+; MSVC-X86-O0-NEXT:    movl %esp, %ebp
+; MSVC-X86-O0-NEXT:    pushl %eax
+; MSVC-X86-O0-NEXT:    movl 8(%ebp), %eax
+; MSVC-X86-O0-NEXT:    movl ___security_cookie, %ecx
+; MSVC-X86-O0-NEXT:    xorl %ebp, %ecx
+; MSVC-X86-O0-NEXT:    movl %ecx, -4(%ebp)
+; MSVC-X86-O0-NEXT:    shll $2, %eax
+; MSVC-X86-O0-NEXT:    calll __chkstk
+; MSVC-X86-O0-NEXT:    movl %esp, %eax
+; MSVC-X86-O0-NEXT:    subl $4, %esp
+; MSVC-X86-O0-NEXT:    movl %eax, (%esp)
+; MSVC-X86-O0-NEXT:    calll _escape
+; MSVC-X86-O0-NEXT:    addl $4, %esp
+; MSVC-X86-O0-NEXT:    movl -4(%ebp), %ecx
+; MSVC-X86-O0-NEXT:    xorl %ebp, %ecx
+; MSVC-X86-O0-NEXT:    calll @__security_check_cookie at 4
+; MSVC-X86-O0-NEXT:    movl %ebp, %esp
+; MSVC-X86-O0-NEXT:    popl %ebp
+; MSVC-X86-O0-NEXT:    retl
+;
+; MSVC-X64-O0-LABEL: test_vla:
+; MSVC-X64-O0:       # %bb.0:
+; MSVC-X64-O0-NEXT:    pushq %rbp
+; MSVC-X64-O0-NEXT:    subq $16, %rsp
+; MSVC-X64-O0-NEXT:    leaq {{[0-9]+}}(%rsp), %rbp
+; MSVC-X64-O0-NEXT:    movq __security_cookie(%rip), %rax
+; MSVC-X64-O0-NEXT:    xorq %rbp, %rax
+; MSVC-X64-O0-NEXT:    movq %rax, -8(%rbp)
+; MSVC-X64-O0-NEXT:    movl %ecx, %eax
+; MSVC-X64-O0-NEXT:    # kill: def $rax killed $eax
+; MSVC-X64-O0-NEXT:    leaq 15(,%rax,4), %rax
+; MSVC-X64-O0-NEXT:    andq $-16, %rax
+; MSVC-X64-O0-NEXT:    callq __chkstk
+; MSVC-X64-O0-NEXT:    subq %rax, %rsp
+; MSVC-X64-O0-NEXT:    movq %rsp, %rcx
+; MSVC-X64-O0-NEXT:    subq $32, %rsp
+; MSVC-X64-O0-NEXT:    callq escape
+; MSVC-X64-O0-NEXT:    addq $32, %rsp
+; MSVC-X64-O0-NEXT:    movq -8(%rbp), %rcx
+; MSVC-X64-O0-NEXT:    xorq %rbp, %rcx
+; MSVC-X64-O0-NEXT:    subq $32, %rsp
+; MSVC-X64-O0-NEXT:    callq __security_check_cookie
+; MSVC-X64-O0-NEXT:    movq %rbp, %rsp
+; MSVC-X64-O0-NEXT:    popq %rbp
+; MSVC-X64-O0-NEXT:    retq
   %vla = alloca i32, i32 %n
   call void @escape(ptr %vla)
   ret void
@@ -115,6 +311,143 @@ define void @test_vla(i32 %n) nounwind ssp {
 ; are the same across the life of the frame.
 
 define void @test_vla_realign(i32 %n) nounwind ssp {
+; MSVC-X86-LABEL: test_vla_realign:
+; MSVC-X86:       # %bb.0:
+; MSVC-X86-NEXT:    pushl %ebp
+; MSVC-X86-NEXT:    movl %esp, %ebp
+; MSVC-X86-NEXT:    pushl %edi
+; MSVC-X86-NEXT:    pushl %esi
+; MSVC-X86-NEXT:    andl $-32, %esp
+; MSVC-X86-NEXT:    subl $32, %esp
+; MSVC-X86-NEXT:    movl %esp, %esi
+; MSVC-X86-NEXT:    movl 8(%ebp), %eax
+; MSVC-X86-NEXT:    movl ___security_cookie, %ecx
+; MSVC-X86-NEXT:    xorl %ebp, %ecx
+; MSVC-X86-NEXT:    movl %ecx, 12(%esi)
+; MSVC-X86-NEXT:    shll $2, %eax
+; MSVC-X86-NEXT:    calll __chkstk
+; MSVC-X86-NEXT:    movl %esp, %edi
+; MSVC-X86-NEXT:    movl %esi, %eax
+; MSVC-X86-NEXT:    pushl %eax
+; MSVC-X86-NEXT:    calll _escape
+; MSVC-X86-NEXT:    addl $4, %esp
+; MSVC-X86-NEXT:    pushl %edi
+; MSVC-X86-NEXT:    calll _escape
+; MSVC-X86-NEXT:    addl $4, %esp
+; MSVC-X86-NEXT:    movl 12(%esi), %ecx
+; MSVC-X86-NEXT:    xorl %ebp, %ecx
+; MSVC-X86-NEXT:    calll @__security_check_cookie at 4
+; MSVC-X86-NEXT:    leal -8(%ebp), %esp
+; MSVC-X86-NEXT:    popl %esi
+; MSVC-X86-NEXT:    popl %edi
+; MSVC-X86-NEXT:    popl %ebp
+; MSVC-X86-NEXT:    retl
+;
+; MSVC-X64-LABEL: test_vla_realign:
+; MSVC-X64:       # %bb.0:
+; MSVC-X64-NEXT:    pushq %rbp
+; MSVC-X64-NEXT:    pushq %rsi
+; MSVC-X64-NEXT:    pushq %rbx
+; MSVC-X64-NEXT:    subq $32, %rsp
+; MSVC-X64-NEXT:    leaq {{[0-9]+}}(%rsp), %rbp
+; MSVC-X64-NEXT:    andq $-32, %rsp
+; MSVC-X64-NEXT:    movq %rsp, %rbx
+; MSVC-X64-NEXT:    movq __security_cookie(%rip), %rax
+; MSVC-X64-NEXT:    xorq %rbp, %rax
+; MSVC-X64-NEXT:    movq %rax, 24(%rbx)
+; MSVC-X64-NEXT:    movl %ecx, %eax
+; MSVC-X64-NEXT:    leaq 15(,%rax,4), %rax
+; MSVC-X64-NEXT:    andq $-16, %rax
+; MSVC-X64-NEXT:    callq __chkstk
+; MSVC-X64-NEXT:    subq %rax, %rsp
+; MSVC-X64-NEXT:    movq %rsp, %rsi
+; MSVC-X64-NEXT:    subq $32, %rsp
+; MSVC-X64-NEXT:    movq %rbx, %rcx
+; MSVC-X64-NEXT:    callq escape
+; MSVC-X64-NEXT:    movq %rsi, %rcx
+; MSVC-X64-NEXT:    callq escape
+; MSVC-X64-NEXT:    addq $32, %rsp
+; MSVC-X64-NEXT:    movq 24(%rbx), %rcx
+; MSVC-X64-NEXT:    xorq %rbp, %rcx
+; MSVC-X64-NEXT:    cmpq __security_cookie(%rip), %rcx
+; MSVC-X64-NEXT:    jne .LBB2_2
+; MSVC-X64-NEXT:  # %bb.1:
+; MSVC-X64-NEXT:    movq %rbp, %rsp
+; MSVC-X64-NEXT:    popq %rbx
+; MSVC-X64-NEXT:    popq %rsi
+; MSVC-X64-NEXT:    popq %rbp
+; MSVC-X64-NEXT:    retq
+; MSVC-X64-NEXT:  .LBB2_2:
+; MSVC-X64-NEXT:    subq $32, %rsp
+; MSVC-X64-NEXT:    callq __security_check_cookie
+; MSVC-X64-NEXT:    addq $32, %rsp
+; MSVC-X64-NEXT:    int3
+;
+; MSVC-X86-O0-LABEL: test_vla_realign:
+; MSVC-X86-O0:       # %bb.0:
+; MSVC-X86-O0-NEXT:    pushl %ebp
+; MSVC-X86-O0-NEXT:    movl %esp, %ebp
+; MSVC-X86-O0-NEXT:    pushl %esi
+; MSVC-X86-O0-NEXT:    andl $-32, %esp
+; MSVC-X86-O0-NEXT:    subl $64, %esp
+; MSVC-X86-O0-NEXT:    movl %esp, %esi
+; MSVC-X86-O0-NEXT:    movl 8(%ebp), %eax
+; MSVC-X86-O0-NEXT:    movl ___security_cookie, %ecx
+; MSVC-X86-O0-NEXT:    xorl %ebp, %ecx
+; MSVC-X86-O0-NEXT:    movl %ecx, 48(%esi)
+; MSVC-X86-O0-NEXT:    shll $2, %eax
+; MSVC-X86-O0-NEXT:    calll __chkstk
+; MSVC-X86-O0-NEXT:    movl %esp, %eax
+; MSVC-X86-O0-NEXT:    movl %eax, 28(%esi) # 4-byte Spill
+; MSVC-X86-O0-NEXT:    leal 32(%esi), %eax
+; MSVC-X86-O0-NEXT:    subl $4, %esp
+; MSVC-X86-O0-NEXT:    movl %eax, (%esp)
+; MSVC-X86-O0-NEXT:    calll _escape
+; MSVC-X86-O0-NEXT:    movl 28(%esi), %eax # 4-byte Reload
+; MSVC-X86-O0-NEXT:    movl %eax, (%esp)
+; MSVC-X86-O0-NEXT:    calll _escape
+; MSVC-X86-O0-NEXT:    addl $4, %esp
+; MSVC-X86-O0-NEXT:    movl 48(%esi), %ecx
+; MSVC-X86-O0-NEXT:    xorl %ebp, %ecx
+; MSVC-X86-O0-NEXT:    calll @__security_check_cookie at 4
+; MSVC-X86-O0-NEXT:    leal -4(%ebp), %esp
+; MSVC-X86-O0-NEXT:    popl %esi
+; MSVC-X86-O0-NEXT:    popl %ebp
+; MSVC-X86-O0-NEXT:    retl
+;
+; MSVC-X64-O0-LABEL: test_vla_realign:
+; MSVC-X64-O0:       # %bb.0:
+; MSVC-X64-O0-NEXT:    pushq %rbp
+; MSVC-X64-O0-NEXT:    pushq %rbx
+; MSVC-X64-O0-NEXT:    subq $72, %rsp
+; MSVC-X64-O0-NEXT:    leaq {{[0-9]+}}(%rsp), %rbp
+; MSVC-X64-O0-NEXT:    andq $-32, %rsp
+; MSVC-X64-O0-NEXT:    movq %rsp, %rbx
+; MSVC-X64-O0-NEXT:    movq __security_cookie(%rip), %rax
+; MSVC-X64-O0-NEXT:    xorq %rbp, %rax
+; MSVC-X64-O0-NEXT:    movq %rax, 64(%rbx)
+; MSVC-X64-O0-NEXT:    movl %ecx, %eax
+; MSVC-X64-O0-NEXT:    # kill: def $rax killed $eax
+; MSVC-X64-O0-NEXT:    leaq 15(,%rax,4), %rax
+; MSVC-X64-O0-NEXT:    andq $-16, %rax
+; MSVC-X64-O0-NEXT:    callq __chkstk
+; MSVC-X64-O0-NEXT:    subq %rax, %rsp
+; MSVC-X64-O0-NEXT:    movq %rsp, %rax
+; MSVC-X64-O0-NEXT:    movq %rax, 24(%rbx) # 8-byte Spill
+; MSVC-X64-O0-NEXT:    leaq 32(%rbx), %rcx
+; MSVC-X64-O0-NEXT:    subq $32, %rsp
+; MSVC-X64-O0-NEXT:    callq escape
+; MSVC-X64-O0-NEXT:    movq 24(%rbx), %rcx # 8-byte Reload
+; MSVC-X64-O0-NEXT:    callq escape
+; MSVC-X64-O0-NEXT:    addq $32, %rsp
+; MSVC-X64-O0-NEXT:    movq 64(%rbx), %rcx
+; MSVC-X64-O0-NEXT:    xorq %rbp, %rcx
+; MSVC-X64-O0-NEXT:    subq $32, %rsp
+; MSVC-X64-O0-NEXT:    callq __security_check_cookie
+; MSVC-X64-O0-NEXT:    leaq 8(%rbp), %rsp
+; MSVC-X64-O0-NEXT:    popq %rbx
+; MSVC-X64-O0-NEXT:    popq %rbp
+; MSVC-X64-O0-NEXT:    retq
   %realign = alloca i32, align 32
   %vla = alloca i32, i32 %n
   call void @escape(ptr %realign)
@@ -160,7 +493,7 @@ define void @test_vla_realign(i32 %n) nounwind ssp {
 ; MSVC-X64: movq	__security_cookie(%rip), %rax
 ; MSVC-X64: cmpq	%rcx, %rax
 ; MSVC-X64: jne	.LBB2_2
-; MSVC-X64: retq 
+; MSVC-X64: retq
 ; MSVC-X64: callq __security_check_cookie
 ; MSVC-X64: int3
 
diff --git a/llvm/test/CodeGen/X86/tailcc-ssp.ll b/llvm/test/CodeGen/X86/tailcc-ssp.ll
index ad9f4b9d6a4b6..1328e0cfa7124 100644
--- a/llvm/test/CodeGen/X86/tailcc-ssp.ll
+++ b/llvm/test/CodeGen/X86/tailcc-ssp.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
 ; RUN: llc -mtriple=x86_64-windows-msvc %s -o - -verify-machineinstrs | FileCheck %s -check-prefix=WINDOWS
 ; RUN: llc -mtriple=x86_64-linux-gnu    %s -o - -verify-machineinstrs | FileCheck %s -check-prefix=LINUX
 
@@ -5,25 +6,49 @@ declare void @h(ptr, i64, ptr)
 
 define tailcc void @tailcall_frame(ptr %0, i64 %1) sspreq {
 ; WINDOWS-LABEL: tailcall_frame:
-; WINDOWS: movq	__security_cookie(%rip), %rax
-; WINDOWS: xorq	%rsp, %rax
-; WINDOWS: movq	%rax, {{[0-9]*}}(%rsp)
-; WINDOWS: movq	 {{[0-9]*}}(%rsp), %rcx
-; WINDOWS: xorq	%rsp, %rcx
-; WINDOWS: movq	__security_cookie(%rip), %rax
-; WINDOWS: cmpq	%rcx, %rax
-; WINDOWS: jne	.LBB0_1
-; WINDOWS: xorl %ecx, %ecx
-; WINDOWS: jmp h
-; WINDOWS: .LBB0_1
-; WINDOWS: callq __security_check_cookie
-; WINDOWS: int3
+; WINDOWS:       # %bb.0:
+; WINDOWS-NEXT:    subq $56, %rsp
+; WINDOWS-NEXT:    .seh_stackalloc 56
+; WINDOWS-NEXT:    .seh_endprologue
+; WINDOWS-NEXT:    movq __security_cookie(%rip), %rax
+; WINDOWS-NEXT:    xorq %rsp, %rax
+; WINDOWS-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
+; WINDOWS-NEXT:    movq {{[0-9]+}}(%rsp), %rcx
+; WINDOWS-NEXT:    xorq %rsp, %rcx
+; WINDOWS-NEXT:    cmpq __security_cookie(%rip), %rcx
+; WINDOWS-NEXT:    jne .LBB0_1
+; WINDOWS-NEXT:  # %bb.2:
+; WINDOWS-NEXT:    xorl %ecx, %ecx
+; WINDOWS-NEXT:    xorl %edx, %edx
+; WINDOWS-NEXT:    xorl %r8d, %r8d
+; WINDOWS-NEXT:    addq $56, %rsp
+; WINDOWS-NEXT:    jmp h # TAILCALL
+; WINDOWS-NEXT:  .LBB0_1:
+; WINDOWS-NEXT:    callq __security_check_cookie
+; WINDOWS-NEXT:    int3
+; WINDOWS-NEXT:    .seh_endproc
+;
+; LINUX-LABEL: tailcall_frame:
+; LINUX:       # %bb.0:
+; LINUX-NEXT:    subq $24, %rsp
+; LINUX-NEXT:    .cfi_def_cfa_offset 32
+; LINUX-NEXT:    movq %fs:40, %rax
+; LINUX-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
+; LINUX-NEXT:    movq %fs:40, %rax
+; LINUX-NEXT:    cmpq {{[0-9]+}}(%rsp), %rax
+; LINUX-NEXT:    jne .LBB0_2
+; LINUX-NEXT:  # %bb.1: # %SP_return
+; LINUX-NEXT:    xorl %edi, %edi
+; LINUX-NEXT:    xorl %esi, %esi
+; LINUX-NEXT:    xorl %edx, %edx
+; LINUX-NEXT:    addq $24, %rsp
+; LINUX-NEXT:    .cfi_def_cfa_offset 8
+; LINUX-NEXT:    jmp h at PLT # TAILCALL
+; LINUX-NEXT:  .LBB0_2: # %CallStackCheckFailBlk
+; LINUX-NEXT:    .cfi_def_cfa_offset 32
+; LINUX-NEXT:    callq __stack_chk_fail at PLT
 
 
-; LINUX-LABEL: tailcall_frame:
-; LINUX: jne
-; LINUX: jmp h
-; LINUX: callq __stack_chk_fail
 
    tail call tailcc void @h(ptr null, i64 0, ptr null)
    ret void
@@ -32,25 +57,44 @@ define tailcc void @tailcall_frame(ptr %0, i64 %1) sspreq {
 declare void @bar()
 define void @tailcall_unrelated_frame() sspreq {
 ; WINDOWS-LABEL: tailcall_unrelated_frame:
-; WINDOWS: subq [[STACK:\$.*]], %rsp
-; WINDOWS: movq	__security_cookie(%rip), %rax
-; WINDOWS: xorq	%rsp, %rax
-; WINDOWS: callq bar
-; WINDOWS: movq	 {{[0-9]*}}(%rsp), %rcx
-; WINDOWS: xorq	%rsp, %rcx
-; WINDOWS: movq	__security_cookie(%rip), %rax
-; WINDOWS: cmpq	%rcx, %rax
-; WINDOWS: jne	.LBB1_1
-; WINDOWS: jmp	bar
-; WINDOWS: .LBB1_1
-; WINDOWS: callq	__security_check_cookie
-; WINDOWS: int3
-
+; WINDOWS:       # %bb.0:
+; WINDOWS-NEXT:    subq $40, %rsp
+; WINDOWS-NEXT:    .seh_stackalloc 40
+; WINDOWS-NEXT:    .seh_endprologue
+; WINDOWS-NEXT:    movq __security_cookie(%rip), %rax
+; WINDOWS-NEXT:    xorq %rsp, %rax
+; WINDOWS-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
+; WINDOWS-NEXT:    callq bar
+; WINDOWS-NEXT:    movq {{[0-9]+}}(%rsp), %rcx
+; WINDOWS-NEXT:    xorq %rsp, %rcx
+; WINDOWS-NEXT:    cmpq __security_cookie(%rip), %rcx
+; WINDOWS-NEXT:    jne .LBB1_1
+; WINDOWS-NEXT:  # %bb.2:
+; WINDOWS-NEXT:    addq $40, %rsp
+; WINDOWS-NEXT:    jmp bar # TAILCALL
+; WINDOWS-NEXT:  .LBB1_1:
+; WINDOWS-NEXT:    callq __security_check_cookie
+; WINDOWS-NEXT:    int3
+; WINDOWS-NEXT:    .seh_endproc
+;
 ; LINUX-LABEL: tailcall_unrelated_frame:
-; LINUX: callq bar
-; LINUX: jne
-; LINUX: jmp bar
-; LINUX: callq __stack_chk_fail
+; LINUX:       # %bb.0:
+; LINUX-NEXT:    pushq %rax
+; LINUX-NEXT:    .cfi_def_cfa_offset 16
+; LINUX-NEXT:    movq %fs:40, %rax
+; LINUX-NEXT:    movq %rax, (%rsp)
+; LINUX-NEXT:    callq bar at PLT
+; LINUX-NEXT:    movq %fs:40, %rax
+; LINUX-NEXT:    cmpq (%rsp), %rax
+; LINUX-NEXT:    jne .LBB1_2
+; LINUX-NEXT:  # %bb.1: # %SP_return
+; LINUX-NEXT:    popq %rax
+; LINUX-NEXT:    .cfi_def_cfa_offset 8
+; LINUX-NEXT:    jmp bar at PLT # TAILCALL
+; LINUX-NEXT:  .LBB1_2: # %CallStackCheckFailBlk
+; LINUX-NEXT:    .cfi_def_cfa_offset 16
+; LINUX-NEXT:    callq __stack_chk_fail at PLT
+
 
   call void @bar()
   tail call void @bar()



More information about the cfe-commits mailing list