Hi, Ruoyao,

On Tue, Sep 23, 2025 at 8:34 PM Xi Ruoyao <[email protected]> wrote:
>
> In some applications (notably the Linux kernel), "break 0" is used as a
> trap that a handler may be able to recover.  But in GCC the "trap"
> pattern is meant to make the program rightfully die instead.
>
> As [1] describes, sometimes it's vital to distinguish between the two
> cases.
>
> Use the "documented illegal instruction" amswap.w $r0,$r1,$r0 for "trap"
> instead.  This also aligns the behavior with x86_64 GCC and LoongArch
> clang.
Can we use "break 1" instead?

Huacai

>
> [1]:https://lore.kernel.org/[email protected]
>
> gcc/
>
>         * config/loongarch/loongarch.md (trap): Lower to the documented
>         illegal amswap.w $r0,$r1,$r0.
>
> gcc/testsuite/
>
>         * gcc.target/loongarch/trap.c: New test.
> ---
>
> Bootstrapped and regtested on loongarch64-linux-gnu.  Ok for trunk?
>
>  gcc/config/loongarch/loongarch.md         | 5 ++++-
>  gcc/testsuite/gcc.target/loongarch/trap.c | 9 +++++++++
>  2 files changed, 13 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.target/loongarch/trap.c
>
> diff --git a/gcc/config/loongarch/loongarch.md 
> b/gcc/config/loongarch/loongarch.md
> index a275a2d0158..f3873f5064c 100644
> --- a/gcc/config/loongarch/loongarch.md
> +++ b/gcc/config/loongarch/loongarch.md
> @@ -679,11 +679,14 @@ (define_expand "<optab><mode>3"
>  ;;  ....................
>  ;;
>
> +;; We used to use "break 0" but it's usually used as a trap that a signal
> +;; handler can caught.  Using an insn that maps to an INE makes it more
> +;; likely the program will rightfully die.
>  (define_insn "trap"
>    [(trap_if (const_int 1) (const_int 0))]
>    ""
>  {
> -  return "break\t0";
> +  return "amswap.w\t$r0,$r1,$r0";
>  }
>    [(set_attr "type" "trap")])
>
> diff --git a/gcc/testsuite/gcc.target/loongarch/trap.c 
> b/gcc/testsuite/gcc.target/loongarch/trap.c
> new file mode 100644
> index 00000000000..32948d4c822
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/loongarch/trap.c
> @@ -0,0 +1,9 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -w -fisolate-erroneous-paths-dereference" } */
> +/* { dg-final { scan-assembler "amswap\\.w\\t\\\$r0,\\\$r1,\\\$r0" } } */
> +
> +int
> +bug (void)
> +{
> +  return *(int *)0;
> +}
> --
> 2.51.0
>

Reply via email to