-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[BPF] Add asm support for JSET insn #73161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-mc Author: None (yonghong-song) ChangesBPF upstream reported that JSET insn is not supported in inline asm ([1]). BPF_JSET insn is part of BPF ISA so let us add asm support for it now. [1] https://lore.kernel.org/bpf/2e8a1584-a289-4b2e-800c-8b463e734bcb@linux.dev/ Full diff: https://github.com/llvm/llvm-project/pull/73161.diff 4 Files Affected:
diff --git a/llvm/lib/Target/BPF/BPFInstrFormats.td b/llvm/lib/Target/BPF/BPFInstrFormats.td
index 841d97efc01c5c1..6ed83d877ac0f23 100644
--- a/llvm/lib/Target/BPF/BPFInstrFormats.td
+++ b/llvm/lib/Target/BPF/BPFInstrFormats.td
@@ -63,6 +63,7 @@ def BPF_JA : BPFJumpOp<0x0>;
def BPF_JEQ : BPFJumpOp<0x1>;
def BPF_JGT : BPFJumpOp<0x2>;
def BPF_JGE : BPFJumpOp<0x3>;
+def BPF_JSET : BPFJumpOp<0x4>;
def BPF_JNE : BPFJumpOp<0x5>;
def BPF_JSGT : BPFJumpOp<0x6>;
def BPF_JSGE : BPFJumpOp<0x7>;
diff --git a/llvm/lib/Target/BPF/BPFInstrInfo.td b/llvm/lib/Target/BPF/BPFInstrInfo.td
index 305cbbd34d2707d..9e75f35efe70cb3 100644
--- a/llvm/lib/Target/BPF/BPFInstrInfo.td
+++ b/llvm/lib/Target/BPF/BPFInstrInfo.td
@@ -246,6 +246,70 @@ class JMP_RI_32<BPFJumpOp Opc, string OpcodeStr, PatLeaf Cond>
let BPFClass = BPF_JMP32;
}
+class JSET_RR<string OpcodeStr>
+ : TYPE_ALU_JMP<BPF_JSET.Value, BPF_X.Value,
+ (outs),
+ (ins GPR:$dst, GPR:$src, brtarget:$BrDst),
+ "if $dst "#OpcodeStr#" $src goto $BrDst",
+ []> {
+ bits<4> dst;
+ bits<4> src;
+ bits<16> BrDst;
+
+ let Inst{55-52} = src;
+ let Inst{51-48} = dst;
+ let Inst{47-32} = BrDst;
+ let BPFClass = BPF_JMP;
+}
+
+class JSET_RI<string OpcodeStr>
+ : TYPE_ALU_JMP<BPF_JSET.Value, BPF_K.Value,
+ (outs),
+ (ins GPR:$dst, i64imm:$imm, brtarget:$BrDst),
+ "if $dst "#OpcodeStr#" $imm goto $BrDst",
+ []> {
+ bits<4> dst;
+ bits<16> BrDst;
+ bits<32> imm;
+
+ let Inst{51-48} = dst;
+ let Inst{47-32} = BrDst;
+ let Inst{31-0} = imm;
+ let BPFClass = BPF_JMP;
+}
+
+class JSET_RR_32<string OpcodeStr>
+ : TYPE_ALU_JMP<BPF_JSET.Value, BPF_X.Value,
+ (outs),
+ (ins GPR32:$dst, GPR32:$src, brtarget:$BrDst),
+ "if $dst "#OpcodeStr#" $src goto $BrDst",
+ []> {
+ bits<4> dst;
+ bits<4> src;
+ bits<16> BrDst;
+
+ let Inst{55-52} = src;
+ let Inst{51-48} = dst;
+ let Inst{47-32} = BrDst;
+ let BPFClass = BPF_JMP32;
+}
+
+class JSET_RI_32<string OpcodeStr>
+ : TYPE_ALU_JMP<BPF_JSET.Value, BPF_K.Value,
+ (outs),
+ (ins GPR32:$dst, i32imm:$imm, brtarget:$BrDst),
+ "if $dst "#OpcodeStr#" $imm goto $BrDst",
+ []> {
+ bits<4> dst;
+ bits<16> BrDst;
+ bits<32> imm;
+
+ let Inst{51-48} = dst;
+ let Inst{47-32} = BrDst;
+ let Inst{31-0} = imm;
+ let BPFClass = BPF_JMP32;
+}
+
multiclass J<BPFJumpOp Opc, string OpcodeStr, PatLeaf Cond, PatLeaf Cond32> {
def _rr : JMP_RR<Opc, OpcodeStr, Cond>;
def _ri : JMP_RI<Opc, OpcodeStr, Cond>;
@@ -265,6 +329,10 @@ defm JULT : J<BPF_JLT, "<", BPF_CC_LTU, BPF_CC_LTU_32>;
defm JULE : J<BPF_JLE, "<=", BPF_CC_LEU, BPF_CC_LEU_32>;
defm JSLT : J<BPF_JSLT, "s<", BPF_CC_LT, BPF_CC_LT_32>;
defm JSLE : J<BPF_JSLE, "s<=", BPF_CC_LE, BPF_CC_LE_32>;
+def JSET_RR : JSET_RR<"&">;
+def JSET_RI : JSET_RI<"&">;
+def JSET_RR_32 : JSET_RR_32<"&">;
+def JSET_RI_32 : JSET_RI_32<"&">;
}
// ALU instructions
diff --git a/llvm/test/MC/BPF/insn-unit-32.s b/llvm/test/MC/BPF/insn-unit-32.s
index e53c686a4fa3e33..09b89d72e507c0e 100644
--- a/llvm/test/MC/BPF/insn-unit-32.s
+++ b/llvm/test/MC/BPF/insn-unit-32.s
@@ -55,6 +55,11 @@
// CHECK: b4 09 00 00 ff ff ff ff w9 = -1
// CHECK: c4 0a 00 00 40 00 00 00 w10 s>>= 64
+ if w1 & w2 goto Llabel0 // BPF_JSET | BPF_X
+ if w1 & 0xff goto Llabel0 // BPF_JSET | BPF_K
+// CHECK: 4e 21 0d 00 00 00 00 00 if w1 & w2 goto +13
+// CHECK: 46 01 0c 00 ff 00 00 00 if w1 & 255 goto +12
+
if w0 == w1 goto Llabel0 // BPF_JEQ | BPF_X
if w3 != w4 goto Llabel0 // BPF_JNE | BPF_X
// CHECK: 1e 10 0b 00 00 00 00 00 if w0 == w1 goto +11
diff --git a/llvm/test/MC/BPF/insn-unit.s b/llvm/test/MC/BPF/insn-unit.s
index 94c46e9013bac78..58342cda7cc0ad0 100644
--- a/llvm/test/MC/BPF/insn-unit.s
+++ b/llvm/test/MC/BPF/insn-unit.s
@@ -62,6 +62,11 @@
// CHECK: db a3 e2 ff 00 00 00 00 lock *(u64 *)(r3 - 30) += r10
// ======== BPF_JMP Class ========
+ if r1 & r2 goto Llabel0 // BPF_JSET | BPF_X
+ if r1 & 0xffff goto Llabel0 // BPF_JSET | BPF_K
+// CHECK: 4d 21 1d 00 00 00 00 00 if r1 & r2 goto +29
+// CHECK: 45 01 1c 00 ff ff 00 00 if r1 & 65535 goto +28
+
goto Llabel0 // BPF_JA
call 1 // BPF_CALL
exit // BPF_EXIT
|
linux succeeded and windows failed. The windows failure message:
I do not think this is a problem from this patch. Let me rebase and run again. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
Looks good as is, but I have a suggestion to minimize code duplication, seems to pass all tests. diff --git a/llvm/lib/Target/BPF/BPFInstrInfo.td b/llvm/lib/Target/BPF/BPFInstrInfo.td
index 9e75f35efe70..7a440cf94f5d 100644
--- a/llvm/lib/Target/BPF/BPFInstrInfo.td
+++ b/llvm/lib/Target/BPF/BPFInstrInfo.td
@@ -181,13 +181,18 @@ class TYPE_LD_ST<bits<3> mode, bits<2> size,
let Inst{60-59} = size;
}
+class NoCond : PatLeaf<(vt)> {}
+
// jump instructions
class JMP_RR<BPFJumpOp Opc, string OpcodeStr, PatLeaf Cond>
: TYPE_ALU_JMP<Opc.Value, BPF_X.Value,
(outs),
(ins GPR:$dst, GPR:$src, brtarget:$BrDst),
"if $dst "#OpcodeStr#" $src goto $BrDst",
- [(BPFbrcc i64:$dst, i64:$src, Cond, bb:$BrDst)]> {
+ !if(!isa<NoCond>(Cond),
+ [],
+ [(BPFbrcc i64:$dst, i64:$src, Cond, bb:$BrDst)])>
+{
bits<4> dst;
bits<4> src;
bits<16> BrDst;
@@ -246,70 +251,6 @@ class JMP_RI_32<BPFJumpOp Opc, string OpcodeStr, PatLeaf Cond>
let BPFClass = BPF_JMP32;
}
-class JSET_RR<string OpcodeStr>
- : TYPE_ALU_JMP<BPF_JSET.Value, BPF_X.Value,
- (outs),
- (ins GPR:$dst, GPR:$src, brtarget:$BrDst),
- "if $dst "#OpcodeStr#" $src goto $BrDst",
- []> {
- bits<4> dst;
- bits<4> src;
- bits<16> BrDst;
-
- let Inst{55-52} = src;
- let Inst{51-48} = dst;
- let Inst{47-32} = BrDst;
- let BPFClass = BPF_JMP;
-}
-
-class JSET_RI<string OpcodeStr>
- : TYPE_ALU_JMP<BPF_JSET.Value, BPF_K.Value,
- (outs),
- (ins GPR:$dst, i64imm:$imm, brtarget:$BrDst),
- "if $dst "#OpcodeStr#" $imm goto $BrDst",
- []> {
- bits<4> dst;
- bits<16> BrDst;
- bits<32> imm;
-
- let Inst{51-48} = dst;
- let Inst{47-32} = BrDst;
- let Inst{31-0} = imm;
- let BPFClass = BPF_JMP;
-}
-
-class JSET_RR_32<string OpcodeStr>
- : TYPE_ALU_JMP<BPF_JSET.Value, BPF_X.Value,
- (outs),
- (ins GPR32:$dst, GPR32:$src, brtarget:$BrDst),
- "if $dst "#OpcodeStr#" $src goto $BrDst",
- []> {
- bits<4> dst;
- bits<4> src;
- bits<16> BrDst;
-
- let Inst{55-52} = src;
- let Inst{51-48} = dst;
- let Inst{47-32} = BrDst;
- let BPFClass = BPF_JMP32;
-}
-
-class JSET_RI_32<string OpcodeStr>
- : TYPE_ALU_JMP<BPF_JSET.Value, BPF_K.Value,
- (outs),
- (ins GPR32:$dst, i32imm:$imm, brtarget:$BrDst),
- "if $dst "#OpcodeStr#" $imm goto $BrDst",
- []> {
- bits<4> dst;
- bits<16> BrDst;
- bits<32> imm;
-
- let Inst{51-48} = dst;
- let Inst{47-32} = BrDst;
- let Inst{31-0} = imm;
- let BPFClass = BPF_JMP32;
-}
-
multiclass J<BPFJumpOp Opc, string OpcodeStr, PatLeaf Cond, PatLeaf Cond32> {
def _rr : JMP_RR<Opc, OpcodeStr, Cond>;
def _ri : JMP_RI<Opc, OpcodeStr, Cond>;
@@ -329,10 +270,7 @@ defm JULT : J<BPF_JLT, "<", BPF_CC_LTU, BPF_CC_LTU_32>;
defm JULE : J<BPF_JLE, "<=", BPF_CC_LEU, BPF_CC_LEU_32>;
defm JSLT : J<BPF_JSLT, "s<", BPF_CC_LT, BPF_CC_LT_32>;
defm JSLE : J<BPF_JSLE, "s<=", BPF_CC_LE, BPF_CC_LE_32>;
-def JSET_RR : JSET_RR<"&">;
-def JSET_RI : JSET_RI<"&">;
-def JSET_RR_32 : JSET_RR_32<"&">;
-def JSET_RI_32 : JSET_RI_32<"&">;
+defm JSET : J<BPF_JSET, "&", NoCond<>, NoCond<>>;
}
// ALU instructions |
BPF upstream reported that JSET insn is not supported in inline asm ([1]). BPF_JSET insn is part of BPF ISA so let us add asm support for it now. [1] https://lore.kernel.org/bpf/[email protected]/
Thanks @eddyz87 Your suggestion looks good. I made the change (slightly different from yours) and the patch is much smaller now. In your original suggestion, JMP_RR specialization is not really needed. Thanks! |
BPF upstream reported that JSET insn is not supported in inline asm ([1]). BPF_JSET insn is part of BPF ISA so let us add asm support for it now.
[1] https://lore.kernel.org/bpf/[email protected]/