On Fri, Jan 17, 2025 at 4:38 AM Hongyu Wang <[email protected]> wrote:
>
> Hi,
>
> For shld/shrd_ndd_2 insn, the spiltter outputs wrong pattern that
> mixed parallel for clobber and set. Separate out the set to dest
> from parallel to fix it.
>
> Bootstrapped & regtested on x86-64-pc-linux-gnu.
>
> Ok for trunk?
>
> gcc/ChangeLog:
>
> PR target/118510
> * config/i386/i386.md (*x86_64_shld_ndd_2): Separate set to
> operand[0] from parallel in output template.
> (*x86_shld_ndd_2): Likewise.
> (*x86_64_shrd_ndd_2): Likewise.
> (*x86_shrd_ndd_2): Likewise.
>
> gcc/testsuite/ChangeLog:
>
> PR target/118510
> * gcc.target/i386/pr118510.c: New test.
> ---
> gcc/config/i386/i386.md | 16 ++++++++--------
> gcc/testsuite/gcc.target/i386/pr118510.c | 14 ++++++++++++++
> 2 files changed, 22 insertions(+), 8 deletions(-)
> create mode 100644 gcc/testsuite/gcc.target/i386/pr118510.c
>
> diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
> index 362b0ddcf40..ebfd76593ab 100644
> --- a/gcc/config/i386/i386.md
> +++ b/gcc/config/i386/i386.md
> @@ -15615,8 +15615,8 @@ (define_insn_and_split "*x86_64_shld_ndd_2"
> (minus:QI (const_int 64)
> (and:QI (match_dup 3)
> (const_int 63)))) 0)))
> - (clobber (reg:CC FLAGS_REG))
> - (set (match_dup 0) (match_dup 4))])]
> + (clobber (reg:CC FLAGS_REG))])
> + (set (match_dup 0) (match_dup 4))]
Is there a reason to have operand 0 with "nonimmediate_operand"
predicate? If you have to generate a register temporary and then
unconditionally copy it to the output, it is better to use
"register_operand" predicate and leave middle end to do the copy for
you. Please see the patch at comment #3 in the PR.
Uros.
> {
> operands[4] = gen_reg_rtx (DImode);
> emit_move_insn (operands[4], operands[0]);
> @@ -15851,8 +15851,8 @@ (define_insn_and_split "*x86_shld_ndd_2"
> (minus:QI (const_int 32)
> (and:QI (match_dup 3)
> (const_int 31)))) 0)))
> - (clobber (reg:CC FLAGS_REG))
> - (set (match_dup 0) (match_dup 4))])]
> + (clobber (reg:CC FLAGS_REG))])
> + (set (match_dup 0) (match_dup 4))]
> {
> operands[4] = gen_reg_rtx (SImode);
> emit_move_insn (operands[4], operands[0]);
> @@ -17010,8 +17010,8 @@ (define_insn_and_split "*x86_64_shrd_ndd_2"
> (minus:QI (const_int 64)
> (and:QI (match_dup 3)
> (const_int 63)))) 0)))
> - (clobber (reg:CC FLAGS_REG))
> - (set (match_dup 0) (match_dup 4))])]
> + (clobber (reg:CC FLAGS_REG))])
> + (set (match_dup 0) (match_dup 4))]
> {
> operands[4] = gen_reg_rtx (DImode);
> emit_move_insn (operands[4], operands[0]);
> @@ -17245,8 +17245,8 @@ (define_insn_and_split "*x86_shrd_ndd_2"
> (minus:QI (const_int 32)
> (and:QI (match_dup 3)
> (const_int 31)))) 0)))
> - (clobber (reg:CC FLAGS_REG))
> - (set (match_dup 0) (match_dup 4))])]
> + (clobber (reg:CC FLAGS_REG))])
> + (set (match_dup 0) (match_dup 4))]
> {
> operands[4] = gen_reg_rtx (SImode);
> emit_move_insn (operands[4], operands[0]);
> diff --git a/gcc/testsuite/gcc.target/i386/pr118510.c
> b/gcc/testsuite/gcc.target/i386/pr118510.c
> new file mode 100644
> index 00000000000..6cfe8182b6f
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr118510.c
> @@ -0,0 +1,14 @@
> +/* { dg-do compile { target { ! ia32 } } } */
> +/* { dg-options "-O2 -mapxf" } */
> +
> +typedef struct cpp_num cpp_num;
> +struct cpp_num {
> + int high;
> + unsigned low;
> + int overflow;
> +};
> +int num_rshift_n;
> +cpp_num num_lshift(cpp_num num) {
> + num.low = num.low >> num_rshift_n | num.high << (32 - num_rshift_n);
> + return num;
> +}
> --
> 2.31.1
>