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

Reply via email to