mbox series

[0/2] RISC-V: Change RISC-V bit manipulation / scalar crypto builtin types

Message ID cover.1694482087.git.research_trasio@irq.a4lg.com
Headers show
Series RISC-V: Change RISC-V bit manipulation / scalar crypto builtin types | expand

Message

Tsukasa OI Sept. 12, 2023, 1:28 a.m. UTC
Hello,

My research suggests my previous RFC patchs will not break any real-world
programs (as far as I could find) and I will submit this patch set
(previously, two RFC patch sets) for upstream contribution.

RFC PATCH 1 (combined to this):
<https://gcc.gnu.org/pipermail/gcc-patches/2023-September/629527.html>
RFC PATCH 2 (combined to this):
<https://gcc.gnu.org/pipermail/gcc-patches/2023-September/629644.html>

This patch set consists of two commits:

1.  Changing signed types to unsigned types on bit manipulation and scalar
    crypto intrinsics.
2.  Changing from uint64_t (changed from int64_t on the PATCH 1/2) to
    uint32_t on SHA-256, SM3 and SM4 intrinsics (all operate on 32-bit
    integers and upper 32-bits are not affected).

This is in sync with following commits in LLVM (will be a part of 17):

1. 599421ae36c3
  ("[RISCV] Use unsigned instead of signed types for Zk* and Zb* builtins.")
2. a64b3e92c7cb
  ("[RISCV] Re-define sha256, Zksed, and Zksh intrinsics to use i32 types.")

Many RISC-V builtins operate in signed integer types but in many cases,
they are better to be unsigned.

It follows with a bit fixed cover letter from the previous RFC PATCH sets.

Sincerely,
Tsukasa



Many RISC-V builtins operate in signed integer types but in many cases,
they are better to be unsigned.

There are a few reasons to do that in PATCH 1/2:

1.  Being more natural
    For bit manipulation operations, the direct input and the manipulated
    result should have an unsigned type.
    e.g. __builtin_bswap16
        Both input and output should be (and are) unsigned.
    e.g. __builtin_popcount
        The input should be (and is) unsigned.
        The output is a bit count and is in int (signed integer).
2.  In parity with LLVM (likely in version 17)
    LLVM made similar changes to this patch set in the commit 599421ae36c3
    ("[RISCV] Use unsigned instead of signed types for Zk* and Zb*
    builtins.") by Craig Topper.
    Note that shift amount / round number argument types are changed to
    unsigned in this LLVM commit, I did the same.
3.  Minimum compatibility breakage
    This change rarely causes warnings even if both -Wall and -Wextra are
    specified.

This is not completely compatible.  For instance, we will notice when
operating with for instance C++'s "auto" / "decltype" or overload
resolution.  But I consider this change in PATCH 1/2 is acceptable.



There are also operations that only operate in 32-bit integers but require
XLEN-bit wide integers.  Intrinsics for SHA-256, SM3 and SM4 applies.

PATCH 2/2 changes this in parity with the LLVM commit a64b3e92c7cb ("[RISCV]
Re-define sha256, Zksed, and Zksh intrinsics to use i32 types.") by Craig
Topper and makes those intrinsics accept/return uint32_t even on RV64.

This instruction/expansion changes are based on the handling of 32-bit
instructions on RV64 (such as ADDW).

Before:
   riscv_<op>_si: For RV32, fully operate on uint32_t
   riscv_<op>_di: For RV64, fully operate on uint64_t
After:
  *riscv_<op>_si: For RV32, fully operate on uint32_t
   riscv_<op>_di_extended:
                  For RV64. Input is uint32_t and output is int64_t,
                  sign-extended from the int32_t result
                  (represents a part of <op> behavior).
   riscv_<op>_si: Common (fully operate on uint32_t).
                  On RV32, "expands" to *riscv_<op>_si.
                  On RV64, initially expands to riscv_<op>_di_extended and
                  extracts lower 32-bits from the int64_t result.

I think this (not completely compatible) change is still acceptable.




Tsukasa OI (2):
  RISC-V: Make bit manipulation value / round number and shift amount
    types for builtins unsigned
  RISC-V: Make SHA-256, SM3 and SM4 builtins operate on uint32_t

 gcc/config/riscv/crypto.md                    | 161 ++++++++++++------
 gcc/config/riscv/riscv-builtins.cc            |  14 +-
 gcc/config/riscv/riscv-cmo.def                |  16 +-
 gcc/config/riscv/riscv-ftypes.def             |  23 ++-
 gcc/config/riscv/riscv-scalar-crypto.def      |  96 +++++------
 gcc/testsuite/gcc.target/riscv/zbc32.c        |   6 +-
 gcc/testsuite/gcc.target/riscv/zbc64.c        |   6 +-
 gcc/testsuite/gcc.target/riscv/zbkb32.c       |  10 +-
 gcc/testsuite/gcc.target/riscv/zbkb64.c       |   8 +-
 gcc/testsuite/gcc.target/riscv/zbkc32.c       |   4 +-
 gcc/testsuite/gcc.target/riscv/zbkc64.c       |   4 +-
 gcc/testsuite/gcc.target/riscv/zbkx32.c       |   4 +-
 gcc/testsuite/gcc.target/riscv/zbkx64.c       |   4 +-
 gcc/testsuite/gcc.target/riscv/zknd32.c       |   4 +-
 gcc/testsuite/gcc.target/riscv/zknd64.c       |  10 +-
 gcc/testsuite/gcc.target/riscv/zkne32.c       |   4 +-
 gcc/testsuite/gcc.target/riscv/zkne64.c       |   8 +-
 .../gcc.target/riscv/zknh-sha256-32.c         |  10 ++
 .../riscv/{zknh-sha256.c => zknh-sha256-64.c} |   8 +-
 .../gcc.target/riscv/zknh-sha512-32.c         |  12 +-
 .../gcc.target/riscv/zknh-sha512-64.c         |   8 +-
 gcc/testsuite/gcc.target/riscv/zksed32.c      |   4 +-
 gcc/testsuite/gcc.target/riscv/zksed64.c      |   4 +-
 gcc/testsuite/gcc.target/riscv/zksh32.c       |   4 +-
 gcc/testsuite/gcc.target/riscv/zksh64.c       |   4 +-
 25 files changed, 247 insertions(+), 189 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/zknh-sha256-32.c
 rename gcc/testsuite/gcc.target/riscv/{zknh-sha256.c => zknh-sha256-64.c} (79%)


base-commit: fb4b53d964b797e5f3380726175c95110c4ff9ff