Skip to content

Commit 4808ce5

Browse files
committed
Allow libcalls in BPF
1 parent 21e0b56 commit 4808ce5

File tree

8 files changed

+79
-6
lines changed

8 files changed

+79
-6
lines changed

llvm/lib/Target/BPF/BPF.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ def MisalignedMemAccess : SubtargetFeature<"allows-misaligned-mem-access",
3131
"AllowsMisalignedMemAccess", "true",
3232
"Allows misaligned memory access">;
3333

34+
def AllowBuiltinCall : SubtargetFeature<"allow-builtin-calls",
35+
"AllowBuiltinCalls", "true",
36+
"Allow calls to builtin functions">;
37+
3438
def : Proc<"generic", []>;
3539
def : Proc<"v1", []>;
3640
def : Proc<"v2", []>;

llvm/lib/Target/BPF/BPFISelLowering.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ BPFTargetLowering::BPFTargetLowering(const TargetMachine &TM,
208208
HasMovsx = STI.hasMovsx();
209209

210210
AllowsMisalignedMemAccess = STI.getAllowsMisalignedMemAccess();
211+
AllowBuiltinCalls = STI.getAllowBuiltinCalls();
211212
}
212213

213214
bool BPFTargetLowering::allowsMisalignedMemoryAccesses(EVT VT, unsigned, Align,
@@ -567,9 +568,11 @@ SDValue BPFTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
567568
} else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {
568569
if (StringRef(E->getSymbol()) != BPF_TRAP) {
569570
Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, 0);
570-
fail(CLI.DL, DAG,
571-
Twine("A call to built-in function '" + StringRef(E->getSymbol()) +
572-
"' is not supported."));
571+
if (!AllowBuiltinCalls) {
572+
fail(CLI.DL, DAG,
573+
Twine("A call to built-in function '" + StringRef(E->getSymbol()) +
574+
"' is not supported."));
575+
}
573576
}
574577
}
575578

@@ -1196,3 +1199,18 @@ bool BPFTargetLowering::isLegalAddressingMode(const DataLayout &DL,
11961199

11971200
return true;
11981201
}
1202+
1203+
bool BPFTargetLowering::shouldSignExtendTypeInLibCall(Type *Ty,
1204+
bool IsSigned) const {
1205+
return IsSigned || Ty->isIntegerTy(32);
1206+
}
1207+
1208+
bool BPFTargetLowering::CanLowerReturn(
1209+
CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
1210+
const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
1211+
const Type *RetTy) const {
1212+
// At minimal return Outs.size() <= 1, or check valid types in CC.
1213+
SmallVector<CCValAssign, 16> RVLocs;
1214+
CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
1215+
return CCInfo.CheckReturn(Outs, getHasAlu32() ? RetCC_BPF32 : RetCC_BPF64);
1216+
}

llvm/lib/Target/BPF/BPFISelLowering.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ class BPFTargetLowering : public TargetLowering {
6868
// Allows Misalignment
6969
bool AllowsMisalignedMemAccess;
7070

71+
bool AllowBuiltinCalls;
72+
7173
SDValue LowerSDIVSREM(SDValue Op, SelectionDAG &DAG) const;
7274
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
7375
SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
@@ -163,6 +165,14 @@ class BPFTargetLowering : public TargetLowering {
163165
MachineBasicBlock *
164166
EmitInstrWithCustomInserterLDimm64(MachineInstr &MI,
165167
MachineBasicBlock *BB) const;
168+
169+
/// Returns true if arguments should be sign-extended in lib calls.
170+
bool shouldSignExtendTypeInLibCall(Type *Ty, bool IsSigned) const override;
171+
172+
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
173+
bool IsVarArg,
174+
const SmallVectorImpl<ISD::OutputArg> &Outs,
175+
LLVMContext &Context, const Type *RetTy) const override;
166176
};
167177
}
168178

llvm/lib/Target/BPF/BPFSubtarget.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ void BPFSubtarget::initializeEnvironment() {
7070
HasLoadAcqStoreRel = false;
7171
HasGotox = false;
7272
AllowsMisalignedMemAccess = false;
73+
AllowBuiltinCalls = false;
7374
}
7475

7576
void BPFSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {

llvm/lib/Target/BPF/BPFSubtarget.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ class BPFSubtarget : public BPFGenSubtargetInfo {
7070
bool HasLdsx, HasMovsx, HasBswap, HasSdivSmod, HasGotol, HasStoreImm,
7171
HasLoadAcqStoreRel, HasGotox;
7272

73+
bool AllowBuiltinCalls;
74+
7375
std::unique_ptr<CallLowering> CallLoweringInfo;
7476
std::unique_ptr<InstructionSelector> InstSelector;
7577
std::unique_ptr<LegalizerInfo> Legalizer;
@@ -101,6 +103,7 @@ class BPFSubtarget : public BPFGenSubtargetInfo {
101103
bool hasStoreImm() const { return HasStoreImm; }
102104
bool hasLoadAcqStoreRel() const { return HasLoadAcqStoreRel; }
103105
bool hasGotox() const { return HasGotox; }
106+
bool getAllowBuiltinCalls() const { return AllowBuiltinCalls; }
104107

105108
bool isLittleEndian() const { return IsLittleEndian; }
106109

llvm/test/CodeGen/BPF/atomic-oversize.ll

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
; RUN: llc -mtriple=bpf < %s | FileCheck %s
2-
; XFAIL: *
3-
; Doesn't currently build, with error 'only small returns supported'.
42

53
define void @test(ptr %a) nounwind {
64
; CHECK-LABEL: test:
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
; RUN: llc -march=bpfel -mattr=+allow-builtin-calls < %s | FileCheck %s
2+
;
3+
; C code for this test case:
4+
;
5+
; long func(long a, long b) {
6+
; long x;
7+
; return __builtin_mul_overflow(a, b, &x);
8+
; }
9+
10+
11+
declare { i64, i1 } @llvm.smul.with.overflow.i64(i64, i64)
12+
13+
define noundef range(i64 0, 2) i64 @func(i64 noundef %a, i64 noundef %b) local_unnamed_addr {
14+
entry:
15+
%0 = tail call { i64, i1 } @llvm.smul.with.overflow.i64(i64 %a, i64 %b)
16+
%1 = extractvalue { i64, i1 } %0, 1
17+
%conv = zext i1 %1 to i64
18+
ret i64 %conv
19+
}
20+
21+
; CHECK-LABEL: func
22+
; CHECK: r4 = r2
23+
; CHECK: r2 = r1
24+
; CHECK: r3 = r2
25+
; CHECK: r3 s>>= 63
26+
; CHECK: r5 = r4
27+
; CHECK: r5 s>>= 63
28+
; CHECK: r1 = r10
29+
; CHECK: r1 += -16
30+
; CHECK: call __multi3
31+
; CHECK: r1 = *(u64 *)(r10 - 16)
32+
; CHECK: r1 s>>= 63
33+
; CHECK: w0 = 1
34+
; CHECK: r2 = *(u64 *)(r10 - 8)
35+
; CHECK: if r2 != r1 goto LBB0_2
36+
; CHECK: # %bb.1: # %entry
37+
; CHECK: w0 = 0
38+
; CHECK: LBB0_2: # %entry
39+
; CHECK: exit

llvm/test/CodeGen/BPF/struct_ret2.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
; RUN: not llc -mtriple=bpf < %s 2> %t1
22
; RUN: FileCheck %s < %t1
3-
; CHECK: only small returns
3+
; CHECK: aggregate returns are not supported
44

55
; Function Attrs: nounwind uwtable
66
define { i64, i32 } @foo(i32 %a, i32 %b, i32 %c) #0 {

0 commit comments

Comments
 (0)