diff options
author | Jeff Law <jlaw@ventanamicro.com> | 2025-08-13 11:17:02 -0600 |
---|---|---|
committer | Jeff Law <jlaw@ventanamicro.com> | 2025-08-13 11:17:52 -0600 |
commit | e31a353f1e7c5fe24a6b9d881adabfeed99dc845 (patch) | |
tree | d47dcf942b2d51a548bf7b50ce6d6a7d1f4103ab | |
parent | 11f7d5648c42cd2ef6f0841cde6292b94831e7b6 (diff) | |
download | gcc-e31a353f1e7c5fe24a6b9d881adabfeed99dc845.zip gcc-e31a353f1e7c5fe24a6b9d881adabfeed99dc845.tar.gz gcc-e31a353f1e7c5fe24a6b9d881adabfeed99dc845.tar.bz2 |
[RISC-V][PR target/121160] Avoid bogus force_reg call
When we canonicalize the comparison for a czero sequence we need to handle both
integer and fp comparisons. Furthermore, within the integer space we want to
make sure we promote any sub-word objects to a full word.
All that is working fine. After promotion we then force the value into a
register if it is not a register or constant already. The idea is not to have
to special case subregs in subsequent code. This works fine except when we're
presented with a floating point object that would be a subword. (subreg:SF
(reg:SI)) on rv64 for example.
So this tightens up that force_reg step. Bootstapped and regression tested on
riscv64-linux-gnu and tested on riscv32-elf and riscv64-elf.
Pushing to the trunk after pre-commit verifies no regressions.
Jeff
PR target/121160
gcc/
* config/riscv/riscv.cc (canonicalize_comparands); Tighten check for
forcing value into a GPR.
gcc/testsuite/
* gcc.target/riscv/pr121160.c: New test.
-rw-r--r-- | gcc/config/riscv/riscv.cc | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/pr121160.c | 60 |
2 files changed, 62 insertions, 2 deletions
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 4935367..e394cac7 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -5444,9 +5444,9 @@ canonicalize_comparands (rtx_code code, rtx *op0, rtx *op1) /* We might have been handed back a SUBREG. Just to make things easy, force it into a REG. */ - if (!REG_P (*op0) && !CONST_INT_P (*op0)) + if (!REG_P (*op0) && !CONST_INT_P (*op0) && INTEGRAL_MODE_P (GET_MODE (*op0))) *op0 = force_reg (word_mode, *op0); - if (!REG_P (*op1) && !CONST_INT_P (*op1)) + if (!REG_P (*op1) && !CONST_INT_P (*op1) && INTEGRAL_MODE_P (GET_MODE (*op1))) *op1 = force_reg (word_mode, *op1); } diff --git a/gcc/testsuite/gcc.target/riscv/pr121160.c b/gcc/testsuite/gcc.target/riscv/pr121160.c new file mode 100644 index 0000000..93cca8a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr121160.c @@ -0,0 +1,60 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -ffast-math -O2" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32d -ffast-math -O2" { target { rv32 } } } */ + + +typedef long int ssize_t; +typedef float MagickRealType; +typedef unsigned short Quantum; +typedef unsigned long long MagickSizeType; +typedef struct _PixelPacket +{ + Quantum blue, green, red, opacity; +} PixelPacket; +static inline Quantum +ClampToQuantum (const MagickRealType value) +{ + if (value <= 0.0f) + return ((Quantum) 0); + if (value >= (MagickRealType) ((Quantum) 65535)) + return (((Quantum) 65535)); + return ((Quantum) (value + 0.5f)); +} + +static inline float +HalfToSinglePrecision (const unsigned short half) +{ + typedef union _SinglePrecision + { + unsigned int fixed_point; + float single_precision; + } SinglePrecision; + register unsigned int exponent, significand, sign_bit; + SinglePrecision map; + unsigned int value; + if (significand == 0) + value = sign_bit << 31; + else + { + while ((significand & 0x00000400) == 0) + { + significand <<= 1; + } + value = (sign_bit << 31) | (exponent << 23) | (significand << 13); + } + map.fixed_point = value; + return (map.single_precision); +} + +void +ImportBlueQuantum (const MagickSizeType number_pixels, + PixelPacket *restrict q) +{ + register ssize_t x; + unsigned short pixel; + { + for (x = 0; x < (ssize_t) number_pixels; x++) + q->blue = ClampToQuantum (HalfToSinglePrecision (pixel)); + } +} + |