]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[RISC-V][PR target/121160] Avoid bogus force_reg call
authorJeff Law <jlaw@ventanamicro.com>
Wed, 13 Aug 2025 17:17:02 +0000 (11:17 -0600)
committerJeff Law <jlaw@ventanamicro.com>
Wed, 13 Aug 2025 17:17:52 +0000 (11:17 -0600)
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.

gcc/config/riscv/riscv.cc
gcc/testsuite/gcc.target/riscv/pr121160.c [new file with mode: 0644]

index 4935367dd0e03f383bf2cee97d1f66f2a9839f57..e394cac7d41736fe2f913302c0f9dd689793cbfc 100644 (file)
@@ -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 (file)
index 0000000..93cca8a
--- /dev/null
@@ -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));
+  }
+}
+