diff options
| -rw-r--r-- | llvm/lib/Target/X86/X86FrameLowering.cpp | 18 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86RegisterInfo.cpp | 25 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86RegisterInfo.h | 5 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86RegisterInfo.td | 2 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/emutls-pie.ll | 4 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/emutls.ll | 6 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/half.ll | 4 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/statepoint-allocas.ll | 4 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/statepoint-call-lowering.ll | 10 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/statepoint-gctransition-call-lowering.ll | 12 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/vector-sext.ll | 2 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/win64_sibcall.ll | 38 |
12 files changed, 85 insertions, 45 deletions
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp index 4fbe3613d1e..c7f71478f38 100644 --- a/llvm/lib/Target/X86/X86FrameLowering.cpp +++ b/llvm/lib/Target/X86/X86FrameLowering.cpp @@ -146,21 +146,14 @@ static unsigned getLEArOpcode(unsigned IsLP64) { /// to this register without worry about clobbering it. static unsigned findDeadCallerSavedReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, - const TargetRegisterInfo *TRI, + const X86RegisterInfo *TRI, bool Is64Bit) { const MachineFunction *MF = MBB.getParent(); const Function *F = MF->getFunction(); if (!F || MF->getMMI().callsEHReturn()) return 0; - static const uint16_t CallerSavedRegs32Bit[] = { - X86::EAX, X86::EDX, X86::ECX, 0 - }; - - static const uint16_t CallerSavedRegs64Bit[] = { - X86::RAX, X86::RDX, X86::RCX, X86::RSI, X86::RDI, - X86::R8, X86::R9, X86::R10, X86::R11, 0 - }; + const TargetRegisterClass &AvailableRegs = *TRI->getGPRsForTailCall(*MF); unsigned Opc = MBBI->getOpcode(); switch (Opc) { @@ -189,10 +182,9 @@ static unsigned findDeadCallerSavedReg(MachineBasicBlock &MBB, Uses.insert(*AI); } - const uint16_t *CS = Is64Bit ? CallerSavedRegs64Bit : CallerSavedRegs32Bit; - for (; *CS; ++CS) - if (!Uses.count(*CS)) - return *CS; + for (auto CS : AvailableRegs) + if (!Uses.count(CS) && CS != X86::RIP) + return CS; } } diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp index 8b4bbac7007..39de5004143 100644 --- a/llvm/lib/Target/X86/X86RegisterInfo.cpp +++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp @@ -177,20 +177,25 @@ X86RegisterInfo::getPointerRegClass(const MachineFunction &MF, return &X86::GR64_NOREX_NOSPRegClass; return &X86::GR32_NOREX_NOSPRegClass; case 4: // Available for tailcall (not callee-saved GPRs). - const Function *F = MF.getFunction(); - if (IsWin64 || (F && F->getCallingConv() == CallingConv::X86_64_Win64)) - return &X86::GR64_TCW64RegClass; - else if (Is64Bit) - return &X86::GR64_TCRegClass; - - bool hasHipeCC = (F ? F->getCallingConv() == CallingConv::HiPE : false); - if (hasHipeCC) - return &X86::GR32RegClass; - return &X86::GR32_TCRegClass; + return getGPRsForTailCall(MF); } } const TargetRegisterClass * +X86RegisterInfo::getGPRsForTailCall(const MachineFunction &MF) const { + const Function *F = MF.getFunction(); + if (IsWin64 || (F && F->getCallingConv() == CallingConv::X86_64_Win64)) + return &X86::GR64_TCW64RegClass; + else if (Is64Bit) + return &X86::GR64_TCRegClass; + + bool hasHipeCC = (F ? F->getCallingConv() == CallingConv::HiPE : false); + if (hasHipeCC) + return &X86::GR32RegClass; + return &X86::GR32_TCRegClass; +} + +const TargetRegisterClass * X86RegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const { if (RC == &X86::CCRRegClass) { if (Is64Bit) diff --git a/llvm/lib/Target/X86/X86RegisterInfo.h b/llvm/lib/Target/X86/X86RegisterInfo.h index 1b1a1ccfc1a..c3a2845c362 100644 --- a/llvm/lib/Target/X86/X86RegisterInfo.h +++ b/llvm/lib/Target/X86/X86RegisterInfo.h @@ -87,6 +87,11 @@ public: const TargetRegisterClass * getCrossCopyRegClass(const TargetRegisterClass *RC) const override; + /// getGPRsForTailCall - Returns a register class with registers that can be + /// used in forming tail calls. + const TargetRegisterClass * + getGPRsForTailCall(const MachineFunction &MF) const; + unsigned getRegPressureLimit(const TargetRegisterClass *RC, MachineFunction &MF) const override; diff --git a/llvm/lib/Target/X86/X86RegisterInfo.td b/llvm/lib/Target/X86/X86RegisterInfo.td index 6c74dcbff5b..12f38c7946a 100644 --- a/llvm/lib/Target/X86/X86RegisterInfo.td +++ b/llvm/lib/Target/X86/X86RegisterInfo.td @@ -375,7 +375,7 @@ def GR32_TC : RegisterClass<"X86", [i32], 32, (add EAX, ECX, EDX)>; def GR64_TC : RegisterClass<"X86", [i64], 64, (add RAX, RCX, RDX, RSI, RDI, R8, R9, R11, RIP)>; def GR64_TCW64 : RegisterClass<"X86", [i64], 64, (add RAX, RCX, RDX, - R8, R9, R11)>; + R8, R9, R10, R11)>; // GR8_NOREX - GR8 registers which do not require a REX prefix. def GR8_NOREX : RegisterClass<"X86", [i8], 8, diff --git a/llvm/test/CodeGen/X86/emutls-pie.ll b/llvm/test/CodeGen/X86/emutls-pie.ll index 4970b14838c..45e5c38c0d8 100644 --- a/llvm/test/CodeGen/X86/emutls-pie.ll +++ b/llvm/test/CodeGen/X86/emutls-pie.ll @@ -24,7 +24,7 @@ define i32 @my_get_xyz() { ; X64: movq my_emutls_v_xyz@GOTPCREL(%rip), %rdi ; X64-NEXT: callq my_emutls_get_address@PLT ; X64-NEXT: movl (%rax), %eax -; X64-NEXT: popq %rdx +; X64-NEXT: popq %rcx ; X64-NEXT: retq entry: @@ -50,7 +50,7 @@ define i32 @f1() { ; X64: movq __emutls_v.i@GOTPCREL(%rip), %rdi ; X64-NEXT: callq __emutls_get_address@PLT ; X64-NEXT: movl (%rax), %eax -; X64-NEXT: popq %rdx +; X64-NEXT: popq %rcx ; X64-NEXT: retq entry: diff --git a/llvm/test/CodeGen/X86/emutls.ll b/llvm/test/CodeGen/X86/emutls.ll index bb2f1e2aa82..9266fe962df 100644 --- a/llvm/test/CodeGen/X86/emutls.ll +++ b/llvm/test/CodeGen/X86/emutls.ll @@ -21,7 +21,7 @@ define i32 @my_get_xyz() { ; X64: movl $my_emutls_v_xyz, %edi ; X64-NEXT: callq my_emutls_get_address ; X64-NEXT: movl (%rax), %eax -; X64-NEXT: popq %rdx +; X64-NEXT: popq %rcx ; X64-NEXT: retq entry: @@ -50,7 +50,7 @@ define i32 @f1() { ; X64: movl $__emutls_v.i1, %edi ; X64-NEXT: callq __emutls_get_address ; X64-NEXT: movl (%rax), %eax -; X64-NEXT: popq %rdx +; X64-NEXT: popq %rcx ; X64-NEXT: retq entry: @@ -67,7 +67,7 @@ define i32* @f2() { ; X64-LABEL: f2: ; X64: movl $__emutls_v.i1, %edi ; X64-NEXT: callq __emutls_get_address -; X64-NEXT: popq %rdx +; X64-NEXT: popq %rcx ; X64-NEXT: retq entry: diff --git a/llvm/test/CodeGen/X86/half.ll b/llvm/test/CodeGen/X86/half.ll index 8a726370f19..3b2518e28f5 100644 --- a/llvm/test/CodeGen/X86/half.ll +++ b/llvm/test/CodeGen/X86/half.ll @@ -77,7 +77,7 @@ define i64 @test_fptosi_i64(half* %p) #0 { ; CHECK-LIBCALL-NEXT: movzwl (%rdi), %edi ; CHECK-LIBCALL-NEXT: callq __gnu_h2f_ieee ; CHECK-LIBCALL-NEXT: cvttss2si %xmm0, %rax -; CHECK-LIBCALL-NEXT: popq %rdx +; CHECK-LIBCALL-NEXT: popq %rcx ; CHECK-LIBCALL-NEXT: retq ; CHECK-F16C-NEXT: movswl (%rdi), [[REG0:%[a-z0-9]+]] @@ -127,7 +127,7 @@ define i64 @test_fptoui_i64(half* %p) #0 { ; CHECK-LIBCALL-NEXT: cvttss2si %xmm0, [[REG5:%[a-z0-9]+]] ; CHECK-LIBCALL-NEXT: ucomiss [[REG1]], %xmm0 ; CHECK-LIBCALL-NEXT: cmovaeq [[REG4]], [[REG5]] -; CHECK-LIBCALL-NEXT: popq %rdx +; CHECK-LIBCALL-NEXT: popq %rcx ; CHECK-LIBCALL-NEXT: retq ; CHECK-F16C-NEXT: movswl (%rdi), [[REG0:%[a-z0-9]+]] diff --git a/llvm/test/CodeGen/X86/statepoint-allocas.ll b/llvm/test/CodeGen/X86/statepoint-allocas.ll index 4af33e1f547..61c972f1743 100644 --- a/llvm/test/CodeGen/X86/statepoint-allocas.ll +++ b/llvm/test/CodeGen/X86/statepoint-allocas.ll @@ -16,7 +16,7 @@ define i32 addrspace(1)* @test(i32 addrspace(1)* %ptr) gc "statepoint-example" { ; CHECK: movq %rdi, (%rsp) ; CHECK: callq return_i1 ; CHECK: movq (%rsp), %rax -; CHECK: popq %rdx +; CHECK: popq %rcx ; CHECK: retq entry: %alloca = alloca i32 addrspace(1)*, align 8 @@ -33,7 +33,7 @@ define i32 addrspace(1)* @test2(i32 addrspace(1)* %ptr) gc "statepoint-example" ; CHECK: movq %rdi, (%rsp) ; CHECK: callq return_i1 ; CHECK: xorl %eax, %eax -; CHECK: popq %rdx +; CHECK: popq %rcx ; CHECK: retq entry: %alloca = alloca i32 addrspace(1)*, align 8 diff --git a/llvm/test/CodeGen/X86/statepoint-call-lowering.ll b/llvm/test/CodeGen/X86/statepoint-call-lowering.ll index 14e7da721ca..df386b551d8 100644 --- a/llvm/test/CodeGen/X86/statepoint-call-lowering.ll +++ b/llvm/test/CodeGen/X86/statepoint-call-lowering.ll @@ -20,7 +20,7 @@ define i1 @test_i1_return() gc "statepoint-example" { ; state arguments to the statepoint ; CHECK: pushq %rax ; CHECK: callq return_i1 -; CHECK: popq %rdx +; CHECK: popq %rcx ; CHECK: retq entry: %safepoint_token = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) @@ -32,7 +32,7 @@ define i32 @test_i32_return() gc "statepoint-example" { ; CHECK-LABEL: test_i32_return ; CHECK: pushq %rax ; CHECK: callq return_i32 -; CHECK: popq %rdx +; CHECK: popq %rcx ; CHECK: retq entry: %safepoint_token = tail call i32 (i64, i32, i32 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32f(i64 0, i32 0, i32 ()* @return_i32, i32 0, i32 0, i32 0, i32 0) @@ -44,7 +44,7 @@ define i32* @test_i32ptr_return() gc "statepoint-example" { ; CHECK-LABEL: test_i32ptr_return ; CHECK: pushq %rax ; CHECK: callq return_i32ptr -; CHECK: popq %rdx +; CHECK: popq %rcx ; CHECK: retq entry: %safepoint_token = tail call i32 (i64, i32, i32* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p0i32f(i64 0, i32 0, i32* ()* @return_i32ptr, i32 0, i32 0, i32 0, i32 0) @@ -82,7 +82,7 @@ define i1 @test_relocate(i32 addrspace(1)* %a) gc "statepoint-example" { ; CHECK: pushq %rax ; CHECK: callq return_i1 ; CHECK-NEXT: .Ltmp11: -; CHECK-NEXT: popq %rdx +; CHECK-NEXT: popq %rcx ; CHECK-NEXT: retq entry: %safepoint_token = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* %a) @@ -107,7 +107,7 @@ define i1 @test_i1_return_patchable() gc "statepoint-example" { ; A patchable variant of test_i1_return ; CHECK: pushq %rax ; CHECK: nopl -; CHECK: popq %rdx +; CHECK: popq %rcx ; CHECK: retq entry: %safepoint_token = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 3, i1 ()*null, i32 0, i32 0, i32 0, i32 0) diff --git a/llvm/test/CodeGen/X86/statepoint-gctransition-call-lowering.ll b/llvm/test/CodeGen/X86/statepoint-gctransition-call-lowering.ll index 61b8ded2c47..c0bb8ce40c2 100644 --- a/llvm/test/CodeGen/X86/statepoint-gctransition-call-lowering.ll +++ b/llvm/test/CodeGen/X86/statepoint-gctransition-call-lowering.ll @@ -18,7 +18,7 @@ define i1 @test_i1_return() gc "statepoint-example" { ; state arguments to the statepoint ; CHECK: pushq %rax ; CHECK: callq return_i1 -; CHECK: popq %rdx +; CHECK: popq %rcx ; CHECK: retq entry: %safepoint_token = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 1, i32 0, i32 0) @@ -30,7 +30,7 @@ define i32 @test_i32_return() gc "statepoint-example" { ; CHECK-LABEL: test_i32_return ; CHECK: pushq %rax ; CHECK: callq return_i32 -; CHECK: popq %rdx +; CHECK: popq %rcx ; CHECK: retq entry: %safepoint_token = tail call i32 (i64, i32, i32 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32f(i64 0, i32 0, i32 ()* @return_i32, i32 0, i32 1, i32 0, i32 0) @@ -42,7 +42,7 @@ define i32* @test_i32ptr_return() gc "statepoint-example" { ; CHECK-LABEL: test_i32ptr_return ; CHECK: pushq %rax ; CHECK: callq return_i32ptr -; CHECK: popq %rdx +; CHECK: popq %rcx ; CHECK: retq entry: %safepoint_token = tail call i32 (i64, i32, i32* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p0i32f(i64 0, i32 0, i32* ()* @return_i32ptr, i32 0, i32 1, i32 0, i32 0) @@ -68,7 +68,7 @@ define i1 @test_relocate(i32 addrspace(1)* %a) gc "statepoint-example" { ; CHECK: pushq %rax ; CHECK: callq return_i1 ; CHECK-NEXT: .Ltmp9: -; CHECK-NEXT: popq %rdx +; CHECK-NEXT: popq %rcx ; CHECK-NEXT: retq entry: %safepoint_token = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 1, i32 0, i32 0, i32 addrspace(1)* %a) @@ -92,7 +92,7 @@ define i32 @test_transition_args() gc "statepoint-example" { ; CHECK-LABEL: test_transition_args ; CHECK: pushq %rax ; CHECK: callq return_i32 -; CHECK: popq %rdx +; CHECK: popq %rcx ; CHECK: retq entry: %val = alloca i32 @@ -105,7 +105,7 @@ define i32 @test_transition_args_2() gc "statepoint-example" { ; CHECK-LABEL: test_transition_args_2 ; CHECK: pushq %rax ; CHECK: callq return_i32 -; CHECK: popq %rdx +; CHECK: popq %rcx ; CHECK: retq entry: %val = alloca i32 diff --git a/llvm/test/CodeGen/X86/vector-sext.ll b/llvm/test/CodeGen/X86/vector-sext.ll index 4f1cfdfd4b0..bcf8a2ab164 100644 --- a/llvm/test/CodeGen/X86/vector-sext.ll +++ b/llvm/test/CodeGen/X86/vector-sext.ll @@ -3696,7 +3696,7 @@ define i32 @sext_2i8_to_i32(<16 x i8> %A) nounwind uwtable readnone ssp { ; X32-SSE41-NEXT: .cfi_def_cfa_offset 8 ; X32-SSE41-NEXT: pmovsxbw %xmm0, %xmm0 ; X32-SSE41-NEXT: movd %xmm0, %eax -; X32-SSE41-NEXT: popl %edx +; X32-SSE41-NEXT: popl %ecx ; X32-SSE41-NEXT: retl entry: %Shuf = shufflevector <16 x i8> %A, <16 x i8> undef, <2 x i32> <i32 0, i32 1> diff --git a/llvm/test/CodeGen/X86/win64_sibcall.ll b/llvm/test/CodeGen/X86/win64_sibcall.ll new file mode 100644 index 00000000000..4001f638c2a --- /dev/null +++ b/llvm/test/CodeGen/X86/win64_sibcall.ll @@ -0,0 +1,38 @@ +; RUN: llc < %s -mtriple=x86_64-pc-win32-coreclr | FileCheck %s -check-prefix=WIN_X64 +; RUN: llc < %s -mtriple=x86_64-pc-linux | FileCheck %s -check-prefix=LINUX + +%Object = type <{ [0 x i64*]* }> + +define void @C1(%Object addrspace(1)* %param0) gc "coreclr" { +entry: + +; WIN_X64: # BB#0: +; WIN_X64: pushq %rax +; LINUX: # BB#0: # %entry +; LINUX: movq $0, -8(%rsp) + + %this = alloca %Object addrspace(1)* + store %Object addrspace(1)* null, %Object addrspace(1)** %this + store %Object addrspace(1)* %param0, %Object addrspace(1)** %this + br label %0 + +; <label>:0 ; preds = %entry + %1 = load %Object addrspace(1)*, %Object addrspace(1)** %this, align 8 + +; WIN_X64: xorl %r8d, %r8d +; WIN_X64: popq %rax +; WIN_X64: rex64 jmp C2 # TAILCALL +; LINUX: xorl %edx, %edx +; LINUX: jmp C2 # TAILCALL + + tail call void @C2(%Object addrspace(1)* %1, i32 0, %Object addrspace(1)* null) + ret void +} + +declare void @C2(%Object addrspace(1)*, i32, %Object addrspace(1)*) + +; Function Attrs: nounwind +declare void @llvm.localescape(...) #0 + +attributes #0 = { nounwind } + |

