Skip to content

Commit ddfb999

Browse files
committed
bpf: fix bug on silently truncating 64-bit immediate
We came across an llvm bug when compiling some testcases that 64-bit immediates are silently truncated into 32-bit and then packed into BPF_JMP | BPF_K encoding. This caused comparison with wrong value. This bug looks to be introduced by r308080 (llvm 5.0). The Select_Ri pattern is supposed to be lowered into J*_Ri while the latter only support 32-bit immediate encoding, therefore Select_Ri should have similar immediate predicate check as what J*_Ri are doing. The bug is fixed by git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@315889 91177308-0d34-0410-b5e6-96231b3b80d8 in llvm 6.0. This patch is largely the same as the fix in llvm 6.0 except one minor adjustment for the test case. Reported-by: John Fastabend <john.fastabend@gmail.com> Reported-by: Jakub Kicinski <jakub.kicinski@netronome.com> Signed-off-by: Jiong Wang <jiong.wang@netronome.com> Reviewed-by: Yonghong Song <yhs@fb.com> git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_50@319633 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 9bc5c88 commit ddfb999

File tree

3 files changed

+42
-3
lines changed

3 files changed

+42
-3
lines changed

lib/Target/BPF/BPFISelLowering.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -578,11 +578,15 @@ BPFTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
578578
.addReg(LHS)
579579
.addReg(MI.getOperand(2).getReg())
580580
.addMBB(Copy1MBB);
581-
else
581+
else {
582+
int64_t imm32 = MI.getOperand(2).getImm();
583+
// sanity check before we build J*_ri instruction.
584+
assert (isInt<32>(imm32));
582585
BuildMI(BB, DL, TII.get(NewCC))
583586
.addReg(LHS)
584-
.addImm(MI.getOperand(2).getImm())
587+
.addImm(imm32)
585588
.addMBB(Copy1MBB);
589+
}
586590

587591
// Copy0MBB:
588592
// %FalseValue = ...

lib/Target/BPF/BPFInstrInfo.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ let usesCustomInserter = 1 in {
464464
(ins GPR:$lhs, i64imm:$rhs, i64imm:$imm, GPR:$src, GPR:$src2),
465465
"# Select PSEUDO $dst = $lhs $imm $rhs ? $src : $src2",
466466
[(set i64:$dst,
467-
(BPFselectcc i64:$lhs, (i64 imm:$rhs), (i64 imm:$imm), i64:$src, i64:$src2))]>;
467+
(BPFselectcc i64:$lhs, (i64 i64immSExt32:$rhs), (i64 imm:$imm), i64:$src, i64:$src2))]>;
468468
}
469469

470470
// load 64-bit global addr into register

test/CodeGen/BPF/select_ri.ll

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,38 @@ entry:
2525
}
2626

2727
attributes #0 = { norecurse nounwind readonly }
28+
29+
; test immediate out of 32-bit range
30+
; Source file:
31+
32+
; unsigned long long
33+
; load_word(void *buf, unsigned long long off)
34+
; asm("llvm.bpf.load.word");
35+
;
36+
; int
37+
; foo(void *buf)
38+
; {
39+
; unsigned long long sum = 0;
40+
;
41+
; sum += load_word(buf, 100);
42+
; sum += load_word(buf, 104);
43+
;
44+
; if (sum != 0x1ffffffffULL)
45+
; return ~0U;
46+
;
47+
; return 0;
48+
;}
49+
50+
; Function Attrs: nounwind readonly
51+
define i32 @foo(i8*) local_unnamed_addr #0 {
52+
%2 = tail call i64 @llvm.bpf.load.word(i8* %0, i64 100)
53+
%3 = tail call i64 @llvm.bpf.load.word(i8* %0, i64 104)
54+
%4 = add i64 %3, %2
55+
%5 = icmp ne i64 %4, 8589934591
56+
; CHECK: r{{[0-9]+}} = 8589934591ll
57+
%6 = sext i1 %5 to i32
58+
ret i32 %6
59+
}
60+
61+
; Function Attrs: nounwind readonly
62+
declare i64 @llvm.bpf.load.word(i8*, i64) #1

0 commit comments

Comments
 (0)