This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Allow all 1s of integer as standard SSE constants
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: Uros Bizjak <ubizjak at gmail dot com>
- Cc: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 21 Apr 2016 13:58:39 -0700
- Subject: Re: [PATCH] Allow all 1s of integer as standard SSE constants
- Authentication-results: sourceware.org; auth=none
- References: <20160420195359 dot GA3113 at intel dot com> <CAFULd4ZJrw9hWtkxCZmRHinz+aACOvnkRU4FUXVYcFD4_qjeVA at mail dot gmail dot com> <CAFULd4Y8HGC=+iFtp9PmqW2XcVwnhNygH6si0J1OCNWipGjBLg at mail dot gmail dot com> <CAFULd4b3WPYGr=uL=1D7RmnrYBeviVt0=-ckgT-8zJJcae+m3A at mail dot gmail dot com> <CAMe9rOr9B+X-H0PmBt=fsO3BmQR_MrF3nAg2pdsOoa3NpNV3PA at mail dot gmail dot com> <CAFULd4auhHb54j3GwZRCUiuAxdPcbKk+oA4+paWU=tWsQ+7Whw at mail dot gmail dot com> <CAMe9rOovKPRPNZyaq+-uWz3kwFXJRrTuh4-cFrxYMaWaUZJoYg at mail dot gmail dot com> <CAFULd4bu+r+AFgWg+W+xtKUP=diOdsfh-dxCScFZTyEf+Uu+xg at mail dot gmail dot com> <CAMe9rOrx2R+bDOHZxcp_tcMBpgD0zVsxM7L0FMOAzHKXLQPuGg at mail dot gmail dot com> <CAFULd4ab3zoOWqe3KnMHgjnRusPFoBdvFxWpb5hAMoZG24OgZw at mail dot gmail dot com> <CAMe9rOo3HzitjaH2sF7vio+OVekQVjn0WrL4D5pLkXVbtxmXNA at mail dot gmail dot com> <CAFULd4bZeZdVrTetdiS5Dp9s+BZLTiDYx7YAiy4WEfDOwtB0yQ at mail dot gmail dot com> <CAMe9rOrnJhtFN+AuPznhHh6K7Bs0hdGvcNiv-dcSz2smd37Dcg at mail dot gmail dot com> <CAFULd4a56mPORpFoiKd5XHXgRe8gPoJU+aNK_VYsU+7wc3WB0Q at mail dot gmail dot com> <CAMe9rOofVGmbb_jQ2+QwHTRs54Tbf+--kHYYPmZeV0sg_GMstw at mail dot gmail dot com>
On Thu, Apr 21, 2016 at 9:37 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Thu, Apr 21, 2016 at 9:31 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
>> On Thu, Apr 21, 2016 at 4:50 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>
>>>>> I tried and it doesn't work since the correct mode may not be always
>>>>> available in predicates. Yes, they pass mode. But they just do
>>>>>
>>>>> mode = GET_MODE (op);
>>>>>
>>>>> which returns VOIDmode for -1.
>>>>
>>>> Well, looking at generated gcc/insns-preds.c, the predicates do:
>>>>
>>>> (mode == VOIDmode || GET_MODE (op) == mode).
>>>>
>>>> They *check* and don't *assign* "mode" variable.
>>>>
>>>> So, I see no problem checking "mode" variable (that gets the value
>>>> from the pattern) in the predicates.
>>>
>>> This is an incomplete list:
>>>
>>> combine.c: && ! push_operand (dest, GET_MODE (dest)))
>>> expr.c: if (push_operand (x, GET_MODE (x)))
>>> expr.c: && ! push_operand (x, GET_MODE (x))))
>>> gcse.c: && ! push_operand (dest, GET_MODE (dest)))
>>> gcse.c: if (general_operand (exp, GET_MODE (reg)))
>>> ifcvt.c: if (! general_operand (cmp_a, GET_MODE (cmp_a))
>>> ifcvt.c: || ! general_operand (cmp_b, GET_MODE (cmp_b)))
>>> ifcvt.c: else if (general_operand (b, GET_MODE (b)))
>>> ifcvt.c: if (! general_operand (a, GET_MODE (a)) || tmp_a)
>>> ifcvt.c: if (! general_operand (b, GET_MODE (b)) || tmp_b)
>>> ira-costs.c: if (address_operand (op, GET_MODE (op))
>>> ira-costs.c: && general_operand (SET_SRC (set), GET_MODE (SET_SRC (set))))
>>> lower-subreg.c: if (GET_MODE (op_operand) != word_mode
>>> lower-subreg.c: && GET_MODE_SIZE (GET_MODE (op_operand)) > UNITS_PER_WORD)
>>> lower-subreg.c: GET_MODE (op_operand),
>>> lra-constraints.c: if (simplify_operand_subreg (i, GET_MODE (old)) ||
>>> op_change_p)
>>> optabs.c: create_output_operand (&ops[0], target, GET_MODE (target));
>>> optabs.c: create_input_operand (&ops[1], op0, GET_MODE (op0));
>>> postreload-gcse.c: if (! push_operand (dest, GET_MODE (dest)))
>>> postreload-gcse.c: && general_operand (src, GET_MODE (src))
>>> postreload-gcse.c: && general_operand (dest, GET_MODE (dest))
>>> postreload-gcse.c: && general_operand (src, GET_MODE (src))
>>>
>>> IRA and LRA use GET_MODE and pass it to predicates.
>>
>> I don't know what are you trying to prove here ...
>
> The "mode" argument passed to predates can't be used to determine if
> -1 is a valid SSE constant.
>
Hi Uros,
Here is the updated patch with my standard_sse_constant_p change and
your SSE/AVX pattern change. I didn't include your
standard_sse_constant_opcode since it didn't compile nor is needed
for this purpose.
--
H.J.
From 57c811f25e0735e744d255b3d66a86dbb131749c Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Sun, 6 Mar 2016 06:40:31 -0800
Subject: [PATCH] Allow all 1s of integer as standard SSE constants
Since all 1s in TImode is standard SSE2 constants, all 1s in OImode is
standard AVX2 constants and all 1s in XImode is standard AVX512F constants,
pass mode to standard_sse_constant_p and standard_sse_constant_opcode
to check if all 1s is available for target.
* config/i386/i386-protos.h (standard_sse_constant_p): Take
machine_mode with VOIDmode as default.
* config/i386/i386.c (standard_sse_constant_p): Get mode if
it is VOIDmode. Return 2 for all 1s of integer in supported
modes.
(ix86_expand_vector_move): Pass mode to standard_sse_constant_p.
* config/i386/i386.md (*movxi_internal_avx512f): Replace
vector_move_operand with nonimmediate_or_sse_const_operand and
use BC instead of C in constraint. Check register_operand
instead of MEM_P.
(*movoi_internal_avx): Add a "BC" alternative for AVX2. Check
register_operand instead of MEM_P.
(*movti_internal): Add a "BC" alternative for SSE2. Check
register_operand instead of MEM_P for SSE.
---
gcc/config/i386/i386-protos.h | 2 +-
gcc/config/i386/i386.c | 27 ++++++++++++++++++++-------
gcc/config/i386/i386.md | 39 ++++++++++++++++++++++++---------------
3 files changed, 45 insertions(+), 23 deletions(-)
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index ff47bc1..cf54189 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -50,7 +50,7 @@ extern bool ix86_using_red_zone (void);
extern int standard_80387_constant_p (rtx);
extern const char *standard_80387_constant_opcode (rtx);
extern rtx standard_80387_constant_rtx (int);
-extern int standard_sse_constant_p (rtx);
+extern int standard_sse_constant_p (rtx, machine_mode = VOIDmode);
extern const char *standard_sse_constant_opcode (rtx_insn *, rtx);
extern bool symbolic_reference_mentioned_p (rtx);
extern bool extended_reg_mentioned_p (rtx);
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 6379313..dd951c2 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -10766,18 +10766,31 @@ standard_80387_constant_rtx (int idx)
in supported SSE/AVX vector mode. */
int
-standard_sse_constant_p (rtx x)
+standard_sse_constant_p (rtx x, machine_mode mode)
{
- machine_mode mode;
-
if (!TARGET_SSE)
return 0;
- mode = GET_MODE (x);
-
+ if (mode == VOIDmode)
+ mode = GET_MODE (x);
+
if (x == const0_rtx || x == CONST0_RTX (mode))
return 1;
- if (vector_all_ones_operand (x, mode))
+ if (CONST_INT_P (x))
+ {
+ /* If mode != VOIDmode, standard_sse_constant_p must be called:
+ 1. On TImode with SSE2.
+ 2. On OImode with AVX2.
+ 3. On XImode with AVX512F.
+ */
+ if ((HOST_WIDE_INT) INTVAL (x) == HOST_WIDE_INT_M1
+ && (mode == VOIDmode
+ || (mode == TImode && TARGET_SSE2)
+ || (mode == OImode && TARGET_AVX2)
+ || (mode == XImode && TARGET_AVX512F)))
+ return 2;
+ }
+ else if (vector_all_ones_operand (x, mode))
switch (mode)
{
case V16QImode:
@@ -18758,7 +18771,7 @@ ix86_expand_vector_move (machine_mode mode, rtx operands[])
&& (CONSTANT_P (op1)
|| (SUBREG_P (op1)
&& CONSTANT_P (SUBREG_REG (op1))))
- && !standard_sse_constant_p (op1))
+ && !standard_sse_constant_p (op1, mode))
op1 = validize_mem (force_const_mem (mode, op1));
/* We need to check memory alignment for SSE mode since attribute
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index babd0a4..716c4ba 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -1970,9 +1970,11 @@
(set_attr "length_immediate" "1")])
(define_insn "*movxi_internal_avx512f"
- [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,m")
- (match_operand:XI 1 "vector_move_operand" "C ,vm,v"))]
- "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+ [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,m")
+ (match_operand:XI 1 "nonimmediate_or_sse_const_operand" "BC,vm,v"))]
+ "TARGET_AVX512F
+ && (register_operand (operands[0], XImode)
+ || register_operand (operands[1], XImode))"
{
switch (which_alternative)
{
@@ -1994,9 +1996,11 @@
(set_attr "mode" "XI")])
(define_insn "*movoi_internal_avx"
- [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,m")
- (match_operand:OI 1 "vector_move_operand" "C ,vm,v"))]
- "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+ [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v,v ,m")
+ (match_operand:OI 1 "nonimmediate_or_sse_const_operand" "BC,C,vm,v"))]
+ "TARGET_AVX
+ && (register_operand (operands[0], OImode)
+ || register_operand (operands[1], OImode))"
{
switch (get_attr_type (insn))
{
@@ -2028,7 +2032,8 @@
gcc_unreachable ();
}
}
- [(set_attr "type" "sselog1,ssemov,ssemov")
+ [(set_attr "isa" "avx2,*,*,*")
+ (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
(set_attr "prefix" "vex")
(set (attr "mode")
(cond [(ior (match_operand 0 "ext_sse_reg_operand")
@@ -2036,17 +2041,21 @@
(const_string "XI")
(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
(const_string "V8SF")
- (and (eq_attr "alternative" "2")
+ (and (eq_attr "alternative" "3")
(match_test "TARGET_SSE_TYPELESS_STORES"))
(const_string "V8SF")
]
(const_string "OI")))])
(define_insn "*movti_internal"
- [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,m")
- (match_operand:TI 1 "general_operand" "riFo,re,C,vm,v"))]
- "(TARGET_64BIT || TARGET_SSE)
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+ [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v ,v,v ,m")
+ (match_operand:TI 1 "general_operand" "riFo,re,BC,C,vm,v"))]
+ "(TARGET_64BIT
+ && !(MEM_P (operands[0]) && MEM_P (operands[1])))
+ || (TARGET_SSE
+ && nonimmediate_or_sse_const_operand (operands[1], TImode)
+ && (register_operand (operands[0], TImode)
+ || register_operand (operands[1], TImode)))"
{
switch (get_attr_type (insn))
{
@@ -2083,8 +2092,8 @@
gcc_unreachable ();
}
}
- [(set_attr "isa" "x64,x64,*,*,*")
- (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
+ [(set_attr "isa" "x64,x64,sse2,*,*,*")
+ (set_attr "type" "multi,multi,sselog1,sselog1,ssemov,ssemov")
(set (attr "prefix")
(if_then_else (eq_attr "type" "sselog1,ssemov")
(const_string "maybe_vex")
@@ -2098,7 +2107,7 @@
(ior (not (match_test "TARGET_SSE2"))
(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
(const_string "V4SF")
- (and (eq_attr "alternative" "4")
+ (and (eq_attr "alternative" "5")
(match_test "TARGET_SSE_TYPELESS_STORES"))
(const_string "V4SF")
(match_test "TARGET_AVX")
--
2.5.5