Skip to content

Commit 0a432ed

Browse files
LuoYuankeYuanke Luo
authored andcommitted
[FastIsel] Get the right register type for call instruction (llvm#164565)
When switch from fast isel to dag isel the input value is from llvm IR instruction. If the instruction is call we should get the calling convention of the callee and pass it to RegsForValue::getCopyFromRegs, so that it can deduce the right RegisterVT of the returned value of the callee. --------- Co-authored-by: Yuanke Luo <[email protected]>
1 parent 5bbfa26 commit 0a432ed

File tree

2 files changed

+72
-1
lines changed

2 files changed

+72
-1
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1977,8 +1977,13 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) {
19771977
if (const Instruction *Inst = dyn_cast<Instruction>(V)) {
19781978
Register InReg = FuncInfo.InitializeRegForValue(Inst);
19791979

1980+
std::optional<CallingConv::ID> CallConv;
1981+
auto *CI = dyn_cast<CallInst>(Inst);
1982+
if (CI && !CI->isInlineAsm())
1983+
CallConv = CI->getCallingConv();
1984+
19801985
RegsForValue RFV(*DAG.getContext(), TLI, DAG.getDataLayout(), InReg,
1981-
Inst->getType(), std::nullopt);
1986+
Inst->getType(), CallConv);
19821987
SDValue Chain = DAG.getEntryNode();
19831988
return RFV.getCopyFromRegs(DAG, FuncInfo, getCurSDLoc(), Chain, nullptr, V);
19841989
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
2+
; RUN: llc --fast-isel < %s -mtriple=x86_64-unknown-unknown | FileCheck %s
3+
4+
define i8 @test_direct_call(ptr %f) nounwind {
5+
; CHECK-LABEL: test_direct_call:
6+
; CHECK: # %bb.0: # %entry
7+
; CHECK-NEXT: pushq %rax
8+
; CHECK-NEXT: callq foo@PLT
9+
; CHECK-NEXT: callq bar@PLT
10+
; CHECK-NEXT: popq %rcx
11+
; CHECK-NEXT: retq
12+
entry:
13+
%call = call bfloat @foo(ptr %f)
14+
%call2 = call zeroext i8 @bar(bfloat %call)
15+
ret i8 %call2
16+
}
17+
18+
define i8 @test_fast_direct_call(ptr %f) nounwind {
19+
; CHECK-LABEL: test_fast_direct_call:
20+
; CHECK: # %bb.0: # %entry
21+
; CHECK-NEXT: pushq %rax
22+
; CHECK-NEXT: callq foo_fast@PLT
23+
; CHECK-NEXT: callq bar@PLT
24+
; CHECK-NEXT: popq %rcx
25+
; CHECK-NEXT: retq
26+
entry:
27+
%call = call fastcc bfloat @foo_fast(ptr %f)
28+
%call2 = call zeroext i8 @bar(bfloat %call)
29+
ret i8 %call2
30+
}
31+
32+
define i8 @test_indirect_all(ptr %fptr, ptr %f) nounwind {
33+
; CHECK-LABEL: test_indirect_all:
34+
; CHECK: # %bb.0: # %entry
35+
; CHECK-NEXT: pushq %rbx
36+
; CHECK-NEXT: movq %rdi, %rbx
37+
; CHECK-NEXT: movq %rsi, %rdi
38+
; CHECK-NEXT: callq foo@PLT
39+
; CHECK-NEXT: callq *%rbx
40+
; CHECK-NEXT: popq %rbx
41+
; CHECK-NEXT: retq
42+
entry:
43+
%call = call bfloat @foo(ptr %f)
44+
%call2 = call zeroext i8 %fptr(bfloat %call)
45+
ret i8 %call2
46+
}
47+
48+
define i8 @test_fast_indirect_all(ptr %fptr, ptr %f) nounwind {
49+
; CHECK-LABEL: test_fast_indirect_all:
50+
; CHECK: # %bb.0: # %entry
51+
; CHECK-NEXT: pushq %rbx
52+
; CHECK-NEXT: movq %rdi, %rbx
53+
; CHECK-NEXT: movq %rsi, %rdi
54+
; CHECK-NEXT: callq foo@PLT
55+
; CHECK-NEXT: callq *%rbx
56+
; CHECK-NEXT: popq %rbx
57+
; CHECK-NEXT: retq
58+
entry:
59+
%call = call fastcc bfloat @foo(ptr %f)
60+
%call2 = call zeroext i8 %fptr(bfloat %call)
61+
ret i8 %call2
62+
}
63+
64+
declare bfloat @foo(ptr %f)
65+
declare zeroext i8 @bar(bfloat)
66+
declare fastcc bfloat @foo_fast(ptr %f)

0 commit comments

Comments
 (0)