于 2025年1月15日 GMT+08:00 下午6:12:34,Xi Ruoyao <xry...@xry111.site> 写道:
>For things like
>
> (x | 0x101) << 11
>
>It's obvious to write:
>
> ori $r4,$r4,257
> slli.d $r4,$r4,11
>
>But we are actually generating something insane:
>
> lu12i.w $r12,524288>>12 # 0x80000
> ori $r12,$r12,2048
> slli.d $r4,$r4,11
> or $r4,$r4,$r12
> jr $r1
/* snip */
>
>+/* Test if reassociate (a << shamt) [&|^] mask to
>+ (a [&|^] (mask >> shamt)) << shamt is possible and beneficial.
>+ If true, return (mask >> shamt). Return NULL_RTX otherwise. */
>+
>+rtx
>+loongarch_reassoc_shift_bitwise (bool is_and, rtx shamt, rtx mask,
>+ machine_mode mode)
>+{
>+ gcc_checking_assert (CONST_INT_P (shamt));
>+ gcc_checking_assert (CONST_INT_P (mask));
>+ gcc_checking_assert (mode == SImode || mode == DImode);
>+
>+ if (ctz_hwi (INTVAL (mask)) < INTVAL (shamt))
>+ return NULL_RTX;
>+
>+ rtx new_mask = gen_int_mode (UINTVAL (mask) >> UINTVAL (shamt), mode);
>+ if (const_uns_arith_operand (new_mask, mode))
>+ return new_mask;
>+
>+ if (!is_and)
>+ return NULL_RTX;
>+
>+ if (low_bitmask_operand (new_mask, mode))
>+ return new_mask;
>+
>+ new_mask = gen_int_mode (INTVAL (mask) >> UINTVAL (shamt), mode);
This is problematic: it relies on shifting negative integers for which the
behavior is
unspecificed in C++14. I'll send V2 to fix it.