[PATCH] D131468: [WIP][BPF]: Force truncation for arguments in callee and return values in caller
Yonghong Song via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 8 23:21:44 PDT 2022
yonghong-song created this revision.
yonghong-song added reviewers: ast, anakryiko.
Herald added a subscriber: pengfei.
Herald added a project: All.
yonghong-song requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
For function arguments, current implementation will do
needed sign/zero extension for 32/64-bit integer types
in callee and 8/16-bit types in caller.
This patch forced sign/zero extension to be done in
callee. Alternatively, with a slightly different
implementation, sign/zero extension can be done in caller.
Similarly for function return value, current implementation
will do needed sign/zero extension for 32/64-bit integer
types in caller and 8/16-bit return values in callee.
This patch forced sign/zero extension in caller.
Alternatively, with a slightly different implementation,
sign/zero extension can be done in callee.
$ cat t.c
unsigned char bar();
char foo(short a) {
if (bar() != a) return a; else return a + 1;
}
$ clang -target bpf -O2 -g -c t.c
$ llvm-objdump -S t.o
...
; char foo(short a) {
0: bf 16 00 00 00 00 00 00 r6 = r1
; if (bar() != a) return a; else return a + 1;
1: bf 67 00 00 00 00 00 00 r7 = r6
2: 67 07 00 00 30 00 00 00 r7 <<= 48
3: c7 07 00 00 30 00 00 00 r7 s>>= 48
4: 85 10 00 00 ff ff ff ff call -1
5: bf 01 00 00 00 00 00 00 r1 = r0
6: 57 01 00 00 ff 00 00 00 r1 &= 255
7: b7 00 00 00 01 00 00 00 r0 = 1
8: 1d 71 01 00 00 00 00 00 if r1 == r7 goto +1 <LBB0_2>
9: b7 00 00 00 00 00 00 00 r0 = 0
0000000000000050 <LBB0_2>:
; if (bar() != a) return a; else return a + 1;
10: 0f 60 00 00 00 00 00 00 r0 += r6
; }
11: 95 00 00 00 00 00 00 00 exit
In the above example, 16-bit argument value has sign extension
is done in callee before it is used. 8-bit return value has
zero extension done in caller before the value is used.
Note that we mostly care about 8-bit return value sign/zero
extension in the context of bpf program calling kernel functions
since for x86_64, the caller can directly access 8-bit %al
register while bpf can only access 32/64-bit registers.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D131468
Files:
clang/lib/CodeGen/TargetInfo.cpp
Index: clang/lib/CodeGen/TargetInfo.cpp
===================================================================
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -11498,6 +11498,75 @@
};
} // end anonymous namespace
+//===----------------------------------------------------------------------===//
+// BPF ABI Implementation
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+class BPFABIInfo : public DefaultABIInfo {
+public:
+ BPFABIInfo(CodeGenTypes &CGT) : DefaultABIInfo(CGT) {}
+
+#if 1
+ ABIArgInfo classifyArgumentType(QualType Ty) const {
+ Ty = useFirstFieldIfTransparentUnion(Ty);
+
+ if (isAggregateTypeForABI(Ty))
+ return getNaturalAlignIndirect(Ty);
+
+ // Treat an enum type as its underlying type.
+ if (const EnumType *EnumTy = Ty->getAs<EnumType>())
+ Ty = EnumTy->getDecl()->getIntegerType();
+
+ ASTContext &Context = getContext();
+ if (const auto *EIT = Ty->getAs<BitIntType>())
+ if (EIT->getNumBits() > Context.getTypeSize(Context.Int128Ty))
+ return getNaturalAlignIndirect(Ty);
+
+ return ABIArgInfo::getDirect();
+ }
+#endif
+
+ ABIArgInfo classifyReturnType(QualType RetTy) const {
+ if (RetTy->isVoidType())
+ return ABIArgInfo::getIgnore();
+
+ if (isAggregateTypeForABI(RetTy))
+ return getNaturalAlignIndirect(RetTy);
+
+ // Treat an enum type as its underlying type.
+ if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
+ RetTy = EnumTy->getDecl()->getIntegerType();
+
+ ASTContext &Context = getContext();
+ if (const auto *EIT = RetTy->getAs<BitIntType>())
+ if (EIT->getNumBits() > Context.getTypeSize(Context.Int128Ty))
+ return getNaturalAlignIndirect(RetTy);
+
+ return ABIArgInfo::getDirect();
+ }
+
+ void computeInfo(CGFunctionInfo &FI) const override {
+ FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
+ for (auto &I : FI.arguments())
+ I.info = classifyArgumentType(I.type);
+ }
+
+};
+
+class BPFTargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+ BPFTargetCodeGenInfo(CodeGenTypes &CGT)
+ : TargetCodeGenInfo(std::make_unique<BPFABIInfo>(CGT)) {}
+
+ const BPFABIInfo &getABIInfo() const {
+ return static_cast<const BPFABIInfo&>(TargetCodeGenInfo::getABIInfo());
+ }
+};
+
+}
+
//===----------------------------------------------------------------------===//
// Driver code
//===----------------------------------------------------------------------===//
@@ -11726,6 +11795,9 @@
: hasFP64 ? 64
: 32));
}
+ case llvm::Triple::bpfeb:
+ case llvm::Triple::bpfel:
+ return SetCGInfo(new BPFTargetCodeGenInfo(Types));
}
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D131468.451055.patch
Type: text/x-patch
Size: 2827 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220809/6042b24a/attachment-0001.bin>
More information about the cfe-commits
mailing list