isel: Fold more in gimple_expand_vec_cond_expr [PR115659]
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_gcc_build--master-arm |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gcc_check--master-arm |
success
|
Test passed
|
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 |
success
|
Test passed
|
Commit Message
Hi,
As PR115659 shows, assuming c = x CMP y, there are some
folding chances for patterns r = c ? -1/z : z/0.
For r = c ? -1 : z, it can be folded into:
- r = c | z (with ior_optab supported)
- or r = c ? c : z
while for r = c ? z : 0, it can be foled into:
- r = c & z (with and_optab supported)
- or r = c ? z : c
This patch is to teach ISEL to take care of them and also
remove the redundant gsi_replace as the caller of function
gimple_expand_vec_cond_expr will handle it.
Bootstrapped and regtested on x86_64-redhat-linux and
powerpc64{,le}-linux-gnu.
Is it ok for trunk?
BR,
Kewen
-----
PR tree-optimization/115659
gcc/ChangeLog:
* gimple-isel.cc (gimple_expand_vec_cond_expr): Add more foldings for
patterns x CMP y ? -1 : z and x CMP y ? z : 0.
---
gcc/gimple-isel.cc | 48 +++++++++++++++++++++++++++++++++++++++-------
1 file changed, 41 insertions(+), 7 deletions(-)
--
2.43.0
Comments
On Mon, Jul 1, 2024 at 8:16 AM Kewen.Lin <linkw@linux.ibm.com> wrote:
>
> Hi,
>
> As PR115659 shows, assuming c = x CMP y, there are some
> folding chances for patterns r = c ? -1/z : z/0.
>
> For r = c ? -1 : z, it can be folded into:
> - r = c | z (with ior_optab supported)
> - or r = c ? c : z
>
> while for r = c ? z : 0, it can be foled into:
> - r = c & z (with and_optab supported)
> - or r = c ? z : c
>
> This patch is to teach ISEL to take care of them and also
> remove the redundant gsi_replace as the caller of function
> gimple_expand_vec_cond_expr will handle it.
Yeah, not the nicest API ...
> Bootstrapped and regtested on x86_64-redhat-linux and
> powerpc64{,le}-linux-gnu.
>
> Is it ok for trunk?
Minor nit below
> BR,
> Kewen
> -----
> PR tree-optimization/115659
>
> gcc/ChangeLog:
>
> * gimple-isel.cc (gimple_expand_vec_cond_expr): Add more foldings for
> patterns x CMP y ? -1 : z and x CMP y ? z : 0.
> ---
> gcc/gimple-isel.cc | 48 +++++++++++++++++++++++++++++++++++++++-------
> 1 file changed, 41 insertions(+), 7 deletions(-)
>
> diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc
> index 54c1801038b..71af1a8cd97 100644
> --- a/gcc/gimple-isel.cc
> +++ b/gcc/gimple-isel.cc
> @@ -240,16 +240,50 @@ gimple_expand_vec_cond_expr (struct function *fun, gimple_stmt_iterator *gsi,
> can_compute_op0 = expand_vec_cmp_expr_p (op0a_type, op0_type,
> tcode);
>
> - /* Try to fold x CMP y ? -1 : 0 to x CMP y. */
> if (can_compute_op0
> - && integer_minus_onep (op1)
> - && integer_zerop (op2)
> && TYPE_MODE (TREE_TYPE (lhs)) == TYPE_MODE (TREE_TYPE (op0)))
> {
> - tree conv_op = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (lhs), op0);
> - gassign *new_stmt = gimple_build_assign (lhs, conv_op);
> - gsi_replace (gsi, new_stmt, true);
> - return new_stmt;
> + /* Assuming c = x CMP y. */
> + bool op1_minus_onep = integer_minus_onep (op1);
> + bool op2_zerop = integer_zerop (op2);
> + tree vtype = TREE_TYPE (lhs);
> + machine_mode vmode = TYPE_MODE (vtype);
> + /* Try to fold r = c ? -1 : 0 to r = c. */
> + if (op1_minus_onep && op2_zerop)
> + {
> + tree conv_op = build1 (VIEW_CONVERT_EXPR, vtype, op0);
> + return gimple_build_assign (lhs, conv_op);
> + }
> + /* Try to fold r = c ? -1 : z to r = c | z, or
> + r = c ? c : z. */
> + if (op1_minus_onep)
> + {
> + tree conv_op = build1 (VIEW_CONVERT_EXPR, vtype, op0);
> + tree new_op0 = make_ssa_name (vtype);
> + gassign *new_stmt = gimple_build_assign (new_op0, conv_op);
> + gsi_insert_seq_before (gsi, new_stmt, GSI_SAME_STMT);
> + if (optab_handler (ior_optab, vmode) != CODE_FOR_nothing)
> + /* r = c | z */
> + return gimple_build_assign (lhs, BIT_IOR_EXPR, new_op0,
> + op2);
> + /* r = c ? c : z */
> + op1 = new_op0;
maybe better call it new_op1 then? Or new_op.
> + }
> + /* Try to fold r = c ? z : 0 to r = c & z, or
> + r = c ? z : c. */
> + else if (op2_zerop)
> + {
> + tree conv_op = build1 (VIEW_CONVERT_EXPR, vtype, op0);
> + tree new_op0 = make_ssa_name (vtype);
> + gassign *new_stmt = gimple_build_assign (new_op0, conv_op);
> + gsi_insert_seq_before (gsi, new_stmt, GSI_SAME_STMT);
> + if (optab_handler (and_optab, vmode) != CODE_FOR_nothing)
> + /* r = c | z */
> + return gimple_build_assign (lhs, BIT_AND_EXPR, new_op0,
> + op1);
> + /* r = c ? z : c */
> + op2 = new_op0;
Likewise (new_op2 or also new_op).
OK with that nit fixed.
Thanks,
Richard.
> + }
> }
>
> /* When the compare has EH we do not want to forward it when
> --
> 2.43.0
on 2024/7/1 22:28, Richard Biener wrote:
> On Mon, Jul 1, 2024 at 8:16 AM Kewen.Lin <linkw@linux.ibm.com> wrote:
>>
>> Hi,
>>
>> As PR115659 shows, assuming c = x CMP y, there are some
>> folding chances for patterns r = c ? -1/z : z/0.
>>
>> For r = c ? -1 : z, it can be folded into:
>> - r = c | z (with ior_optab supported)
>> - or r = c ? c : z
>>
>> while for r = c ? z : 0, it can be foled into:
>> - r = c & z (with and_optab supported)
>> - or r = c ? z : c
>>
>> This patch is to teach ISEL to take care of them and also
>> remove the redundant gsi_replace as the caller of function
>> gimple_expand_vec_cond_expr will handle it.
>
> Yeah, not the nicest API ...
>
>> Bootstrapped and regtested on x86_64-redhat-linux and
>> powerpc64{,le}-linux-gnu.
>>
>> Is it ok for trunk?
>
> Minor nit below
>
>> BR,
>> Kewen
>> -----
>> PR tree-optimization/115659
>>
>> gcc/ChangeLog:
>>
>> * gimple-isel.cc (gimple_expand_vec_cond_expr): Add more foldings for
>> patterns x CMP y ? -1 : z and x CMP y ? z : 0.
>> ---
>> gcc/gimple-isel.cc | 48 +++++++++++++++++++++++++++++++++++++++-------
>> 1 file changed, 41 insertions(+), 7 deletions(-)
>>
>> diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc
>> index 54c1801038b..71af1a8cd97 100644
>> --- a/gcc/gimple-isel.cc
>> +++ b/gcc/gimple-isel.cc
>> @@ -240,16 +240,50 @@ gimple_expand_vec_cond_expr (struct function *fun, gimple_stmt_iterator *gsi,
>> can_compute_op0 = expand_vec_cmp_expr_p (op0a_type, op0_type,
>> tcode);
>>
>> - /* Try to fold x CMP y ? -1 : 0 to x CMP y. */
>> if (can_compute_op0
>> - && integer_minus_onep (op1)
>> - && integer_zerop (op2)
>> && TYPE_MODE (TREE_TYPE (lhs)) == TYPE_MODE (TREE_TYPE (op0)))
>> {
>> - tree conv_op = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (lhs), op0);
>> - gassign *new_stmt = gimple_build_assign (lhs, conv_op);
>> - gsi_replace (gsi, new_stmt, true);
>> - return new_stmt;
>> + /* Assuming c = x CMP y. */
>> + bool op1_minus_onep = integer_minus_onep (op1);
>> + bool op2_zerop = integer_zerop (op2);
>> + tree vtype = TREE_TYPE (lhs);
>> + machine_mode vmode = TYPE_MODE (vtype);
>> + /* Try to fold r = c ? -1 : 0 to r = c. */
>> + if (op1_minus_onep && op2_zerop)
>> + {
>> + tree conv_op = build1 (VIEW_CONVERT_EXPR, vtype, op0);
>> + return gimple_build_assign (lhs, conv_op);
>> + }
>> + /* Try to fold r = c ? -1 : z to r = c | z, or
>> + r = c ? c : z. */
>> + if (op1_minus_onep)
>> + {
>> + tree conv_op = build1 (VIEW_CONVERT_EXPR, vtype, op0);
>> + tree new_op0 = make_ssa_name (vtype);
>> + gassign *new_stmt = gimple_build_assign (new_op0, conv_op);
>> + gsi_insert_seq_before (gsi, new_stmt, GSI_SAME_STMT);
>> + if (optab_handler (ior_optab, vmode) != CODE_FOR_nothing)
>> + /* r = c | z */
>> + return gimple_build_assign (lhs, BIT_IOR_EXPR, new_op0,
>> + op2);
>> + /* r = c ? c : z */
>> + op1 = new_op0;
>
> maybe better call it new_op1 then? Or new_op.
>
>> + }
>> + /* Try to fold r = c ? z : 0 to r = c & z, or
>> + r = c ? z : c. */
>> + else if (op2_zerop)
>> + {
>> + tree conv_op = build1 (VIEW_CONVERT_EXPR, vtype, op0);
>> + tree new_op0 = make_ssa_name (vtype);
>> + gassign *new_stmt = gimple_build_assign (new_op0, conv_op);
>> + gsi_insert_seq_before (gsi, new_stmt, GSI_SAME_STMT);
>> + if (optab_handler (and_optab, vmode) != CODE_FOR_nothing)
>> + /* r = c | z */
>> + return gimple_build_assign (lhs, BIT_AND_EXPR, new_op0,
>> + op1);
>> + /* r = c ? z : c */
>> + op2 = new_op0;
>
> Likewise (new_op2 or also new_op).
>
> OK with that nit fixed.
Thanks Richi, refined with new_op1/new_op2, re-tested well and pushed as r15-1763.
BR,
Kewen
>
> Thanks,
> Richard.
>
>> + }
>> }
>>
>> /* When the compare has EH we do not want to forward it when
>> --
>> 2.43.0
@@ -240,16 +240,50 @@ gimple_expand_vec_cond_expr (struct function *fun, gimple_stmt_iterator *gsi,
can_compute_op0 = expand_vec_cmp_expr_p (op0a_type, op0_type,
tcode);
- /* Try to fold x CMP y ? -1 : 0 to x CMP y. */
if (can_compute_op0
- && integer_minus_onep (op1)
- && integer_zerop (op2)
&& TYPE_MODE (TREE_TYPE (lhs)) == TYPE_MODE (TREE_TYPE (op0)))
{
- tree conv_op = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (lhs), op0);
- gassign *new_stmt = gimple_build_assign (lhs, conv_op);
- gsi_replace (gsi, new_stmt, true);
- return new_stmt;
+ /* Assuming c = x CMP y. */
+ bool op1_minus_onep = integer_minus_onep (op1);
+ bool op2_zerop = integer_zerop (op2);
+ tree vtype = TREE_TYPE (lhs);
+ machine_mode vmode = TYPE_MODE (vtype);
+ /* Try to fold r = c ? -1 : 0 to r = c. */
+ if (op1_minus_onep && op2_zerop)
+ {
+ tree conv_op = build1 (VIEW_CONVERT_EXPR, vtype, op0);
+ return gimple_build_assign (lhs, conv_op);
+ }
+ /* Try to fold r = c ? -1 : z to r = c | z, or
+ r = c ? c : z. */
+ if (op1_minus_onep)
+ {
+ tree conv_op = build1 (VIEW_CONVERT_EXPR, vtype, op0);
+ tree new_op0 = make_ssa_name (vtype);
+ gassign *new_stmt = gimple_build_assign (new_op0, conv_op);
+ gsi_insert_seq_before (gsi, new_stmt, GSI_SAME_STMT);
+ if (optab_handler (ior_optab, vmode) != CODE_FOR_nothing)
+ /* r = c | z */
+ return gimple_build_assign (lhs, BIT_IOR_EXPR, new_op0,
+ op2);
+ /* r = c ? c : z */
+ op1 = new_op0;
+ }
+ /* Try to fold r = c ? z : 0 to r = c & z, or
+ r = c ? z : c. */
+ else if (op2_zerop)
+ {
+ tree conv_op = build1 (VIEW_CONVERT_EXPR, vtype, op0);
+ tree new_op0 = make_ssa_name (vtype);
+ gassign *new_stmt = gimple_build_assign (new_op0, conv_op);
+ gsi_insert_seq_before (gsi, new_stmt, GSI_SAME_STMT);
+ if (optab_handler (and_optab, vmode) != CODE_FOR_nothing)
+ /* r = c | z */
+ return gimple_build_assign (lhs, BIT_AND_EXPR, new_op0,
+ op1);
+ /* r = c ? z : c */
+ op2 = new_op0;
+ }
}
/* When the compare has EH we do not want to forward it when