On Sat, 2023-09-09 at 15:42 +0800, Lulu Cheng wrote: > PR 111334 > > gcc/ChangeLog: > > * config/loongarch/loongarch.md: Fix bug of <optab>di3_fake. > > gcc/testsuite/ChangeLog: > > * gcc.target/loongarch/pr111334.c: New test.
Ok. Despite I still think we should use unspec inside any_div, this should be enough to prevent the compiler from matching di3_fake. > --- > gcc/config/loongarch/loongarch.md | 14 +++++-- > gcc/testsuite/gcc.target/loongarch/pr111334.c | 39 +++++++++++++++++++ > 2 files changed, 49 insertions(+), 4 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/loongarch/pr111334.c > > diff --git a/gcc/config/loongarch/loongarch.md > b/gcc/config/loongarch/loongarch.md > index 1dc6b524416..3fa32562aa6 100644 > --- a/gcc/config/loongarch/loongarch.md > +++ b/gcc/config/loongarch/loongarch.md > @@ -72,6 +72,9 @@ (define_c_enum "unspec" [ > UNSPEC_LUI_H_HI12 > UNSPEC_TLS_LOW > > + ;; Fake div.w[u] mod.w[u] > + UNSPEC_FAKE_ANY_DIV > + > UNSPEC_SIBCALL_VALUE_MULTIPLE_INTERNAL_1 > UNSPEC_CALL_VALUE_MULTIPLE_INTERNAL_1 > ]) > @@ -900,7 +903,7 @@ (define_expand "<optab><mode>3" > (match_operand:GPR 2 "register_operand")))] > "" > { > - if (GET_MODE (operands[0]) == SImode) > + if (GET_MODE (operands[0]) == SImode && TARGET_64BIT) > { > rtx reg1 = gen_reg_rtx (DImode); > rtx reg2 = gen_reg_rtx (DImode); > @@ -938,9 +941,12 @@ (define_insn "*<optab><mode>3" > (define_insn "<optab>di3_fake" > [(set (match_operand:DI 0 "register_operand" "=r,&r,&r") > (sign_extend:DI > - (any_div:SI (match_operand:DI 1 "register_operand" "r,r,0") > - (match_operand:DI 2 "register_operand" "r,r,r"))))] > - "" > + (unspec:SI > + [(subreg:SI > + (any_div:DI (match_operand:DI 1 "register_operand" "r,r,0") > + (match_operand:DI 2 "register_operand" "r,r,r")) 0)] > + UNSPEC_FAKE_ANY_DIV)))] > + "TARGET_64BIT" > { > return loongarch_output_division ("<insn>.w<u>\t%0,%1,%2", operands); > } > diff --git a/gcc/testsuite/gcc.target/loongarch/pr111334.c > b/gcc/testsuite/gcc.target/loongarch/pr111334.c > new file mode 100644 > index 00000000000..47366afcb74 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/loongarch/pr111334.c > @@ -0,0 +1,39 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2" } */ > + > +unsigned > +util_next_power_of_two (unsigned x) > +{ > + return (1 << __builtin_clz (x - 1)); > +} > + > +extern int create_vec_from_array (void); > + > +struct ac_shader_args { > + struct { > + unsigned char offset; > + unsigned char size; > + } args[384]; > +}; > + > +struct isel_context { > + const struct ac_shader_args* args; > + int arg_temps[384]; > +}; > + > + > +void > +add_startpgm (struct isel_context* ctx, unsigned short arg_count) > +{ > + > + for (unsigned i = 0, arg = 0; i < arg_count; i++) > + { > + unsigned size = ctx->args->args[i].size; > + unsigned reg = ctx->args->args[i].offset; > + > + if (reg % ( 4 < util_next_power_of_two (size) > + ? 4 : util_next_power_of_two (size))) > + ctx->arg_temps[i] = create_vec_from_array (); > + } > +} > + -- Xi Ruoyao <xry...@xry111.site> School of Aerospace Science and Technology, Xidian University