Re: [PATCH] RISC-V: Add conditional unary neg/abs/not autovec patterns

2023-08-24 Thread Richard Sandiford via Gcc-patches
Jeff Law  writes:
> On 8/22/23 02:08, juzhe.zh...@rivai.ai wrote:
>> Yes, I agree long-term we want every-thing be optimized as early as 
>> possible.
>> 
>> However, IMHO, it's impossible we can support every conditional patterns 
>> in the middle-end (match.pd).
>> It's a really big number.
>> 
>> For example, for sign_extend conversion, we have vsext.vf2 (vector SI -> 
>> vector DI),... vsext.vf4 (vector HI -> vector DI), vsext.vf8 (vector QI 
>> -> vector DI)..
>> Not only the conversion, every auto-vectorization patterns can have 
>> conditional format.
>> For example, abs,..rotate, sqrt, floor, ceil,etc.
>> I bet it could be over 100+ conditional optabs/internal FNs. It's huge 
>> number.
>> I don't see necessity that we should support them in middle-end 
>> (match.pd) since we known RTL back-end combine PASS can do the good job 
>> here.
>> 
>> Besides, LLVM doesn't such many conditional pattern. LLVM just has "add" 
>> and "select" separate IR then do the combine in the back-end:
>> https://godbolt.org/z/rYcMMG1eT 
>> 
>> You can see LLVM didn't do the op + select optimization in generic IR, 
>> they do the optimization in combine PASS.
>> 
>> So I prefer this patch solution and apply such solution for the future 
>> more support : sign extend, zero extend, float extend, abs, sqrt, ceil, 
>> floor, etc.
> It's certainly got the potential to get out of hand.  And it's not just 
> the vectorizer operations.  I know of an architecture that can execute 
> most of its ALU and loads/stores conditionally (not predication, but 
> actual conditional ops) like target  = (x COND Y) ? a << b ; a)
>
> I'd tend to lean towards synthesizing these conditional ops around a 
> conditional move/select primitive in gimple through the RTL expanders. 
> That would in turn set things up so that if the target had various 
> conditional operations like conditional shift it could be trivially 
> discovered by the combiner.

FWIW, one of the original motivations behind the COND_* internal
functions was to represent the fact that the operation is suppressed
(rather than being performed and discarded) when the predicate is false.
This allows if-conversion for FP operations even in strict FP modes,
since inactive lanes are guaranteed not to generate an exception.

I think it makes sense to add COND_* functions for anything that can
reasonably be done on FP types, and that could generate an FP exception.
E.g. sqrt was one of the examples mentioned, and I think COND_SQRT is
something that we should have.

I agree it's less clear-cut for purely integer stuff, or for FP operations
like neg and abs that are pure bit manipulation.  But perhaps there's a
question of how many operations are only defined for integers, and
whether the number is high enough for them to be treated differently.

I wouldn't have expected an explosion of operations to be a significant
issue, since (a) the underlying infrastructure is pretty mechanical and
(b) any operation that a target supports is going to need an .md pattern
whatever happens.

Thanks,
Richard


Re: [PATCH] RISC-V: Add conditional unary neg/abs/not autovec patterns

2023-08-22 Thread Lehua Ding

Hi Robin,

Thanks for these nice comments!


-  emit_insn (gen_vcond_mask (vmode, vmode, d->target, d->op0, d->op1, mask));
+  /* swap op0 and op1 since the order is opposite to pred_merge.  */
+  rtx ops2[] = {d->target, d->op1, d->op0, mask};
+  emit_vlmax_merge_insn (code_for_pred_merge (vmode), 
riscv_vector::RVV_MERGE_OP, ops2);
return true;
  }


This seems a separate, general fix that just surfaced in the course of
this patch?  Would be nice to have this factored out but as we already have
it, no need I guess.


Yes, since I change @vcond_mask_ from define_expand to 
define_insn_and_split. If I don't change it then I need to manually make 
sure that d->target, d->op1, d->op0 satisfy the predicate of the 
@vcond_mask (vregs pass will check it, so need forbidden mem operand). 
If I use emit_vlmax_merge_insn directly, it uses expand_insn inner, 
which automatically converts the operands for me to make it satisfy the 
predicate condition. This is one difference between gen_xxx and 
expand_insn. And I think calling emit_vlmax_merge_insn to generate 
pred_merge is the most appropriate and uniform way.



+  if (is_dummy_mask)
+{
+  /* Use TU, MASK ANY policy.  */
+  if (needs_fp_rounding (code, mode))
+   emit_nonvlmax_fp_tu_insn (icode, RVV_UNOP_TU, cond_ops, len);
+  else
+   emit_nonvlmax_tu_insn (icode, RVV_UNOP_TU, cond_ops, len);
+}


We have quite a bit of code duplication across the expand_cond_len functions
now (binop, ternop, unop).  Not particular to your patch but I'd suggest to
unify this later.


Indeed, leave it to me and I'll send another patch later to reduce this 
duplicate code.





+TEST_ALL (DEF_LOOP)
+
+/* NOTE: int abs operator is converted to vmslt + vneg.v */
+/* { dg-final { scan-assembler-times {\tvneg\.v\tv[0-9]+,v[0-9]+,v0\.t} 12 { xfail { 
any-opts "--param riscv-autovec-lmul=m2" } } } } */


Why does this fail with LMUL == 2 (also in the following tests)?  A comment
would be nice here.


This is because the number of iterations 5 in the testcase caused GCC to 
remove the Loop and turn it into two basic blocks, resulting in a 
doubling of the number of vnegs. I'm going to modify the iteration count 
(It should be big enough that that wouldn't happen even when LMUL=m8) so 
that it doesn't trigger that optimization.


V2 patch: https://gcc.gnu.org/pipermail/gcc-patches/2023-August/628210.html

--
Best,
Lehua



Re: [PATCH] RISC-V: Add conditional unary neg/abs/not autovec patterns

2023-08-22 Thread Robin Dapp via Gcc-patches
Hi Lehua,

no concerns here, just tiny remarks but in general LGTM as is.

> +(define_insn_and_split "*copysign_neg"
> +  [(set (match_operand:VF 0 "register_operand")
> +(neg:VF
> +  (unspec:VF [
> +(match_operand:VF 1 "register_operand")
> +(match_operand:VF 2 "register_operand")
> +  ] UNSPEC_VCOPYSIGN)))]
> +  "TARGET_VECTOR && can_create_pseudo_p ()"
> +  "#"
> +  "&& 1"
> +  [(const_int 0)]
> +{
> +  riscv_vector::emit_vlmax_insn (code_for_pred_ncopysign (mode),
> + riscv_vector::RVV_BINOP, operands);
> +  DONE;
> +})

It's a bit unfortunate that we need this now but well, no way around it.

> -  emit_insn (gen_vcond_mask (vmode, vmode, d->target, d->op0, d->op1, mask));
> +  /* swap op0 and op1 since the order is opposite to pred_merge.  */
> +  rtx ops2[] = {d->target, d->op1, d->op0, mask};
> +  emit_vlmax_merge_insn (code_for_pred_merge (vmode), 
> riscv_vector::RVV_MERGE_OP, ops2);
>return true;
>  }

This seems a separate, general fix that just surfaced in the course of
this patch?  Would be nice to have this factored out but as we already have
it, no need I guess.

> +  if (is_dummy_mask)
> +{
> +  /* Use TU, MASK ANY policy.  */
> +  if (needs_fp_rounding (code, mode))
> + emit_nonvlmax_fp_tu_insn (icode, RVV_UNOP_TU, cond_ops, len);
> +  else
> + emit_nonvlmax_tu_insn (icode, RVV_UNOP_TU, cond_ops, len);
> +}

We have quite a bit of code duplication across the expand_cond_len functions
now (binop, ternop, unop).  Not particular to your patch but I'd suggest to
unify this later. 

> +TEST_ALL (DEF_LOOP)
> +
> +/* NOTE: int abs operator is converted to vmslt + vneg.v */
> +/* { dg-final { scan-assembler-times {\tvneg\.v\tv[0-9]+,v[0-9]+,v0\.t} 12 { 
> xfail { any-opts "--param riscv-autovec-lmul=m2" } } } } */

Why does this fail with LMUL == 2 (also in the following tests)?  A comment
would be nice here.

Regards
 Robin



Re: Re: [PATCH] RISC-V: Add conditional unary neg/abs/not autovec patterns

2023-08-22 Thread 钟居哲
>> It's certainly got the potential to get out of hand.  And it's not just
>> the vectorizer operations.  I know of an architecture that can execute
>> most of its ALU and loads/stores conditionally (not predication, but
>> actual conditional ops) like target  = (x COND Y) ? a << b ; a)

Do you mean we need to add cond_abs, cond_sqrt, cond_sign_extend, 
cond_zero_extend, cond_float_extend,.
...etc, over 100+ optabs/fns for vectoriation optimizaiton and support them in 
gimple IR (middle-end match.pd) ?

Or it's ok fo now we try to support those conditional operations in RISC-V 
backend by combine PASS ?

I personally prefer the later and I assign Lehua working on it.

Thanks.


juzhe.zh...@rivai.ai
 
From: Jeff Law
Date: 2023-08-22 22:05
To: juzhe.zh...@rivai.ai; Robin Dapp; pinskia
CC: 丁乐华; gcc-patches; kito.cheng; palmer; richard.sandiford; Richard Biener
Subject: Re: [PATCH] RISC-V: Add conditional unary neg/abs/not autovec patterns
 
 
On 8/22/23 02:08, juzhe.zh...@rivai.ai wrote:
> Yes, I agree long-term we want every-thing be optimized as early as 
> possible.
> 
> However, IMHO, it's impossible we can support every conditional patterns 
> in the middle-end (match.pd).
> It's a really big number.
> 
> For example, for sign_extend conversion, we have vsext.vf2 (vector SI -> 
> vector DI),... vsext.vf4 (vector HI -> vector DI), vsext.vf8 (vector QI 
> -> vector DI)..
> Not only the conversion, every auto-vectorization patterns can have 
> conditional format.
> For example, abs,..rotate, sqrt, floor, ceil,etc.
> I bet it could be over 100+ conditional optabs/internal FNs. It's huge 
> number.
> I don't see necessity that we should support them in middle-end 
> (match.pd) since we known RTL back-end combine PASS can do the good job 
> here.
> 
> Besides, LLVM doesn't such many conditional pattern. LLVM just has "add" 
> and "select" separate IR then do the combine in the back-end:
> https://godbolt.org/z/rYcMMG1eT <https://godbolt.org/z/rYcMMG1eT>
> 
> You can see LLVM didn't do the op + select optimization in generic IR, 
> they do the optimization in combine PASS.
> 
> So I prefer this patch solution and apply such solution for the future 
> more support : sign extend, zero extend, float extend, abs, sqrt, ceil, 
> floor, etc.
It's certainly got the potential to get out of hand.  And it's not just 
the vectorizer operations.  I know of an architecture that can execute 
most of its ALU and loads/stores conditionally (not predication, but 
actual conditional ops) like target  = (x COND Y) ? a << b ; a)
 
I'd tend to lean towards synthesizing these conditional ops around a 
conditional move/select primitive in gimple through the RTL expanders. 
That would in turn set things up so that if the target had various 
conditional operations like conditional shift it could be trivially 
discovered by the combiner.
 
We still get most of the benefit of eliminating control flow early, a 
sensible gimple representation, relatively easy translation into RTL and 
  easy combination for targets with actual conditional operations.
 
It turns out that model is something we may want to work towards anyway. 
  We were looking at this exact problem in the context of zicond for 
riscv.  The biggest problem we've seen so far is that the generic 
conditional move expansion generates fairly poor code when the target 
doesn't actually have a conditional move primitive.
 
jeff
 


Re: [PATCH] RISC-V: Add conditional unary neg/abs/not autovec patterns

2023-08-22 Thread Jeff Law via Gcc-patches




On 8/22/23 02:08, juzhe.zh...@rivai.ai wrote:
Yes, I agree long-term we want every-thing be optimized as early as 
possible.


However, IMHO, it's impossible we can support every conditional patterns 
in the middle-end (match.pd).

It's a really big number.

For example, for sign_extend conversion, we have vsext.vf2 (vector SI -> 
vector DI),... vsext.vf4 (vector HI -> vector DI), vsext.vf8 (vector QI 
-> vector DI)..
Not only the conversion, every auto-vectorization patterns can have 
conditional format.

For example, abs,..rotate, sqrt, floor, ceil,etc.
I bet it could be over 100+ conditional optabs/internal FNs. It's huge 
number.
I don't see necessity that we should support them in middle-end 
(match.pd) since we known RTL back-end combine PASS can do the good job 
here.


Besides, LLVM doesn't such many conditional pattern. LLVM just has "add" 
and "select" separate IR then do the combine in the back-end:

https://godbolt.org/z/rYcMMG1eT 

You can see LLVM didn't do the op + select optimization in generic IR, 
they do the optimization in combine PASS.


So I prefer this patch solution and apply such solution for the future 
more support : sign extend, zero extend, float extend, abs, sqrt, ceil, 
floor, etc.
It's certainly got the potential to get out of hand.  And it's not just 
the vectorizer operations.  I know of an architecture that can execute 
most of its ALU and loads/stores conditionally (not predication, but 
actual conditional ops) like target  = (x COND Y) ? a << b ; a)


I'd tend to lean towards synthesizing these conditional ops around a 
conditional move/select primitive in gimple through the RTL expanders. 
That would in turn set things up so that if the target had various 
conditional operations like conditional shift it could be trivially 
discovered by the combiner.


We still get most of the benefit of eliminating control flow early, a 
sensible gimple representation, relatively easy translation into RTL and 
 easy combination for targets with actual conditional operations.


It turns out that model is something we may want to work towards anyway. 
 We were looking at this exact problem in the context of zicond for 
riscv.  The biggest problem we've seen so far is that the generic 
conditional move expansion generates fairly poor code when the target 
doesn't actually have a conditional move primitive.


jeff


Re: Re: [PATCH] RISC-V: Add conditional unary neg/abs/not autovec patterns

2023-08-22 Thread juzhe.zh...@rivai.ai
Yes, I agree long-term we want every-thing be optimized as early as possible.

However, IMHO, it's impossible we can support every conditional patterns in the 
middle-end (match.pd).
It's a really big number.

For example, for sign_extend conversion, we have vsext.vf2 (vector SI -> vector 
DI),... vsext.vf4 (vector HI -> vector DI), vsext.vf8 (vector QI -> vector DI)..
Not only the conversion, every auto-vectorization patterns can have conditional 
format. 
For example, abs,..rotate, sqrt, floor, ceil,etc.
I bet it could be over 100+ conditional optabs/internal FNs. It's huge number. 
I don't see necessity that we should support them in middle-end (match.pd) 
since we known RTL back-end combine PASS can do the good job here.

Besides, LLVM doesn't such many conditional pattern. LLVM just has "add" and 
"select" separate IR then do the combine in the back-end:
https://godbolt.org/z/rYcMMG1eT 

You can see LLVM didn't do the op + select optimization in generic IR, they do 
the optimization in combine PASS.

So I prefer this patch solution and apply such solution for the future more 
support : sign extend, zero extend, float extend, abs, sqrt, ceil, floor, 
etc.

Thanks. 


juzhe.zh...@rivai.ai
 
From: Robin Dapp
Date: 2023-08-22 15:33
To: juzhe.zhong; Andrew Pinski
CC: rdapp.gcc; Lehua Ding; gcc-patches@gcc.gnu.org; kito.ch...@gmail.com; 
pal...@rivosinc.com; jeffreya...@gmail.com
Subject: Re: [PATCH] RISC-V: Add conditional unary neg/abs/not autovec patterns
> What about conditional zero_extension, sign_extension,
> float_extension, ...etc?
> 
> We have discussed this, we can have some many conditional situations
> that can be supported by either match.pd or rtl backend combine
> pass.
> 
> IMHO, it will be too many optabs/internal fns if we support all of
> them in match.pd? Feel free to correct me I am wrong.
I think the general trend is (and should be) to push things forward
in the pipeline and not just have combine fix it.  However, for now
this would complicate things and therefore I agree with the approach
the patch takes.  I'd rather have the patterns in now rather than change
the middle end for unclear benefit.  
 
IMHO long-term we want things to be optimized early but short-term
combine is good enough.  We can then move optimizations forward on a
case-by-case basis.
 
Regards
Robin
 


Re: [PATCH] RISC-V: Add conditional unary neg/abs/not autovec patterns

2023-08-22 Thread Robin Dapp via Gcc-patches
> What about conditional zero_extension, sign_extension,
> float_extension, ...etc?
> 
> We have discussed this, we can have some many conditional situations
> that can be supported by either match.pd or rtl backend combine
> pass.
> 
> IMHO, it will be too many optabs/internal fns if we support all of
> them in match.pd? Feel free to correct me I am wrong.
I think the general trend is (and should be) to push things forward
in the pipeline and not just have combine fix it.  However, for now
this would complicate things and therefore I agree with the approach
the patch takes.  I'd rather have the patterns in now rather than change
the middle end for unclear benefit.  

IMHO long-term we want things to be optimized early but short-term
combine is good enough.  We can then move optimizations forward on a
case-by-case basis.

Regards
 Robin


Re: [PATCH] RISC-V: Add conditional unary neg/abs/not autovec patterns

2023-08-21 Thread Andrew Pinski via Gcc-patches
On Mon, Aug 21, 2023 at 10:42 PM Lehua Ding  wrote:
>
> Hi,
>
> This patch add conditional unary neg/abs/not autovec patterns to RISC-V 
> backend.
> Consider this C code:
>
> void
> test_3 (float *__restrict a, float *__restrict b, int *__restrict pred, int n)
> {
>   for (int i = 0; i < n; i += 1)
> {
>   a[i] = pred[i] ? __builtin_fabsf (b[i]) : a[i];
> }
> }
>
> Before this patch:
> ...
> vsetvli a7,zero,e32,m1,ta,ma
> vfabs.v v2,v2
> vmerge.vvm  v1,v1,v2,v0
> ...
>
> After this patch:
> ...
> vsetvli a7,zero,e32,m1,ta,mu
> vfabs.v v1,v2,v0.t
> ...
>
> For int neg/abs/not and FP neg patterns, Defining the corresponding cond_xxx
> paterns is enough.

Maybe we should add optabs and IFN support for conditional ABS too.
I added it for conditional not with r14-3257-ga32de58c9e63 to fix up a
regression I had introduced with SVE code.

Thanks,
Andrew

> For the FP abs pattern, We need to change the definition of `abs2` and
> `@vcond_mask_` pattern from define_expand to define_insn_and_split
> in order to fuse them into a new pattern `*cond_abs` at the combine 
> pass.
> After changing the pattern of neg, a vlmax copysin + neg fusion pattern needs
> to be added.
>
> A fusion process similar to the one below:
>
> (insn 30 29 31 4 (set (reg:RVVM1SF 152 [ vect_iftmp.15 ])
> (abs:RVVM1SF (reg:RVVM1SF 137 [ vect__6.14 ]))) "float.c":15:56 
> discrim 1 12799 {absrvvm1sf2}
>  (expr_list:REG_DEAD (reg:RVVM1SF 137 [ vect__6.14 ])
> (nil)))
>
> (insn 31 30 32 4 (set (reg:RVVM1SF 140 [ vect_iftmp.19 ])
> (if_then_else:RVVM1SF (reg:RVVMF32BI 136 [ mask__27.11 ])
> (reg:RVVM1SF 152 [ vect_iftmp.15 ])
> (reg:RVVM1SF 139 [ vect_iftmp.18 ]))) 12707 
> {vcond_mask_rvvm1sfrvvmf32bi}
>  (expr_list:REG_DEAD (reg:RVVM1SF 152 [ vect_iftmp.15 ])
> (expr_list:REG_DEAD (reg:RVVM1SF 139 [ vect_iftmp.18 ])
> (expr_list:REG_DEAD (reg:RVVMF32BI 136 [ mask__27.11 ])
> (nil)
> ==>
>
> (insn 31 30 32 4 (set (reg:RVVM1SF 140 [ vect_iftmp.19 ])
> (if_then_else:RVVM1SF (reg:RVVMF32BI 136 [ mask__27.11 ])
> (abs:RVVM1SF (reg:RVVM1SF 137 [ vect__6.14 ]))
> (reg:RVVM1SF 139 [ vect_iftmp.18 ]))) 13444 {*cond_absrvvm1sf}
>  (expr_list:REG_DEAD (reg:RVVM1SF 137 [ vect__6.14 ])
> (expr_list:REG_DEAD (reg:RVVMF32BI 136 [ mask__27.11 ])
> (expr_list:REG_DEAD (reg:RVVM1SF 139 [ vect_iftmp.18 ])
> (nil)
>
> Best,
> Lehua
>
> gcc/ChangeLog:
>
> * config/riscv/autovec-opt.md (*cond_abs): New combine pattern.
> (*copysign_neg): Ditto.
> * config/riscv/autovec.md (@vcond_mask_): Adjust.
> (2): Ditto.
> (cond_): New.
> (cond_len_): Ditto.
> * config/riscv/riscv-protos.h (enum insn_type): New.
> (expand_cond_len_unop): New helper func.
> * config/riscv/riscv-v.cc (shuffle_merge_patterns): Adjust.
> (expand_cond_len_unop): New helper func.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/riscv/rvv/autovec/cond/cond_unary_1.c: New test.
> * gcc.target/riscv/rvv/autovec/cond/cond_unary_1_run.c: New test.
> * gcc.target/riscv/rvv/autovec/cond/cond_unary_2.c: New test.
> * gcc.target/riscv/rvv/autovec/cond/cond_unary_2_run.c: New test.
> * gcc.target/riscv/rvv/autovec/cond/cond_unary_3.c: New test.
> * gcc.target/riscv/rvv/autovec/cond/cond_unary_3_run.c: New test.
> * gcc.target/riscv/rvv/autovec/cond/cond_unary_4.c: New test.
> * gcc.target/riscv/rvv/autovec/cond/cond_unary_4_run.c: New test.
> * gcc.target/riscv/rvv/autovec/cond/cond_unary_5.c: New test.
> * gcc.target/riscv/rvv/autovec/cond/cond_unary_5_run.c: New test.
> * gcc.target/riscv/rvv/autovec/cond/cond_unary_6.c: New test.
> * gcc.target/riscv/rvv/autovec/cond/cond_unary_6_run.c: New test.
> * gcc.target/riscv/rvv/autovec/cond/cond_unary_7.c: New test.
> * gcc.target/riscv/rvv/autovec/cond/cond_unary_7_run.c: New test.
> * gcc.target/riscv/rvv/autovec/cond/cond_unary_8.c: New test.
> * gcc.target/riscv/rvv/autovec/cond/cond_unary_8_run.c: New test.
>
> ---
>  gcc/config/riscv/autovec-opt.md   | 39 
>  gcc/config/riscv/autovec.md   | 97 +--
>  gcc/config/riscv/riscv-protos.h   |  7 +-
>  gcc/config/riscv/riscv-v.cc   | 56 ++-
>  .../riscv/rvv/autovec/cond/cond_unary_1.c | 43 
>  .../riscv/rvv/autovec/cond/cond_unary_1_run.c | 27 ++
>  .../riscv/rvv/autovec/cond/cond_unary_2.c | 47 +
>  .../riscv/rvv/autovec/cond/cond_unary_2_run.c | 28 ++
>  .../riscv/rvv/autovec/cond/cond_unary_3.c | 43 
>  .../riscv/rvv/autovec/cond/cond_unary_3_run.c | 27 ++
>  .../riscv/rvv/autovec/cond/cond_unary_4.c | 43 
>  .../

[PATCH] RISC-V: Add conditional unary neg/abs/not autovec patterns

2023-08-21 Thread Lehua Ding
Hi,

This patch add conditional unary neg/abs/not autovec patterns to RISC-V backend.
Consider this C code:

void
test_3 (float *__restrict a, float *__restrict b, int *__restrict pred, int n)
{
  for (int i = 0; i < n; i += 1)
{
  a[i] = pred[i] ? __builtin_fabsf (b[i]) : a[i];
}
}

Before this patch:
...
vsetvli a7,zero,e32,m1,ta,ma
vfabs.v v2,v2
vmerge.vvm  v1,v1,v2,v0
...

After this patch:
...
vsetvli a7,zero,e32,m1,ta,mu
vfabs.v v1,v2,v0.t
...

For int neg/abs/not and FP neg patterns, Defining the corresponding cond_xxx
paterns is enough.
For the FP abs pattern, We need to change the definition of `abs2` and
`@vcond_mask_` pattern from define_expand to define_insn_and_split
in order to fuse them into a new pattern `*cond_abs` at the combine pass.
After changing the pattern of neg, a vlmax copysin + neg fusion pattern needs
to be added.

A fusion process similar to the one below:

(insn 30 29 31 4 (set (reg:RVVM1SF 152 [ vect_iftmp.15 ])
(abs:RVVM1SF (reg:RVVM1SF 137 [ vect__6.14 ]))) "float.c":15:56 discrim 
1 12799 {absrvvm1sf2}
 (expr_list:REG_DEAD (reg:RVVM1SF 137 [ vect__6.14 ])
(nil)))

(insn 31 30 32 4 (set (reg:RVVM1SF 140 [ vect_iftmp.19 ])
(if_then_else:RVVM1SF (reg:RVVMF32BI 136 [ mask__27.11 ])
(reg:RVVM1SF 152 [ vect_iftmp.15 ])
(reg:RVVM1SF 139 [ vect_iftmp.18 ]))) 12707 
{vcond_mask_rvvm1sfrvvmf32bi}
 (expr_list:REG_DEAD (reg:RVVM1SF 152 [ vect_iftmp.15 ])
(expr_list:REG_DEAD (reg:RVVM1SF 139 [ vect_iftmp.18 ])
(expr_list:REG_DEAD (reg:RVVMF32BI 136 [ mask__27.11 ])
(nil)
==>

(insn 31 30 32 4 (set (reg:RVVM1SF 140 [ vect_iftmp.19 ])
(if_then_else:RVVM1SF (reg:RVVMF32BI 136 [ mask__27.11 ])
(abs:RVVM1SF (reg:RVVM1SF 137 [ vect__6.14 ]))
(reg:RVVM1SF 139 [ vect_iftmp.18 ]))) 13444 {*cond_absrvvm1sf}
 (expr_list:REG_DEAD (reg:RVVM1SF 137 [ vect__6.14 ])
(expr_list:REG_DEAD (reg:RVVMF32BI 136 [ mask__27.11 ])
(expr_list:REG_DEAD (reg:RVVM1SF 139 [ vect_iftmp.18 ])
(nil)

Best,
Lehua

gcc/ChangeLog:

* config/riscv/autovec-opt.md (*cond_abs): New combine pattern.
(*copysign_neg): Ditto.
* config/riscv/autovec.md (@vcond_mask_): Adjust.
(2): Ditto.
(cond_): New.
(cond_len_): Ditto.
* config/riscv/riscv-protos.h (enum insn_type): New.
(expand_cond_len_unop): New helper func.
* config/riscv/riscv-v.cc (shuffle_merge_patterns): Adjust.
(expand_cond_len_unop): New helper func.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/cond/cond_unary_1.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_unary_1_run.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_unary_2.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_unary_2_run.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_unary_3.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_unary_3_run.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_unary_4.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_unary_4_run.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_unary_5.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_unary_5_run.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_unary_6.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_unary_6_run.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_unary_7.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_unary_7_run.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_unary_8.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_unary_8_run.c: New test.

---
 gcc/config/riscv/autovec-opt.md   | 39 
 gcc/config/riscv/autovec.md   | 97 +--
 gcc/config/riscv/riscv-protos.h   |  7 +-
 gcc/config/riscv/riscv-v.cc   | 56 ++-
 .../riscv/rvv/autovec/cond/cond_unary_1.c | 43 
 .../riscv/rvv/autovec/cond/cond_unary_1_run.c | 27 ++
 .../riscv/rvv/autovec/cond/cond_unary_2.c | 47 +
 .../riscv/rvv/autovec/cond/cond_unary_2_run.c | 28 ++
 .../riscv/rvv/autovec/cond/cond_unary_3.c | 43 
 .../riscv/rvv/autovec/cond/cond_unary_3_run.c | 27 ++
 .../riscv/rvv/autovec/cond/cond_unary_4.c | 43 
 .../riscv/rvv/autovec/cond/cond_unary_4_run.c | 27 ++
 .../riscv/rvv/autovec/cond/cond_unary_5.c | 37 +++
 .../riscv/rvv/autovec/cond/cond_unary_5_run.c | 26 +
 .../riscv/rvv/autovec/cond/cond_unary_6.c | 41 
 .../riscv/rvv/autovec/cond/cond_unary_6_run.c | 27 ++
 .../riscv/rvv/autovec/cond/cond_unary_7.c | 37 +++
 .../riscv/rvv/autovec/cond/cond_unary_7_run.c | 26 +
 .../riscv/rvv/autovec/cond/cond_unary_8.c | 37 +