https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117544

Palmer Dabbelt <palmer at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2024-11-20
     Ever confirmed|0                           |1

--- Comment #2 from Palmer Dabbelt <palmer at gcc dot gnu.org> ---
(In reply to Kito Cheng from comment #0)
> Cross posting from RISC-V LLVM community.
> 
> Unfortunately, whole register move instructions depend on vtype*1, which
> means they will cause an illegal instruction exception if VILL=1. This is
> generally not a problem, as VILL is set to 0 after any valid vsetvli
> instruction, so it’s usually safe unless the user executes a whole vector
> register move very early in the program.
> 
> However, the situation changed after the Linux kernel applied a patch[2]
> that sets VILL=1 after any system call. So, if we try to execute a whole
> register move after a system call, it will cause an illegal instruction
> exception. This can be difficult to detect, as the system call may not be
> invoked immediately; it might be deeply nested in a call chain, such as
> within printf. Unfortunately, this change has already shipped with Linux
> kernel 6.5, which was released on August 28, 2023.
> 
> I'm not sure if it's reasonable to ask the Linux kernel maintainers to fix
> this by keeping VILL consistent across system calls.

I went and read the psABI again, and VTYPE isn't preserved by any of the
function calls (either standard or variant).  So I think this is just a
straight-forward bug in GCC: we're relying on the value of VTYPE to be
preserved when the ABI says it isn't.

I think we might just need something like

diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index 898cda847cb..70d7c67d49e 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -55,7 +55,7 @@ (define_attr "has_vtype_op" "false,true"
                         
vssegtux,vssegtox,vlsegdff,vandn,vbrev,vbrev8,vrev8,vcpop,vclz,vctz,vrol,\
                         
vror,vwsll,vclmul,vclmulh,vghsh,vgmul,vaesef,vaesem,vaesdf,vaesdm,\
                         
vaeskf1,vaeskf2,vaesz,vsha2ms,vsha2ch,vsha2cl,vsm4k,vsm4r,vsm3me,vsm3c,\
-                         vfncvtbf16,vfwcvtbf16,vfwmaccbf16")
+                         vfncvtbf16,vfwcvtbf16,vfwmaccbf16,vmov")
         (const_string "true")]
        (const_string "false")))


but I haven't tested that at all...
  • [Bug target/117544] Lack of vse... palmer at gcc dot gnu.org via Gcc-bugs

Reply via email to