aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorXi Ruoyao <xry111@xry111.site>2025-03-07 12:49:54 +0800
committerXi Ruoyao <xry111@xry111.site>2025-03-10 17:12:05 +0800
commitc7d493baf13f1f144f2c4bc375383b6ce5d88a76 (patch)
treea8b35640d4434608ca0338cac0a485013978937f /gcc
parent9fe5106ea92218380ea2a7166417565f79fe680d (diff)
downloadgcc-c7d493baf13f1f144f2c4bc375383b6ce5d88a76.zip
gcc-c7d493baf13f1f144f2c4bc375383b6ce5d88a76.tar.gz
gcc-c7d493baf13f1f144f2c4bc375383b6ce5d88a76.tar.bz2
LoongArch: Fix ICE when trying to recognize bitwise + alsl.w pair [PR119127]
When we call loongarch_reassoc_shift_bitwise for <optab>_alsl_reversesi_extend, the mask is in DImode but we are trying to operate it in SImode, causing an ICE. To fix the issue sign-extend the mask into the mode we want. And also specially handle the case the mask is extended into -1 to avoid a miss-optimization. gcc/ChangeLog: PR target/119127 * config/loongarch/loongarch.cc (loongarch_reassoc_shift_bitwise): Sign extend mask to mode, specially handle the case it's extended to -1. * config/loongarch/loongarch.md (loongarch_reassoc_shift_bitwise): Update the comment for the special case.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/loongarch/loongarch.cc22
-rw-r--r--gcc/config/loongarch/loongarch.md6
-rw-r--r--gcc/testsuite/gcc.target/loongarch/pr119127.c14
3 files changed, 31 insertions, 11 deletions
diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
index 68f5d85..01f0486 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -4575,8 +4575,22 @@ loongarch_reassoc_shift_bitwise (bool is_and, rtx shamt, rtx mask,
if (ctz_hwi (INTVAL (mask)) < INTVAL (shamt))
return NULL_RTX;
+ /* When trying alsl.w, deliberately ignore the high bits. */
+ mask = gen_int_mode (UINTVAL (mask), mode);
+
rtx new_mask = simplify_const_binary_operation (LSHIFTRT, mode, mask,
shamt);
+
+ /* Do an arithmetic shift for checking ins_zero_bitmask_operand or -1:
+ ashiftrt (0xffffffff00000000, 2) is 0xffffffff60000000 which is an
+ ins_zero_bitmask_operand, but lshiftrt will produce
+ 0x3fffffff60000000. */
+ rtx new_mask_1 = simplify_const_binary_operation (ASHIFTRT, mode, mask,
+ shamt);
+
+ if (is_and && const_m1_operand (new_mask_1, mode))
+ return new_mask_1;
+
if (const_uns_arith_operand (new_mask, mode))
return new_mask;
@@ -4586,13 +4600,7 @@ loongarch_reassoc_shift_bitwise (bool is_and, rtx shamt, rtx mask,
if (low_bitmask_operand (new_mask, mode))
return new_mask;
- /* Do an arithmetic shift for checking ins_zero_bitmask_operand:
- ashiftrt (0xffffffff00000000, 2) is 0xffffffff60000000 which is an
- ins_zero_bitmask_operand, but lshiftrt will produce
- 0x3fffffff60000000. */
- new_mask = simplify_const_binary_operation (ASHIFTRT, mode, mask,
- shamt);
- return ins_zero_bitmask_operand (new_mask, mode) ? new_mask : NULL_RTX;
+ return ins_zero_bitmask_operand (new_mask_1, mode) ? new_mask_1 : NULL_RTX;
}
/* Implement TARGET_CONSTANT_ALIGNMENT. */
diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md
index 90c475e..f7005de 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -3200,10 +3200,8 @@
emit_insn (gen_<optab>di3 (operands[0], operands[1], operands[3]));
else
{
- /* Hmm would we really reach here? If we reach here we'd have
- a miss-optimization in the generic code (as it should have
- optimized this to alslsi3_extend_subreg). But let's be safe
- than sorry. */
+ /* We can end up here with things like:
+ x:DI = sign_extend(a:SI + ((b:DI << 2) & 0xfffffffc)#0) */
gcc_checking_assert (<is_and>);
emit_move_insn (operands[0], operands[1]);
}
diff --git a/gcc/testsuite/gcc.target/loongarch/pr119127.c b/gcc/testsuite/gcc.target/loongarch/pr119127.c
new file mode 100644
index 0000000..4e253be
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/pr119127.c
@@ -0,0 +1,14 @@
+/* PR target/119127: ICE caused by operating DImode const in SImode */
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=loongarch64 -mabi=lp64d" } */
+
+int x;
+struct Type {
+ unsigned SubclassData : 24;
+} y;
+
+void
+test (void)
+{
+ x = y.SubclassData * 37;
+}