https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117608
--- Comment #7 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Jakub Jelinek <ja...@gcc.gnu.org>: https://gcc.gnu.org/g:f7bbdf7e4acf9c90f51d24db9a3c911c49169ab6 commit r15-5771-gf7bbdf7e4acf9c90f51d24db9a3c911c49169ab6 Author: Jakub Jelinek <ja...@redhat.com> Date: Fri Nov 29 10:17:07 2024 +0100 __builtin_prefetch fixes [PR117608] The r15-4833-ge9ab41b79933 patch had among tons of config/i386 specific changes also important change to the generic code, allowing also 2 as valid value of the second argument of __builtin_prefetch: - /* Argument 1 must be either zero or one. */ - if (INTVAL (op1) != 0 && INTVAL (op1) != 1) + /* Argument 1 must be 0, 1 or 2. */ + if (INTVAL (op1) < 0 || INTVAL (op1) > 2) But the patch failed to document that change in __builtin_prefetch documentation, and more importantly didn't adjust any of the other backends to deal with it (my understanding is the expected behavior is that 2 will be silently handled as 0 unless backends have some more specific way). Some of the backends would ICE on it, in some cases gcc_assert failures/gcc_unreachable, in other cases crash later (e.g. accessing arrays with that value as index and due to accessing garbage after the array crashing at final.cc time), others treated 2 silently as 0, others treated 2 silently as 1. And even in the i386 backend there were bugs which caused ICEs. The patch added some if (write == 0) and write 2 handling into a (badly indented, maybe that is the reason, if (write == 1) body), rather than into the else side, so it would be always false. The new *prefetch_rst2 define_insn only accepts parameters 2 1 (i.e. read-shared with moderate degree of locality), so in order not to ICE the patch uses it only for __builtin_prefetch (ptr, 2, 1); or __builtin_ia32_prefetch (ptr, 2, 1, 0); and not for other values of the parameter. If that isn't what we want and we want it to be used also for all or some of __builtin_prefetch (ptr, 2, {0,2,3}); and corresponding __builtin_ia32_prefetch, maybe the define_insn could match other values. And there was another problem that -mno-mmx -mno-sse -mmovrs compilation would ICE on most of the prefetches, so I had to add the FAIL; cases. 2024-11-29 Jakub Jelinek <ja...@redhat.com> PR target/117608 * doc/extend.texi (__builtin_prefetch): Document that second argument may be also 2 and its meaning. * config/i386/i386.md (prefetch): Remove unreachable code. Clear write set operands[1] to const0_rtx if !TARGET_MOVRS or of locality is not 1. Formatting fixes. * config/i386/i386-expand.cc (ix86_expand_builtin): Use IN_RANGE. Call gen_prefetch even for TARGET_MOVRS. * config/alpha/alpha.md (prefetch): Treat read_or_write 2 like 0. * config/mips/mips.md (prefetch): Likewise. * config/arc/arc.md (prefetch_1, prefetch_2, prefetch_3): Likewise. * config/riscv/riscv.md (prefetch): Likewise. * config/loongarch/loongarch.md (prefetch): Likewise. * config/sparc/sparc.md (prefetch): Likewise. Use IN_RANGE. * config/ia64/ia64.md (prefetch): Likewise. * config/pa/pa.md (prefetch): Likewise. * config/aarch64/aarch64.md (prefetch): Likewise. * config/rs6000/rs6000.md (prefetch): Likewise. * gcc.dg/builtin-prefetch-1.c (good): Add tests with second argument 2. * gcc.target/i386/pr117608-1.c: New test. * gcc.target/i386/pr117608-2.c: New test.