Skip to content

Commit

Permalink
Remove external call from v3 and use pointer value directly
Browse files Browse the repository at this point in the history
  • Loading branch information
LucasSte committed Dec 18, 2024
1 parent 92e78eb commit 2152515
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 28 deletions.
13 changes: 4 additions & 9 deletions llvm/lib/Target/SBF/SBFISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -599,15 +599,10 @@ SDValue SBFTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
G->getOffset(), 0);
} else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {
Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, 0);
} else if (ConstantSDNode * CNode = dyn_cast<ConstantSDNode>(Callee)) {
uint64_t Cte = CNode->getZExtValue();
uint64_t U32Max = static_cast<uint64_t>
(std::numeric_limits<uint32_t>::max());
if (Subtarget->getHasStaticSyscalls() && Cte >= U32Max - MaxSyscall) {
NodeCode = SBFISD::SYSCALL;
uint64_t SyscallCode = U32Max - Cte;
Callee = DAG.getConstant(SyscallCode, CLI.DL, MVT::i64);
}
} else if (isa<ConstantSDNode>(Callee) && Subtarget->getHasStaticSyscalls()) {
// When static syscalls are enabled and we have a constant operand for call,
// we emit a syscall.
NodeCode = SBFISD::SYSCALL;
}

// Returns a chain & a flag for retval copy to use.
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/SBF/SBFInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -963,7 +963,7 @@ def : Pat<(i64 (and (i64 GPR:$src), 0xffffFFFF)),
// Calls
def : Pat<(SBFcall tglobaladdr:$dst), (JAL tglobaladdr:$dst)>;
def : Pat<(SBFcall texternalsym:$dst), (JAL texternalsym:$dst)>;
def : Pat<(SBFcall imm:$dst), (JAL imm:$dst)>;
def : Pat<(SBFcall imm:$dst), (JAL imm:$dst)>, Requires<[SBFNoStaticSyscalls]>;
def : Pat<(SBFcall GPR:$dst), (JALX GPR:$dst)>, Requires<[SBFNoCallxSrc]>;
def : Pat<(SBFcall GPR:$dst), (JALX_v2 GPR:$dst)>, Requires<[SBFCallxSrc]>;
def : Pat<(SBFSyscall imm:$imm), (SYSCALL_v3 imm:$imm)>, Requires<[SBFHasStaticSyscalls]>;
Expand Down
15 changes: 9 additions & 6 deletions llvm/test/CodeGen/SBF/call_internal.ll
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
; RUN: llc < %s -march=sbf --show-mc-encoding | FileCheck --check-prefix=CHECK-ASM %s
; RUN: llc -march=sbf --filetype=obj -o - %s | llvm-objdump -d - | FileCheck --check-prefix=CHECK-OBJ %s
; RUN: llc < %s -march=sbf -mcpu=sbfv2 --show-mc-encoding | FileCheck --check-prefix=CHECK-ASM %s
; RUN: llc < %s -march=sbf --show-mc-encoding | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-V0 %s
; RUN: llc -march=sbf --filetype=obj -o - %s | llvm-objdump -d - | FileCheck --check-prefixes=CHECK-OBJ,CHECK-OBJ-V0 %s
; RUN: llc < %s -march=sbf -mcpu=sbfv2 --show-mc-encoding | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-V3 %s
; RUN: llc -march=sbf -mcpu=sbfv2 --filetype=obj -o - %s | llvm-objdump -d -
; | FileCheck --check-prefix=CHECK-OBJ %s
; | FileCheck --check-prefixes=CHECK-OBJ,CHECK-OBJ-V3 %s

@.str = private unnamed_addr constant [5 x i8] c"foo\0A\00", align 1

Expand All @@ -16,8 +16,11 @@ entry:
; Function Attrs: nounwind
define dso_local i64 @entrypoint(ptr noundef %input) local_unnamed_addr #1 {
entry:
; CHECK-ASM: call 1811268606 # encoding: [0x85,0x00,0x00,0x00,0xfe,0xc3,0xf5,0x6b]
; CHECK-OBJ: 85 00 00 00 fe c3 f5 6b call 0x6bf5c3fe
; CHECK-ASM-V0: call 1811268606 # encoding: [0x85,0x00,0x00,0x00,0xfe,0xc3,0xf5,0x6b]
; CHECK-ASM-V3: syscall 1811268606 # encoding: [0x95,0x00,0x00,0x00,0xfe,0xc3,0xf5,0x6b]

; CHECK-OBJ-V0: 85 00 00 00 fe c3 f5 6b call 0x6bf5c3fe
; CHECK-OBJ-V3: 95 00 00 00 fe c3 f5 6b syscall 0x6bf5c3fe

tail call void inttoptr (i64 1811268606 to ptr)(ptr noundef nonnull @.str, i64 noundef 4) #3
%add.ptr = getelementptr inbounds i8, ptr %input, i64 4
Expand Down
24 changes: 12 additions & 12 deletions llvm/test/CodeGen/SBF/static_syscall.ll
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
; RUN: llc -march=sbf < %s | FileCheck --check-prefix=CHECK-V1 %s
; RUN: llc -march=sbf -mattr=+static-syscalls -show-mc-encoding < %s | FileCheck --check-prefix=CHECK-V2 %s
; RUN: llc -march=sbf < %s | FileCheck --check-prefix=CHECK-V0 %s
; RUN: llc -march=sbf -mattr=+static-syscalls -show-mc-encoding < %s | FileCheck --check-prefix=CHECK-V3 %s


; Function Attrs: nounwind
define dso_local i32 @test(i32 noundef %a, i32 noundef %b) {
entry:
; CHECK-LABEL: test

; CHECK-V1: call -2
; CHECK-V2: syscall 1 # encoding: [0x95,0x00,0x00,0x00,0x01,0x00,0x00,0x00]
%syscall_1 = tail call i32 inttoptr (i64 4294967294 to ptr)(i32 noundef %a, i32 noundef %b)
; CHECK-V0: call 2
; CHECK-V3 syscall 2 # encoding: [0x95,0x00,0x00,0x00,0x01,0x00,0x00,0x00]
%syscall_1 = tail call i32 inttoptr (i64 2 to ptr)(i32 noundef %a, i32 noundef %b)

; CHECK-V1: call -12
; CHECK-V2: syscall 11 # encoding: [0x95,0x00,0x00,0x00,0x0b,0x00,0x00,0x00]
%syscall_2 = tail call i32 inttoptr (i64 4294967284 to ptr)(i32 noundef %a, i32 noundef %b)
; CHECK-V0: call 11
; CHECK-V3: syscall 11 # encoding: [0x95,0x00,0x00,0x00,0x0b,0x00,0x00,0x00]
%syscall_2 = tail call i32 inttoptr (i64 11 to ptr)(i32 noundef %a, i32 noundef %b)

; CHECK-V1: call -112
; CHECK-V2: call -112
%not_syscall = tail call i32 inttoptr (i64 4294967184 to ptr)(i32 noundef %a, i32 noundef %b)
; CHECK-V0: call 112
; CHECK-V3: syscall 112
%syscall_3 = tail call i32 inttoptr (i64 112 to ptr)(i32 noundef %a, i32 noundef %b)

%add_1 = add i32 %syscall_1, %syscall_2
%add_2 = add i32 %add_1, %not_syscall
%add_2 = add i32 %add_1, %syscall_3
ret i32 %add_1
}
50 changes: 50 additions & 0 deletions llvm/test/CodeGen/SBF/static_syscall_2.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
; RUN: llc -march=sbf -mattr=+static-syscalls < %s | FileCheck --check-prefix=CHECK %s

; Syscall declaration in C:
;
; int c_declaration(int a, int b) {
; int (*const syscall)(int a, int b) = (void*)50;
; return syscall(a, b);
; }
; The following is the unoptimized output from clang:

define dso_local i32 @c_declaration(i32 noundef %a, i32 noundef %b) #0 {
entry:
%a.addr = alloca i32, align 4
%b.addr = alloca i32, align 4
%syscall = alloca ptr, align 8
store i32 %a, ptr %a.addr, align 4
store i32 %b, ptr %b.addr, align 4
store ptr inttoptr (i64 50 to ptr), ptr %syscall, align 8
%0 = load i32, ptr %a.addr, align 4
%1 = load i32, ptr %b.addr, align 4

; Ensure the syscall instruction is emitted
; CHECK: syscall 50

%call = call i32 inttoptr (i64 50 to ptr)(i32 noundef %0, i32 noundef %1)
ret i32 %call
}

; Syscall declaration in Rust:
;
; #[no_mangle]
; pub unsafe fn rust_declaration(b: u64) -> u32 {
; let syscall : extern "C" fn(b: u64) -> u32 = core::mem::transmute(60u64);
; return syscall(b);
; }
; The following is the unoptimized output from rustc:

define i32 @rust_declaration(i64 %b) unnamed_addr {
start:
%syscall.dbg.spill = alloca [8 x i8], align 8
%b.dbg.spill = alloca [8 x i8], align 8
store i64 %b, ptr %b.dbg.spill, align 8
store ptr getelementptr (i8, ptr null, i64 60), ptr %syscall.dbg.spill, align 8

; Ensure the syscall instruction is emitted
; CHECK: syscall 60

%_0 = call i32 getelementptr (i8, ptr null, i64 60)(i64 %b)
ret i32 %_0
}

0 comments on commit 2152515

Please sign in to comment.