From 7476f9c5134a7170ca53561d20e9a19adef251f8 Mon Sep 17 00:00:00 2001 From: Pete Cooper Date: Mon, 27 Oct 2014 19:40:35 +0000 Subject: [PATCH 1/1] Stackmap shadows should consider call returns a branch target. To avoid emitting too many nops, a stackmap shadow can include emitted instructions in the shadow, but these must not include branch targets. A return from a call should count as a branch target as patching over the instructions after the call would lead to incorrect behaviour for threads currently making that call, when they return. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@220710 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86MCInstLower.cpp | 6 ++++++ test/CodeGen/X86/stackmap-shadow-optimization.ll | 10 ++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/Target/X86/X86MCInstLower.cpp b/lib/Target/X86/X86MCInstLower.cpp index fc3662e6bec..85cf5144f0c 100644 --- a/lib/Target/X86/X86MCInstLower.cpp +++ b/lib/Target/X86/X86MCInstLower.cpp @@ -1210,4 +1210,10 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) { MCInst TmpInst; MCInstLowering.Lower(MI, TmpInst); EmitAndCountInstruction(TmpInst); + + // Stackmap shadows cannot include branch targets, so we can count the bytes + // in a call towards the shadow, but must flush the shadow immediately after + // to account for the return from the call. + if (MI->isCall()) + SMShadowTracker.emitShadowPadding(OutStreamer, getSubtargetInfo()); } diff --git a/test/CodeGen/X86/stackmap-shadow-optimization.ll b/test/CodeGen/X86/stackmap-shadow-optimization.ll index 6f7c5935b8f..f640b9e6f6c 100644 --- a/test/CodeGen/X86/stackmap-shadow-optimization.ll +++ b/test/CodeGen/X86/stackmap-shadow-optimization.ll @@ -1,16 +1,18 @@ ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7 | FileCheck %s -; Check that the X86 stackmap shadow optimization is only outputting a 1-byte -; nop here. 8-bytes are requested, but 7 are covered by the code for the call to -; bar, the frame teardown and the return. +; Check that the X86 stackmap shadow optimization is only outputting a 3-byte +; nop here. 8-bytes are requested, but 5 are covered by the code for the call to +; bar. However, the frame teardown and the return do not count towards the +; stackmap shadow as the call return counts as a branch target so must flush +; the shadow. define void @shadow_optimization_test() { entry: ; CHECK-LABEL: shadow_optimization_test: ; CHECK: callq _bar ; CHECK-NOT: nop ; CHECK: callq _bar -; CHECK: retq ; CHECK: nop +; CHECK: retq call void @bar() tail call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 0, i32 8) call void @bar() -- 2.34.1