-
Notifications
You must be signed in to change notification settings - Fork 15k
Open
Labels
crash-on-validllvm:SelectionDAGSelectionDAGISel as wellSelectionDAGISel as wellobsoleteIssues with old (unsupported) versions of LLVMIssues with old (unsupported) versions of LLVM
Description
Environment
- LLVM/Clang: Ubuntu clang version 14.0.0-1ubuntu1.1
- Targets:
bpfelandbpfeb - Flags:
-O2 -mcpu=v1 -target bpf{el,eb} - Reproducibility: always, with minimal tc program below
Minimal source (repro.c)
#include <linux/bpf.h>
#include <linux/pkt_cls.h>
#define SEC(NAME) __attribute__((section(NAME), used))
typedef __u32 u32;
static __always_inline u32 ilog2_u32(u32 v) {
return 31u - __builtin_clz(v | 1u);
}
SEC("tc")
int repro_prog(struct __sk_buff *skb)
{
u32 x = ilog2_u32((u32)skb->len);
return x ? TC_ACT_SHOT : TC_ACT_OK;
}
char _license[] SEC("license") = "GPL";Reproduction steps
Little-endian:
clang -O2 -g -Wall \
-target bpfel -mcpu=v1 \
-I/usr/include/x86_64-linux-gnu \
-c repro.c -o repro_bpfel.oBig-endian:
clang -O2 -g -Wall \
-target bpfeb -mcpu=v1 \
-I/usr/include/x86_64-linux-gnu \
-c repro.c -o repro_bpfeb.oObserved result
Clang crashes during code generation:
Code generation
Running pass 'Function Pass Manager' on module 'repro.c'.
Running pass 'BPF DAG->DAG Pattern Instruction Selection' on function '@repro_prog'
#0 llvm::sys::PrintStackTrace
#1 llvm::sys::RunSignalHandlers
#2 llvm::sys::CleanupOnSignal
#3 ...
#5 llvm::SelectionDAG::createOperands
#6 llvm::SelectionDAG::getNode
#7 ... (BPF ISel lowering) ...
#9 llvm::SelectionDAG::Legalize
#11 llvm::SelectionDAGISel::CodeGenAndEmitDAG
...
clang: error: clang frontend command failed with exit code 139
Expected result
- No crash.
- Either successful codegen, or a diagnostic if
ctlzon v1 is not legal and needs expansion.
Notes / Workarounds
- Replacing the expression with a branchy
ilog2(no builtins) avoids the crash. - Example safe replacement:
static __always_inline u32 ilog2_u32(u32 v) { u32 r = 0; v |= 1; if (v >= (1u<<16)) { v >>= 16; r += 16; } if (v >= (1u<< 8)) { v >>= 8; r += 8; } if (v >= (1u<< 4)) { v >>= 4; r += 4; } if (v >= (1u<< 2)) { v >>= 2; r += 2; } if (v >= (1u<< 1)) { r += 1; } return r; }
- The problem is reproducible even with LLVM 18.1.3
Metadata
Metadata
Assignees
Labels
crash-on-validllvm:SelectionDAGSelectionDAGISel as wellSelectionDAGISel as wellobsoleteIssues with old (unsupported) versions of LLVMIssues with old (unsupported) versions of LLVM