llvm.org GIT mirror llvm / 77a84a9
findDeadCallerSavedReg needs to pay attention to calling convention Caller saved regs differ between SysV and Win64. Use the tail call available set to scavenge from. Refactor register info to create new helper to get at tail call GPRs. Added a new test case for windows. Fixed up a number of X64 tests since now RCX is preferred over RDX on SysV. Differential Revision: http://reviews.llvm.org/D14878 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253927 91177308-0d34-0410-b5e6-96231b3b80d8 Andy Ayers 4 years ago
12 changed file(s) with 86 addition(s) and 46 deletion(s). Raw diff Collapse all Expand all
145145 /// to this register without worry about clobbering it.
146146 static unsigned findDeadCallerSavedReg(MachineBasicBlock &MBB,
147147 MachineBasicBlock::iterator &MBBI,
148 const TargetRegisterInfo *TRI,
148 const X86RegisterInfo *TRI,
149149 bool Is64Bit) {
150150 const MachineFunction *MF = MBB.getParent();
151151 const Function *F = MF->getFunction();
152152 if (!F || MF->getMMI().callsEHReturn())
153153 return 0;
154154
155 static const uint16_t CallerSavedRegs32Bit[] = {
156 X86::EAX, X86::EDX, X86::ECX, 0
157 };
158
159 static const uint16_t CallerSavedRegs64Bit[] = {
160 X86::RAX, X86::RDX, X86::RCX, X86::RSI, X86::RDI,
161 X86::R8, X86::R9, X86::R10, X86::R11, 0
162 };
155 const TargetRegisterClass &AvailableRegs = *TRI->getGPRsForTailCall(*MF);
163156
164157 unsigned Opc = MBBI->getOpcode();
165158 switch (Opc) {
188181 Uses.insert(*AI);
189182 }
190183
191 const uint16_t *CS = Is64Bit ? CallerSavedRegs64Bit : CallerSavedRegs32Bit;
192 for (; *CS; ++CS)
193 if (!Uses.count(*CS))
194 return *CS;
184 for (auto CS : AvailableRegs)
185 if (!Uses.count(CS) && CS != X86::RIP)
186 return CS;
195187 }
196188 }
197189
176176 return &X86::GR64_NOREX_NOSPRegClass;
177177 return &X86::GR32_NOREX_NOSPRegClass;
178178 case 4: // Available for tailcall (not callee-saved GPRs).
179 const Function *F = MF.getFunction();
180 if (IsWin64 || (F && F->getCallingConv() == CallingConv::X86_64_Win64))
181 return &X86::GR64_TCW64RegClass;
182 else if (Is64Bit)
183 return &X86::GR64_TCRegClass;
184
185 bool hasHipeCC = (F ? F->getCallingConv() == CallingConv::HiPE : false);
186 if (hasHipeCC)
187 return &X86::GR32RegClass;
188 return &X86::GR32_TCRegClass;
189 }
179 return getGPRsForTailCall(MF);
180 }
181 }
182
183 const TargetRegisterClass *
184 X86RegisterInfo::getGPRsForTailCall(const MachineFunction &MF) const {
185 const Function *F = MF.getFunction();
186 if (IsWin64 || (F && F->getCallingConv() == CallingConv::X86_64_Win64))
187 return &X86::GR64_TCW64RegClass;
188 else if (Is64Bit)
189 return &X86::GR64_TCRegClass;
190
191 bool hasHipeCC = (F ? F->getCallingConv() == CallingConv::HiPE : false);
192 if (hasHipeCC)
193 return &X86::GR32RegClass;
194 return &X86::GR32_TCRegClass;
190195 }
191196
192197 const TargetRegisterClass *
8686 const TargetRegisterClass *
8787 getCrossCopyRegClass(const TargetRegisterClass *RC) const override;
8888
89 /// getGPRsForTailCall - Returns a register class with registers that can be
90 /// used in forming tail calls.
91 const TargetRegisterClass *
92 getGPRsForTailCall(const MachineFunction &MF) const;
93
8994 unsigned getRegPressureLimit(const TargetRegisterClass *RC,
9095 MachineFunction &MF) const override;
9196
374374 def GR64_TC : RegisterClass<"X86", [i64], 64, (add RAX, RCX, RDX, RSI, RDI,
375375 R8, R9, R11, RIP)>;
376376 def GR64_TCW64 : RegisterClass<"X86", [i64], 64, (add RAX, RCX, RDX,
377 R8, R9, R11)>;
377 R8, R9, R10, R11)>;
378378
379379 // GR8_NOREX - GR8 registers which do not require a REX prefix.
380380 def GR8_NOREX : RegisterClass<"X86", [i8], 8,
2323 ; X64: movq my_emutls_v_xyz@GOTPCREL(%rip), %rdi
2424 ; X64-NEXT: callq my_emutls_get_address@PLT
2525 ; X64-NEXT: movl (%rax), %eax
26 ; X64-NEXT: popq %rdx
26 ; X64-NEXT: popq %rcx
2727 ; X64-NEXT: retq
2828
2929 entry:
4949 ; X64: movq __emutls_v.i@GOTPCREL(%rip), %rdi
5050 ; X64-NEXT: callq __emutls_get_address@PLT
5151 ; X64-NEXT: movl (%rax), %eax
52 ; X64-NEXT: popq %rdx
52 ; X64-NEXT: popq %rcx
5353 ; X64-NEXT: retq
5454
5555 entry:
2020 ; X64: movl $my_emutls_v_xyz, %edi
2121 ; X64-NEXT: callq my_emutls_get_address
2222 ; X64-NEXT: movl (%rax), %eax
23 ; X64-NEXT: popq %rdx
23 ; X64-NEXT: popq %rcx
2424 ; X64-NEXT: retq
2525
2626 entry:
4949 ; X64: movl $__emutls_v.i1, %edi
5050 ; X64-NEXT: callq __emutls_get_address
5151 ; X64-NEXT: movl (%rax), %eax
52 ; X64-NEXT: popq %rdx
52 ; X64-NEXT: popq %rcx
5353 ; X64-NEXT: retq
5454
5555 entry:
6666 ; X64-LABEL: f2:
6767 ; X64: movl $__emutls_v.i1, %edi
6868 ; X64-NEXT: callq __emutls_get_address
69 ; X64-NEXT: popq %rdx
69 ; X64-NEXT: popq %rcx
7070 ; X64-NEXT: retq
7171
7272 entry:
7676 ; CHECK-LIBCALL-NEXT: movzwl (%rdi), %edi
7777 ; CHECK-LIBCALL-NEXT: callq __gnu_h2f_ieee
7878 ; CHECK-LIBCALL-NEXT: cvttss2si %xmm0, %rax
79 ; CHECK-LIBCALL-NEXT: popq %rdx
79 ; CHECK-LIBCALL-NEXT: popq %rcx
8080 ; CHECK-LIBCALL-NEXT: retq
8181
8282 ; CHECK-F16C-NEXT: movswl (%rdi), [[REG0:%[a-z0-9]+]]
126126 ; CHECK-LIBCALL-NEXT: cvttss2si %xmm0, [[REG5:%[a-z0-9]+]]
127127 ; CHECK-LIBCALL-NEXT: ucomiss [[REG1]], %xmm0
128128 ; CHECK-LIBCALL-NEXT: cmovaeq [[REG4]], [[REG5]]
129 ; CHECK-LIBCALL-NEXT: popq %rdx
129 ; CHECK-LIBCALL-NEXT: popq %rcx
130130 ; CHECK-LIBCALL-NEXT: retq
131131
132132 ; CHECK-F16C-NEXT: movswl (%rdi), [[REG0:%[a-z0-9]+]]
1515 ; CHECK: movq %rdi, (%rsp)
1616 ; CHECK: callq return_i1
1717 ; CHECK: movq (%rsp), %rax
18 ; CHECK: popq %rdx
18 ; CHECK: popq %rcx
1919 ; CHECK: retq
2020 entry:
2121 %alloca = alloca i32 addrspace(1)*, align 8
3232 ; CHECK: movq %rdi, (%rsp)
3333 ; CHECK: callq return_i1
3434 ; CHECK: xorl %eax, %eax
35 ; CHECK: popq %rdx
35 ; CHECK: popq %rcx
3636 ; CHECK: retq
3737 entry:
3838 %alloca = alloca i32 addrspace(1)*, align 8
1919 ; state arguments to the statepoint
2020 ; CHECK: pushq %rax
2121 ; CHECK: callq return_i1
22 ; CHECK: popq %rdx
22 ; CHECK: popq %rcx
2323 ; CHECK: retq
2424 entry:
2525 %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)
3131 ; CHECK-LABEL: test_i32_return
3232 ; CHECK: pushq %rax
3333 ; CHECK: callq return_i32
34 ; CHECK: popq %rdx
34 ; CHECK: popq %rcx
3535 ; CHECK: retq
3636 entry:
3737 %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)
4343 ; CHECK-LABEL: test_i32ptr_return
4444 ; CHECK: pushq %rax
4545 ; CHECK: callq return_i32ptr
46 ; CHECK: popq %rdx
46 ; CHECK: popq %rcx
4747 ; CHECK: retq
4848 entry:
4949 %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)
8181 ; CHECK: pushq %rax
8282 ; CHECK: callq return_i1
8383 ; CHECK-NEXT: .Ltmp11:
84 ; CHECK-NEXT: popq %rdx
84 ; CHECK-NEXT: popq %rcx
8585 ; CHECK-NEXT: retq
8686 entry:
8787 %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)
106106 ; A patchable variant of test_i1_return
107107 ; CHECK: pushq %rax
108108 ; CHECK: nopl
109 ; CHECK: popq %rdx
109 ; CHECK: popq %rcx
110110 ; CHECK: retq
111111 entry:
112112 %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)
1717 ; state arguments to the statepoint
1818 ; CHECK: pushq %rax
1919 ; CHECK: callq return_i1
20 ; CHECK: popq %rdx
20 ; CHECK: popq %rcx
2121 ; CHECK: retq
2222 entry:
2323 %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)
2929 ; CHECK-LABEL: test_i32_return
3030 ; CHECK: pushq %rax
3131 ; CHECK: callq return_i32
32 ; CHECK: popq %rdx
32 ; CHECK: popq %rcx
3333 ; CHECK: retq
3434 entry:
3535 %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)
4141 ; CHECK-LABEL: test_i32ptr_return
4242 ; CHECK: pushq %rax
4343 ; CHECK: callq return_i32ptr
44 ; CHECK: popq %rdx
44 ; CHECK: popq %rcx
4545 ; CHECK: retq
4646 entry:
4747 %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)
6767 ; CHECK: pushq %rax
6868 ; CHECK: callq return_i1
6969 ; CHECK-NEXT: .Ltmp9:
70 ; CHECK-NEXT: popq %rdx
70 ; CHECK-NEXT: popq %rcx
7171 ; CHECK-NEXT: retq
7272 entry:
7373 %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)
9191 ; CHECK-LABEL: test_transition_args
9292 ; CHECK: pushq %rax
9393 ; CHECK: callq return_i32
94 ; CHECK: popq %rdx
94 ; CHECK: popq %rcx
9595 ; CHECK: retq
9696 entry:
9797 %val = alloca i32
104104 ; CHECK-LABEL: test_transition_args_2
105105 ; CHECK: pushq %rax
106106 ; CHECK: callq return_i32
107 ; CHECK: popq %rdx
107 ; CHECK: popq %rcx
108108 ; CHECK: retq
109109 entry:
110110 %val = alloca i32
36953695 ; X32-SSE41-NEXT: .cfi_def_cfa_offset 8
36963696 ; X32-SSE41-NEXT: pmovsxbw %xmm0, %xmm0
36973697 ; X32-SSE41-NEXT: movd %xmm0, %eax
3698 ; X32-SSE41-NEXT: popl %edx
3698 ; X32-SSE41-NEXT: popl %ecx
36993699 ; X32-SSE41-NEXT: retl
37003700 entry:
37013701 %Shuf = shufflevector <16 x i8> %A, <16 x i8> undef, <2 x i32>
0 ; RUN: llc < %s -mtriple=x86_64-pc-win32-coreclr | FileCheck %s -check-prefix=WIN_X64
1 ; RUN: llc < %s -mtriple=x86_64-pc-linux | FileCheck %s -check-prefix=LINUX
2
3 %Object = type <{ [0 x i64*]* }>
4
5 define void @C1(%Object addrspace(1)* %param0) gc "coreclr" {
6 entry:
7
8 ; WIN_X64: # BB#0:
9 ; WIN_X64: pushq %rax
10 ; LINUX: # BB#0: # %entry
11 ; LINUX: movq $0, -8(%rsp)
12
13 %this = alloca %Object addrspace(1)*
14 store %Object addrspace(1)* null, %Object addrspace(1)** %this
15 store %Object addrspace(1)* %param0, %Object addrspace(1)** %this
16 br label %0
17
18 ;
19 %1 = load %Object addrspace(1)*, %Object addrspace(1)** %this, align 8
20
21 ; WIN_X64: xorl %r8d, %r8d
22 ; WIN_X64: popq %rax
23 ; WIN_X64: rex64 jmp C2 # TAILCALL
24 ; LINUX: xorl %edx, %edx
25 ; LINUX: jmp C2 # TAILCALL
26
27 tail call void @C2(%Object addrspace(1)* %1, i32 0, %Object addrspace(1)* null)
28 ret void
29 }
30
31 declare void @C2(%Object addrspace(1)*, i32, %Object addrspace(1)*)
32
33 ; Function Attrs: nounwind
34 declare void @llvm.localescape(...) #0
35
36 attributes #0 = { nounwind }
37