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.
This commit is contained in:
parent
9fe5106ea9
commit
c7d493baf1
3 changed files with 31 additions and 11 deletions
|
@ -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. */
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
|
14
gcc/testsuite/gcc.target/loongarch/pr119127.c
Normal file
14
gcc/testsuite/gcc.target/loongarch/pr119127.c
Normal file
|
@ -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;
|
||||
}
|
Loading…
Add table
Reference in a new issue