From: Jiajie Chen <[email protected]>

When rhs equals to 0x7fffffff, adding 1 to rhs overflows SI, generating
invalid const_int.

gcc/ChangeLog:

        * config/loongarch/loongarch.cc (loongarch_emit_int_compare):
        Call trunc_int_mode to ensure valid rhs.

gcc/testsuite/ChangeLog:

        * gcc.target/loongarch/trunc_int_for_mode.c: New test.
---
 gcc/config/loongarch/loongarch.cc               |  1 +
 .../gcc.target/loongarch/trunc_int_for_mode.c   | 17 +++++++++++++++++
 2 files changed, 18 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/loongarch/trunc_int_for_mode.c

diff --git a/gcc/config/loongarch/loongarch.cc 
b/gcc/config/loongarch/loongarch.cc
index 94b190dad3b..c31805db95d 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -5555,6 +5555,7 @@ loongarch_emit_int_compare (enum rtx_code *code, rtx 
*op0, rtx *op1)
                break;
 
              new_rhs = rhs + (increment ? 1 : -1);
+             new_rhs = trunc_int_for_mode (new_rhs, GET_MODE (*op0));
              if (loongarch_integer_cost (new_rhs)
                    < loongarch_integer_cost (rhs))
                {
diff --git a/gcc/testsuite/gcc.target/loongarch/trunc_int_for_mode.c 
b/gcc/testsuite/gcc.target/loongarch/trunc_int_for_mode.c
new file mode 100644
index 00000000000..e473bd0c297
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/trunc_int_for_mode.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target { loongarch32*-*-* } } } */
+/* { dg-options "-O2" } */
+float
+__cbrtf (float x)
+{
+  double r = 13322 * 1111;
+  float ub = r;
+  long long cvt1 = x;
+  long long m0 = cvt1 << 19;
+  long long m1 = m0 >> 63;
+  if ((m0 ^ m1) < (1ULL << 31))
+    {
+      cvt1 = (cvt1 + (1 << 31)) & 0xffffffff00000000;
+      ub = cvt1;
+    }
+  return ub;
+}
-- 
2.34.1

Reply via email to