https://gcc.gnu.org/g:8e1baca395be6ff248c7b40eedff9e6e37467315
commit r16-6056-g8e1baca395be6ff248c7b40eedff9e6e37467315 Author: Jiajie Chen <[email protected]> Date: Sun Aug 6 16:36:14 2023 +0800 LoongArch: Fix signed 32-bit overflow for loongarch32 target 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/la32/trunc_int_for_mode.c: New test. Reviewed-by: Xi Ruoyao <[email protected]> Reviewed-by: Lulu Cheng <[email protected]> Diff: --- gcc/config/loongarch/loongarch.cc | 1 + .../gcc.target/loongarch/la32/trunc_int_for_mode.c | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index cf61fcc760c1..61e112952ae6 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -5761,6 +5761,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/la32/trunc_int_for_mode.c b/gcc/testsuite/gcc.target/loongarch/la32/trunc_int_for_mode.c new file mode 100644 index 000000000000..1a2feba3b60b --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la32/trunc_int_for_mode.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { 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; +}
