[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