summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManman Ren <manman.ren@gmail.com>2016-01-15 19:35:42 +0000
committerManman Ren <manman.ren@gmail.com>2016-01-15 19:35:42 +0000
commit4fe01bd8f96e4be0b83049b0cb17f4fd125476db (patch)
tree3f6be08d289064f93ca90acabc385181ef051c56
parent285d7bd4e78c2fdd03b714910776785264e5f6a9 (diff)
downloadbcm5719-llvm-4fe01bd8f96e4be0b83049b0cb17f4fd125476db.tar.gz
bcm5719-llvm-4fe01bd8f96e4be0b83049b0cb17f4fd125476db.zip
CXX_FAST_TLS calling convention: fix issue on X86-64.
When we have a single basic block, the explicit copy-back instructions should be inserted right before the terminator. Before this fix, they were wrongly placed at the beginning of the basic block. I will commit fixes to other platforms as well. PR26136 llvm-svn: 257925
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp9
-rw-r--r--llvm/test/CodeGen/X86/cxx_tlscc64.ll15
2 files changed, 20 insertions, 4 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index b723059f091..6904714ec78 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -28908,6 +28908,7 @@ void X86TargetLowering::insertCopiesSplitCSR(
const TargetInstrInfo *TII = Subtarget->getInstrInfo();
MachineRegisterInfo *MRI = &Entry->getParent()->getRegInfo();
+ MachineBasicBlock::iterator MBBI = Entry->begin();
for (const MCPhysReg *I = IStart; *I; ++I) {
const TargetRegisterClass *RC = nullptr;
if (X86::GR64RegClass.contains(*I))
@@ -28925,13 +28926,13 @@ void X86TargetLowering::insertCopiesSplitCSR(
Attribute::NoUnwind) &&
"Function should be nounwind in insertCopiesSplitCSR!");
Entry->addLiveIn(*I);
- BuildMI(*Entry, Entry->begin(), DebugLoc(), TII->get(TargetOpcode::COPY),
- NewVR)
+ BuildMI(*Entry, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY), NewVR)
.addReg(*I);
+ // Insert the copy-back instructions right before the terminator.
for (auto *Exit : Exits)
- BuildMI(*Exit, Exit->begin(), DebugLoc(), TII->get(TargetOpcode::COPY),
- *I)
+ BuildMI(*Exit, Exit->getFirstTerminator(), DebugLoc(),
+ TII->get(TargetOpcode::COPY), *I)
.addReg(NewVR);
}
}
diff --git a/llvm/test/CodeGen/X86/cxx_tlscc64.ll b/llvm/test/CodeGen/X86/cxx_tlscc64.ll
index 70fe501040b..7f6e0d71cd7 100644
--- a/llvm/test/CodeGen/X86/cxx_tlscc64.ll
+++ b/llvm/test/CodeGen/X86/cxx_tlscc64.ll
@@ -9,6 +9,7 @@
@sg = internal thread_local global %struct.S zeroinitializer, align 1
@__dso_handle = external global i8
@__tls_guard = internal thread_local unnamed_addr global i1 false
+@sum1 = internal thread_local global i32 0, align 4
declare void @_ZN1SC1Ev(%struct.S*)
declare void @_ZN1SD1Ev(%struct.S*)
@@ -50,3 +51,17 @@ init.i:
__tls_init.exit:
ret %struct.S* @sg
}
+
+; CHECK-LABEL: _ZTW4sum1
+; CHECK-NOT: pushq %r11
+; CHECK-NOT: pushq %r10
+; CHECK-NOT: pushq %r9
+; CHECK-NOT: pushq %r8
+; CHECK-NOT: pushq %rsi
+; CHECK-NOT: pushq %rdx
+; CHECK-NOT: pushq %rcx
+; CHECK-NOT: pushq %rbx
+; CHECK: callq
+define cxx_fast_tlscc nonnull i32* @_ZTW4sum1() nounwind {
+ ret i32* @sum1
+}
OpenPOWER on IntegriCloud