Message ID | 20220721051841.13832-1-hongtao.liu@intel.com |
---|---|
State | New |
Headers | show |
Series | [V3] Extend 16/32-bit vector bit_op patterns with (m, 0, i) alternative. | expand |
On Thu, Jul 21, 2022 at 7:19 AM liuhongt <hongtao.liu@intel.com> wrote: > > And split it after reload. > > gcc/ChangeLog: > > PR target/106038 > * config/i386/mmx.md (<code><mode>3): New define_expand, it's > original "<code><mode>3". > (*<code><mode>3): New define_insn, it's original > "<code><mode>3" be extended to handle memory and immediate > operand with ix86_binary_operator_ok. Also adjust define_split > after it. > (mmxinsnmode): New mode attribute. > (*mov<mode>_imm): Refactor with mmxinsnmode. > * config/i386/predicates.md > (register_or_x86_64_const_vector_operand): New predicate. > > gcc/testsuite/ChangeLog: > > * gcc.target/i386/pr106038-1.c: New test. OK. Thanks, Uros. > --- > gcc/config/i386/mmx.md | 70 ++++++++++++---------- > gcc/config/i386/predicates.md | 4 ++ > gcc/testsuite/gcc.target/i386/pr106038-1.c | 27 +++++++++ > 3 files changed, 70 insertions(+), 31 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/i386/pr106038-1.c > > diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md > index 3294c1e6274..dda4b43f5c1 100644 > --- a/gcc/config/i386/mmx.md > +++ b/gcc/config/i386/mmx.md > @@ -86,6 +86,14 @@ (define_mode_attr mmxvecsize > [(V8QI "b") (V4QI "b") (V2QI "b") > (V4HI "w") (V2HI "w") (V2SI "d") (V1DI "q")]) > > +;; Mapping to same size integral mode. > +(define_mode_attr mmxinsnmode > + [(V8QI "DI") (V4QI "SI") (V2QI "HI") > + (V4HI "DI") (V2HI "SI") > + (V2SI "DI") > + (V4HF "DI") (V2HF "SI") > + (V2SF "DI")]) > + > (define_mode_attr mmxdoublemode > [(V8QI "V8HI") (V4HI "V4SI")]) > > @@ -350,22 +358,7 @@ (define_insn_and_split "*mov<mode>_imm" > HOST_WIDE_INT val = ix86_convert_const_vector_to_integer (operands[1], > <MODE>mode); > operands[1] = GEN_INT (val); > - machine_mode mode; > - switch (GET_MODE_SIZE (<MODE>mode)) > - { > - case 2: > - mode = HImode; > - break; > - case 4: > - mode = SImode; > - break; > - case 8: > - mode = DImode; > - break; > - default: > - gcc_unreachable (); > - } > - operands[0] = lowpart_subreg (mode, operands[0], <MODE>mode); > + operands[0] = lowpart_subreg (<mmxinsnmode>mode, operands[0], <MODE>mode); > }) > > ;; For TARGET_64BIT we always round up to 8 bytes. > @@ -2974,33 +2967,48 @@ (define_insn "*mmx_<code><mode>3" > (set_attr "type" "mmxadd,sselog,sselog,sselog") > (set_attr "mode" "DI,TI,TI,TI")]) > > -(define_insn "<code><mode>3" > - [(set (match_operand:VI_16_32 0 "register_operand" "=?r,x,x,v") > +(define_expand "<code><mode>3" > + [(set (match_operand:VI_16_32 0 "nonimmediate_operand") > (any_logic:VI_16_32 > - (match_operand:VI_16_32 1 "register_operand" "%0,0,x,v") > - (match_operand:VI_16_32 2 "register_operand" "r,x,x,v"))) > - (clobber (reg:CC FLAGS_REG))] > + (match_operand:VI_16_32 1 "nonimmediate_operand") > + (match_operand:VI_16_32 2 "nonimmediate_or_x86_64_const_vector_operand")))] > "" > + "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") > + > +(define_insn "*<code><mode>3" > + [(set (match_operand:VI_16_32 0 "nonimmediate_operand" "=?r,m,x,x,v") > + (any_logic:VI_16_32 > + (match_operand:VI_16_32 1 "nonimmediate_operand" "%0,0,0,x,v") > + (match_operand:VI_16_32 2 "nonimmediate_or_x86_64_const_vector_operand" "r,i,x,x,v"))) > + (clobber (reg:CC FLAGS_REG))] > + "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" > "#" > - [(set_attr "isa" "*,sse2_noavx,avx,avx512vl") > - (set_attr "type" "alu,sselog,sselog,sselog") > - (set_attr "mode" "SI,TI,TI,TI")]) > + [(set_attr "isa" "*,*,sse2_noavx,avx,avx512vl") > + (set_attr "type" "alu,alu,sselog,sselog,sselog") > + (set_attr "mode" "SI,SI,TI,TI,TI")]) > > (define_split > - [(set (match_operand:VI_16_32 0 "general_reg_operand") > + [(set (match_operand:VI_16_32 0 "nonimmediate_gr_operand") > (any_logic:VI_16_32 > - (match_operand:VI_16_32 1 "general_reg_operand") > - (match_operand:VI_16_32 2 "general_reg_operand"))) > + (match_operand:VI_16_32 1 "nonimmediate_gr_operand") > + (match_operand:VI_16_32 2 "reg_or_const_vector_operand"))) > (clobber (reg:CC FLAGS_REG))] > "reload_completed" > [(parallel > [(set (match_dup 0) > - (any_logic:SI (match_dup 1) (match_dup 2))) > + (any_logic:<mmxinsnmode> (match_dup 1) (match_dup 2))) > (clobber (reg:CC FLAGS_REG))])] > { > - operands[2] = lowpart_subreg (SImode, operands[2], <MODE>mode); > - operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode); > - operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode); > + if (!register_operand (operands[2], <MODE>mode)) > + { > + HOST_WIDE_INT val = ix86_convert_const_vector_to_integer (operands[2], > + <MODE>mode); > + operands[2] = GEN_INT (val); > + } > + else > + operands[2] = lowpart_subreg (<mmxinsnmode>mode, operands[2], <MODE>mode); > + operands[1] = lowpart_subreg (<mmxinsnmode>mode, operands[1], <MODE>mode); > + operands[0] = lowpart_subreg (<mmxinsnmode>mode, operands[0], <MODE>mode); > }) > > (define_split > diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md > index c71c453cceb..73dfd46bf90 100644 > --- a/gcc/config/i386/predicates.md > +++ b/gcc/config/i386/predicates.md > @@ -1205,6 +1205,10 @@ (define_predicate "x86_64_const_vector_operand" > return trunc_int_for_mode (val, SImode) == val; > }) > > +(define_predicate "nonimmediate_or_x86_64_const_vector_operand" > + (ior (match_operand 0 "nonimmediate_operand") > + (match_operand 0 "x86_64_const_vector_operand"))) > + > ;; Return true when OP is nonimmediate or standard SSE constant. > (define_predicate "nonimmediate_or_sse_const_operand" > (ior (match_operand 0 "nonimmediate_operand") > diff --git a/gcc/testsuite/gcc.target/i386/pr106038-1.c b/gcc/testsuite/gcc.target/i386/pr106038-1.c > new file mode 100644 > index 00000000000..bb52385c8a5 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/pr106038-1.c > @@ -0,0 +1,27 @@ > +/* { dg-do compile } */ > +/* { dg-options "-msse2 -O2" } */ > +/* { dg-final { scan-assembler-not "xmm" } } */ > + > +void > +foo3 (char* a, char* __restrict b) > +{ > + a[0] &= 1; > + a[1] &= 2; > + a[2] &= 3; > + a[3] &= 3; > +} > + > +void > +foo4 (char* a, char* __restrict b) > +{ > + a[0] &= 1; > + a[1] &= 2; > +} > + > + > +void > +foo1 (short* a, short* __restrict b) > +{ > + a[0] &= 1; > + a[1] &= 2; > +} > -- > 2.18.1 >
diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md index 3294c1e6274..dda4b43f5c1 100644 --- a/gcc/config/i386/mmx.md +++ b/gcc/config/i386/mmx.md @@ -86,6 +86,14 @@ (define_mode_attr mmxvecsize [(V8QI "b") (V4QI "b") (V2QI "b") (V4HI "w") (V2HI "w") (V2SI "d") (V1DI "q")]) +;; Mapping to same size integral mode. +(define_mode_attr mmxinsnmode + [(V8QI "DI") (V4QI "SI") (V2QI "HI") + (V4HI "DI") (V2HI "SI") + (V2SI "DI") + (V4HF "DI") (V2HF "SI") + (V2SF "DI")]) + (define_mode_attr mmxdoublemode [(V8QI "V8HI") (V4HI "V4SI")]) @@ -350,22 +358,7 @@ (define_insn_and_split "*mov<mode>_imm" HOST_WIDE_INT val = ix86_convert_const_vector_to_integer (operands[1], <MODE>mode); operands[1] = GEN_INT (val); - machine_mode mode; - switch (GET_MODE_SIZE (<MODE>mode)) - { - case 2: - mode = HImode; - break; - case 4: - mode = SImode; - break; - case 8: - mode = DImode; - break; - default: - gcc_unreachable (); - } - operands[0] = lowpart_subreg (mode, operands[0], <MODE>mode); + operands[0] = lowpart_subreg (<mmxinsnmode>mode, operands[0], <MODE>mode); }) ;; For TARGET_64BIT we always round up to 8 bytes. @@ -2974,33 +2967,48 @@ (define_insn "*mmx_<code><mode>3" (set_attr "type" "mmxadd,sselog,sselog,sselog") (set_attr "mode" "DI,TI,TI,TI")]) -(define_insn "<code><mode>3" - [(set (match_operand:VI_16_32 0 "register_operand" "=?r,x,x,v") +(define_expand "<code><mode>3" + [(set (match_operand:VI_16_32 0 "nonimmediate_operand") (any_logic:VI_16_32 - (match_operand:VI_16_32 1 "register_operand" "%0,0,x,v") - (match_operand:VI_16_32 2 "register_operand" "r,x,x,v"))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:VI_16_32 1 "nonimmediate_operand") + (match_operand:VI_16_32 2 "nonimmediate_or_x86_64_const_vector_operand")))] "" + "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") + +(define_insn "*<code><mode>3" + [(set (match_operand:VI_16_32 0 "nonimmediate_operand" "=?r,m,x,x,v") + (any_logic:VI_16_32 + (match_operand:VI_16_32 1 "nonimmediate_operand" "%0,0,0,x,v") + (match_operand:VI_16_32 2 "nonimmediate_or_x86_64_const_vector_operand" "r,i,x,x,v"))) + (clobber (reg:CC FLAGS_REG))] + "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" "#" - [(set_attr "isa" "*,sse2_noavx,avx,avx512vl") - (set_attr "type" "alu,sselog,sselog,sselog") - (set_attr "mode" "SI,TI,TI,TI")]) + [(set_attr "isa" "*,*,sse2_noavx,avx,avx512vl") + (set_attr "type" "alu,alu,sselog,sselog,sselog") + (set_attr "mode" "SI,SI,TI,TI,TI")]) (define_split - [(set (match_operand:VI_16_32 0 "general_reg_operand") + [(set (match_operand:VI_16_32 0 "nonimmediate_gr_operand") (any_logic:VI_16_32 - (match_operand:VI_16_32 1 "general_reg_operand") - (match_operand:VI_16_32 2 "general_reg_operand"))) + (match_operand:VI_16_32 1 "nonimmediate_gr_operand") + (match_operand:VI_16_32 2 "reg_or_const_vector_operand"))) (clobber (reg:CC FLAGS_REG))] "reload_completed" [(parallel [(set (match_dup 0) - (any_logic:SI (match_dup 1) (match_dup 2))) + (any_logic:<mmxinsnmode> (match_dup 1) (match_dup 2))) (clobber (reg:CC FLAGS_REG))])] { - operands[2] = lowpart_subreg (SImode, operands[2], <MODE>mode); - operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode); - operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode); + if (!register_operand (operands[2], <MODE>mode)) + { + HOST_WIDE_INT val = ix86_convert_const_vector_to_integer (operands[2], + <MODE>mode); + operands[2] = GEN_INT (val); + } + else + operands[2] = lowpart_subreg (<mmxinsnmode>mode, operands[2], <MODE>mode); + operands[1] = lowpart_subreg (<mmxinsnmode>mode, operands[1], <MODE>mode); + operands[0] = lowpart_subreg (<mmxinsnmode>mode, operands[0], <MODE>mode); }) (define_split diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index c71c453cceb..73dfd46bf90 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -1205,6 +1205,10 @@ (define_predicate "x86_64_const_vector_operand" return trunc_int_for_mode (val, SImode) == val; }) +(define_predicate "nonimmediate_or_x86_64_const_vector_operand" + (ior (match_operand 0 "nonimmediate_operand") + (match_operand 0 "x86_64_const_vector_operand"))) + ;; Return true when OP is nonimmediate or standard SSE constant. (define_predicate "nonimmediate_or_sse_const_operand" (ior (match_operand 0 "nonimmediate_operand") diff --git a/gcc/testsuite/gcc.target/i386/pr106038-1.c b/gcc/testsuite/gcc.target/i386/pr106038-1.c new file mode 100644 index 00000000000..bb52385c8a5 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr106038-1.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-msse2 -O2" } */ +/* { dg-final { scan-assembler-not "xmm" } } */ + +void +foo3 (char* a, char* __restrict b) +{ + a[0] &= 1; + a[1] &= 2; + a[2] &= 3; + a[3] &= 3; +} + +void +foo4 (char* a, char* __restrict b) +{ + a[0] &= 1; + a[1] &= 2; +} + + +void +foo1 (short* a, short* __restrict b) +{ + a[0] &= 1; + a[1] &= 2; +}