[clang] [llvm] [Clang][BPF] Allow sign extension for call parameters with int types (PR #84874)

via cfe-commits cfe-commits at lists.llvm.org
Wed Mar 13 11:31:25 PDT 2024


yonghong-song wrote:

@pulehui On top of this patch, the following is a hack to emit 'sign-extension' for uint types (unsigned char/short not affected).

The llvm hack:
```
diff --git a/llvm/lib/Target/BPF/BPFISelLowering.cpp b/llvm/lib/Target/BPF/BPFISelLowering.cpp
index b8ca8ec98c06..e4ab04c99c60 100644
--- a/llvm/lib/Target/BPF/BPFISelLowering.cpp
+++ b/llvm/lib/Target/BPF/BPFISelLowering.cpp
@@ -37,6 +37,10 @@ static cl::opt<bool> BPFExpandMemcpyInOrder("bpf-expand-memcpy-in-order",
   cl::Hidden, cl::init(false),
   cl::desc("Expand memcpy into load/store pairs in order"));
 
+static cl::opt<bool> BPFForRISCV("bpf-for-riscv",
+  cl::Hidden, cl::init(false),
+  cl::desc("BPF prog intended to run on riscv arch"));
+
 static void fail(const SDLoc &DL, SelectionDAG &DAG, const Twine &Msg,
                  SDValue Val = {}) {
   std::string Str;
@@ -239,6 +243,12 @@ bool BPFTargetLowering::isZExtFree(SDValue Val, EVT VT2) const {
   return TargetLoweringBase::isZExtFree(Val, VT2);
 }
 
+bool BPFTargetLowering::isSExtCheaperThanZExt(EVT SrcVT, EVT DstVT) const {
+  if (BPFForRISCV)
+    return SrcVT == MVT::i32 && DstVT == MVT::i64;
+  return TargetLoweringBase::isSExtCheaperThanZExt(SrcVT, DstVT);
+}
+
 BPFTargetLowering::ConstraintType
 BPFTargetLowering::getConstraintType(StringRef Constraint) const {
   if (Constraint.size() == 1) {
diff --git a/llvm/lib/Target/BPF/BPFISelLowering.h b/llvm/lib/Target/BPF/BPFISelLowering.h
index 42707949e864..e157a402b6e0 100644
--- a/llvm/lib/Target/BPF/BPFISelLowering.h
+++ b/llvm/lib/Target/BPF/BPFISelLowering.h
@@ -152,6 +152,7 @@ private:
   bool isZExtFree(Type *Ty1, Type *Ty2) const override;
   bool isZExtFree(EVT VT1, EVT VT2) const override;
   bool isZExtFree(SDValue Val, EVT VT2) const override;
+  bool isSExtCheaperThanZExt(EVT SrcVT, EVT DstVT) const override;
 
   unsigned EmitSubregExt(MachineInstr &MI, MachineBasicBlock *BB, unsigned Reg,
                          bool isSigned) const;
```

The following is a simple example,
```
$ cat t.c
void bar(unsigned int, unsigned int);
void foo() {    
  bar(5, -5);   
}
$ clang --target=bpf -O2 -c t.c && llvm-objdump -d t.o

t.o:    file format elf64-bpf

Disassembly of section .text:

0000000000000000 <foo>:
       0:       b7 01 00 00 05 00 00 00 r1 = 0x5
       1:       18 02 00 00 fb ff ff ff 00 00 00 00 00 00 00 00 r2 = 0xfffffffb ll
       3:       85 10 00 00 ff ff ff ff call -0x1
       4:       95 00 00 00 00 00 00 00 exit
$ clang --target=bpf -O2 -c t.c -mllvm -bpf-for-riscv && llvm-objdump -d t.o

t.o:    file format elf64-bpf

Disassembly of section .text:

0000000000000000 <foo>:
       0:       b7 01 00 00 05 00 00 00 r1 = 0x5
       1:       b7 02 00 00 fb ff ff ff r2 = -0x5
       2:       85 10 00 00 ff ff ff ff call -0x1
       3:       95 00 00 00 00 00 00 00 exit
$
```
But I really do not like to generate BPF codes for different architectures. Maybe riscv can propose some code patterns where bpf backend can generate generic code (for all arches) and those codes can be easier for riscv jit to do proper sign extension?

https://github.com/llvm/llvm-project/pull/84874


More information about the cfe-commits mailing list