+SEC("?tc")
+__log_level(2)
+int test_verifier_range(void)
+{
+ asm volatile (
+ "r5 = 100; \
+ r5 /= 3; \
+ w5 >>= 7; \
+ r5 &= -386969681; \
+ r5 -= -884670597; \
+ w0 = w5; \
+ if w0 & 0x894b6a55 goto +2; \
So actually it is 'if w0 & 0x894b6a55 goto +2' failed
the compilation.
Indeed, the above operation is not supported in llvm.
See
https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/BPF/BPFInstrFormats.td#L62-L74
the missing BPFJumpOp<0x4> which corresponds to JSET.
The following llvm patch (on top of llvm-project main branch):
diff --git a/llvm/lib/Target/BPF/BPFInstrFormats.td b/llvm/lib/Target/BPF/BPFInstrFormats.td
index 841d97efc01c..6ed83d877ac0 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 305cbbd34d27..9e75f35efe70 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
can solve your inline asm issue. We will discuss whether llvm compiler
should be implementing this instruction from source or not.