public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 0/1] RISC-V: Make "prefetch.i" built-in usable
@ 2023-08-10  3:10 Tsukasa OI
  2023-08-10  3:10 ` [PATCH 1/1] " Tsukasa OI
  0 siblings, 1 reply; 5+ messages in thread
From: Tsukasa OI @ 2023-08-10  3:10 UTC (permalink / raw)
  To: Tsukasa OI, Kito Cheng, Palmer Dabbelt, Andrew Waterman, Jim Wilson
  Cc: gcc-patches

Hello,

I found that a built-in function "__builtin_riscv_zicbop_cbo_prefetchi" is
terribly broken so that this is practically unusable.  It emits the
"prefetch.i" machine instruction HINT but with no usable arguments.

Contents of a.c:

> void function_to_be_called(void);
> 
> void sample(void)
> {
>     __builtin_riscv_zicbop_cbo_prefetchi(&function_to_be_called);
>     function_to_be_called();
> }


Compiling with the 'Zicbop' extension fails.

> $ riscv64-unknown-elf-gcc -O2 -march=rv64i_zicbop -mabi=lp64 -c a.c
> a.c: In function 'sample':
> a.c:5:42: warning: passing argument 1 of '__builtin_riscv_zicbop_cbo_prefetchi' makes integer from pointer without a cast [-Wint-conversion]
>     5 |     __builtin_riscv_zicbop_cbo_prefetchi(&function_to_be_called);
>       |                                          ^~~~~~~~~~~~~~~~~~~~~~
>       |                                          |
>       |                                          void (*)(void)
> a.c:5:42: note: expected 'long int' but argument is of type 'void (*)(void)'
> a.c:5:5: error: invalid argument to built-in function
>     5 |     __builtin_riscv_zicbop_cbo_prefetchi(&function_to_be_called);
>       |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

seems the prototype of this built-in function is...

> int  __builtin_riscv_zicbop_cbo_prefetchi(int);  // RV32
> long __builtin_riscv_zicbop_cbo_prefetchi(long); // RV64

I started to have a bad feeling about this.




Looking at the test case, following code compiles (sort of).

> void sample(void)
> {
>     __builtin_riscv_zicbop_cbo_prefetchi(1); /* integer constant: 0-4 (inclusive) */
> }

WHAT IS THIS PREFETCHING!?

The answer was obvious (tested with GCC 13.2.0).

> $ riscv64-unknown-elf-gcc -O2 -march=rv64i_zicbop -mabi=lp64 -S a.c
> $ cat a.s
>         .file   "a.c"
>         .option nopic
>         .attribute arch, "rv64i2p1_zicbop1p0"
>         .attribute unaligned_access, 0
>         .attribute stack_align, 16
>         .text
>         .align  2
>         .globl  sample
>         .type   sample, @function
> sample:
>         li      a5,0
>         prefetch.i      0(a5)
>         ret
>         .size   sample, .-sample
>         .ident  "GCC: (gc891d8dc23e1) 13.2.0"

... none (NULL).  Even the prefetching constant (1) is ignored.




It makes no sense whatsoever.  This patch set is definitely compatibility-
breaking but necessary to make "prefetch.i" work.

This patch set makes following built-in function.

> void  __builtin_riscv_zicbop_prefetch_i(void*);

Did you notice that I renamed the function?  There are three reasons:

1.  We needed to break the compatibility anyway.
2.  To avoid functionality problems.
    Co-existing functional and non-functional
    __builtin_riscv_zicbop_cbo_prefetchi built-in felt like a nightmare.
3.  Although this is also a cache block operation, the instruction
    "prefetch.i" does not have the name "cbo" in it
    (unlike "__builtin_riscv_zicbom_cbo_clean" corresponding "cbo.clean").


Let's make a working sample (a.c):

> void function_to_be_called(void);
> 
> void sample(void)
> {
>     __builtin_riscv_zicbop_prefetch_i(&function_to_be_called);
>     function_to_be_called();
> }

And take look at the output assembly and its relocations.

> $ riscv64-unknown-elf-gcc -O2 -march=rv64i_zicbop -mabi=lp64 -S a.c
> $ cat a.s
>         .file   "a.c"
>         .option nopic
>         .attribute arch, "rv64i2p1_zicbop1p0"
>         .attribute unaligned_access, 0
>         .attribute stack_align, 16
>         .text
>         .align  2
>         .globl  sample
>         .type   sample, @function
> sample:
>         lui     a5,%hi(function_to_be_called)
>         addi    a5,a5,%lo(function_to_be_called)
>         prefetch.i      0(a5)
>         tail    function_to_be_called
>         .size   sample, .-sample
>         .ident  "GCC: (GNU) 14.0.0 20230810 (experimental)"



I hope this issue is fixed soon.

Sincerely,
Tsukasa




Tsukasa OI (1):
  RISC-V: Make "prefetch.i" built-in usable

 gcc/config/riscv/riscv-cmo.def                |  4 ++--
 gcc/config/riscv/riscv.md                     |  5 ++---
 gcc/doc/extend.texi                           |  7 +++++++
 gcc/testsuite/gcc.target/riscv/cmo-zicbop-1.c |  8 +++++---
 gcc/testsuite/gcc.target/riscv/cmo-zicbop-2.c | 10 ++++++----
 5 files changed, 22 insertions(+), 12 deletions(-)


base-commit: 9b099a83b45b8fcdfc07d518e05d36ea741b2227
-- 
2.41.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2023-08-29 13:47 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-10  3:10 [PATCH 0/1] RISC-V: Make "prefetch.i" built-in usable Tsukasa OI
2023-08-10  3:10 ` [PATCH 1/1] " Tsukasa OI
2023-08-28 21:20   ` Jeff Law
2023-08-29  2:09     ` Tsukasa OI
2023-08-29 13:47       ` Jeff Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).