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.

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 4935367dd0e0..e394cac7d417 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 000000000000..93cca8ad6f1c
--- /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));
+  }
+}
+

Reply via email to