https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123502
--- Comment #8 from Jose E. Marchesi <jemarch at gcc dot gnu.org> ---
It is the combiner that transforms:
(insn 5 4 6 2 (set (reg:DI 22)
(lshiftrt:DI (reg/f:DI 21)
(const_int 6 [0x6]))) "foo.c":9:1 44 {lshrdi3}
(expr_list:REG_DEAD (reg/f:DI 21)
(nil)))
(insn 6 5 7 2 (set (reg/f:DI 23)
(ashift:DI (reg:DI 22)
(const_int 6 [0x6]))) "foo.c":9:1 42 {ashldi3}
(expr_list:REG_DEAD (reg:DI 22)
(nil)))
into the AND.
However, in the kernel verifier:
case BPF_AND:
case BPF_OR:
case BPF_XOR:
/* bitwise ops on pointers are troublesome, prohibit. */
verbose(env, "R%d bitwise operator %s on pointer prohibited\n",
dst, bpf_alu_string[opcode >> 4]);
return -EACCES;
default:
/* other operators (e.g. MUL,LSH) produce non-pointer results
*/
verbose(env, "R%d pointer arithmetic with %s operator
prohibited\n",
dst, bpf_alu_string[opcode >> 4]);
return -EACCES;
So even if we somehow made the combiner to not transform into the AND,
the resulting code would still be non-verifiable.