On Tue, 1 Apr 2025 22:57:33 -0600, Jeff Law wrote:
>
>
> On 4/1/25 12:20 AM, Jin Ma wrote:
> > Assuming we have the following variables:
> >
> > unsigned long long a0, a1;
> > unsigned int a2;
> >
> > For the expression:
> >
> > a0 = (a0 << 50) >> 49; // slli a0, a0, 50 + srli a0, a0, 49
> > a2 = a1 + a0; // addw a2, a1, a0 + slli a2, a2, 32 + srli a2, a2,
> > 32
> >
> > In the optimization process of ZBA (combine pass), it would be optimized to:
> >
> > a2 = a0 << 1 + a1; // sh1add a2, a0, a1 + zext.w a2, a2
> >
> > This is clearly incorrect, as it overlooks the fact that a0=a0&0x7ffe,
> > meaning
> > that the bits a0[32:14] are set to zero.
> >
> > gcc/ChangeLog:
> >
> > * config/riscv/bitmanip.md: The optimization can only be applied if
> > the high bit of operands[3] is set to 1.
> >
> > gcc/testsuite/ChangeLog:
> >
> > * gcc.target/riscv/zba-shNadd-09.c: New test.
> > * gcc.target/riscv/zba-shNadd-10.c: New test.
> > ---
> > gcc/config/riscv/bitmanip.md | 3 ++-
> > .../gcc.target/riscv/zba-shNadd-09.c | 12 +++++++++++
> > .../gcc.target/riscv/zba-shNadd-10.c | 20 +++++++++++++++++++
> > 3 files changed, 34 insertions(+), 1 deletion(-)
> > create mode 100644 gcc/testsuite/gcc.target/riscv/zba-shNadd-09.c
> > create mode 100644 gcc/testsuite/gcc.target/riscv/zba-shNadd-10.c
> >
> > diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
> > index b29c127bcb8..9091c48b106 100644
> > --- a/gcc/config/riscv/bitmanip.md
> > +++ b/gcc/config/riscv/bitmanip.md
> > @@ -80,7 +80,8 @@ (define_split
> > (match_operand:DI 3
> > "consecutive_bits_operand")) 0)
> > (subreg:SI (match_operand:DI 4
> > "register_operand") 0))))]
> > "TARGET_64BIT && TARGET_ZBA
> > - && riscv_shamt_matches_mask_p (INTVAL (operands[2]), INTVAL
> > (operands[3]))"
> > + && riscv_shamt_matches_mask_p (INTVAL (operands[2]), INTVAL
> > (operands[3]))
> > + && ((INTVAL (operands[3]) & (1 << 31)) != 0)"
> > [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2))
> > (match_dup 4)))
> > (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))])
> So I would add a comment to that new condition. Something like
> /* Ensure the mask includes all the bits in SImode. */
>
> We need to be careful with constants like 1 << 31. Something like
> (HOST_WIDE_INT_1U << 31) would be better from a type safety standpoint
> (INTVAL returns a HOST_WIDE_INT object).
>
> > +#include <stdio.h>
> In general, avoid #includes if you can in tests. Remove the <stdio.h>
> include.
>
> > + printf("%llu\n", d);
> Instead of a printf and using dg-output, the standard way we test for
> correctness is by either aborting or calling exit (0). So rather than
> the printf use
>
> if (d != 3023282)
> __builtin_abort ();
> __builtin_exit (0);
>
> And drop the dg-output line.
>
>
> With those changes this patch is probably OK. We'd want to post the V2
> so that the pre-commit tester can chew on it.
Yes, Very professional advice. I will make the changes and submit V2.
Best regards,
Jin Ma