RISC-V: Add runtime invariant support

Message ID 20220817071950.271762-1-juzhe.zhong@rivai.ai
State Deferred, archived
Headers
Series RISC-V: Add runtime invariant support |

Commit Message

juzhe.zhong@rivai.ai Aug. 17, 2022, 7:19 a.m. UTC
  From: zhongjuzhe <juzhe.zhong@rivai.ai>

RISC-V 'V' Extension support scalable vector like ARM SVE.
To support RVV, we need to introduce runtime invariant.

- For zve32*, the runtime invariant uses 32-bit chunk.
- For zve64*, the runtime invariant uses 64-bit chunk.

[1] https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#sec-vector-extensions

This patch is preparing patch for RVV support. 
Because we didn't introduce vector machine_mode yet, it safe to just change HOST_WIDE_INT into poly_int.
Also it safe to use "to_constant()" function for scalar operation.
This patch has been tested by full dejagnu regression.

gcc/ChangeLog:

        * config/riscv/predicates.md: Adjust runtime invariant.
        * config/riscv/riscv-modes.def (MAX_BITSIZE_MODE_ANY_MODE): New.
        (NUM_POLY_INT_COEFFS): New.
        * config/riscv/riscv-protos.h (riscv_initial_elimination_offset): Adjust runtime invariant.
        * config/riscv/riscv-sr.cc (riscv_remove_unneeded_save_restore_calls): Adjust runtime invariant.
        * config/riscv/riscv.cc (struct riscv_frame_info): Adjust runtime invariant.
        (enum riscv_microarchitecture_type): Ditto.
        (riscv_valid_offset_p): Ditto.
        (riscv_valid_lo_sum_p): Ditto.
        (riscv_address_insns): Ditto.
        (riscv_load_store_insns): Ditto.
        (riscv_legitimize_move): Ditto.
        (riscv_binary_cost): Ditto.
        (riscv_rtx_costs): Ditto.
        (riscv_output_move): Ditto.
        (riscv_extend_comparands): Ditto.
        (riscv_flatten_aggregate_field): Ditto.
        (riscv_get_arg_info): Ditto.
        (riscv_pass_by_reference): Ditto.
        (riscv_elf_select_rtx_section): Ditto.
        (riscv_stack_align): Ditto.
        (riscv_compute_frame_info): Ditto.
        (riscv_initial_elimination_offset): Ditto.
        (riscv_set_return_address): Ditto.
        (riscv_for_each_saved_reg): Ditto.
        (riscv_first_stack_step): Ditto.
        (riscv_expand_prologue): Ditto.
        (riscv_expand_epilogue): Ditto.
        (riscv_can_use_return_insn): Ditto.
        (riscv_secondary_memory_needed): Ditto.
        (riscv_hard_regno_nregs): Ditto.
        (riscv_convert_vector_bits): New.
        (riscv_option_override): Adjust runtime invariant.
        (riscv_promote_function_mode): Ditto.
        * config/riscv/riscv.h (POLY_SMALL_OPERAND_P): New.
        (BITS_PER_RISCV_VECTOR): New.
        (BYTES_PER_RISCV_VECTOR): New.
        * config/riscv/riscv.md: Adjust runtime invariant.

---
 gcc/config/riscv/predicates.md   |   2 +-
 gcc/config/riscv/riscv-modes.def |  12 ++
 gcc/config/riscv/riscv-protos.h  |   2 +-
 gcc/config/riscv/riscv-sr.cc     |   2 +-
 gcc/config/riscv/riscv.cc        | 181 ++++++++++++++++++++-----------
 gcc/config/riscv/riscv.h         |   9 ++
 gcc/config/riscv/riscv.md        |   2 +-
 7 files changed, 142 insertions(+), 68 deletions(-)
  

Comments

Andreas Schwab Aug. 20, 2022, 10:33 p.m. UTC | #1
This breaks bootstrap:

../../gcc/tree-vect-loop-manip.cc: In function 'void vect_gen_vector_loop_niters(loop_vec_info, tree, tree_node**, tree_node**, bool)':
../../gcc/tree-vect-loop-manip.cc:1981:26: error: 'const_vf' may be used uninitialized [-Werror=maybe-uninitialized]
 1981 |   unsigned HOST_WIDE_INT const_vf;
      |                          ^~~~~~~~
cc1plus: all warnings being treated as errors
make[3]: *** [Makefile:1146: tree-vect-loop-manip.o] Error 1
make[2]: *** [Makefile:4977: all-stage2-gcc] Error 2
make[1]: *** [Makefile:30363: stage2-bubble] Error 2
make: *** [Makefile:1065: all] Error 2
  
Andrew Pinski Aug. 20, 2022, 11:53 p.m. UTC | #2
On Sat, Aug 20, 2022 at 3:34 PM Andreas Schwab <schwab@linux-m68k.org> wrote:
>
> This breaks bootstrap:
>
> ../../gcc/tree-vect-loop-manip.cc: In function 'void vect_gen_vector_loop_niters(loop_vec_info, tree, tree_node**, tree_node**, bool)':
> ../../gcc/tree-vect-loop-manip.cc:1981:26: error: 'const_vf' may be used uninitialized [-Werror=maybe-uninitialized]
>  1981 |   unsigned HOST_WIDE_INT const_vf;
>       |                          ^~~~~~~~
> cc1plus: all warnings being treated as errors
> make[3]: *** [Makefile:1146: tree-vect-loop-manip.o] Error 1
> make[2]: *** [Makefile:4977: all-stage2-gcc] Error 2
> make[1]: *** [Makefile:30363: stage2-bubble] Error 2
> make: *** [Makefile:1065: all] Error 2


This looks like a real uninitialized variable issue.
I even can't tell if the paths that lead to using const_vf will be
always set so how we expect GCC to do the same.
The code that uses const_vf was added with r11-5820-cdcbef3c3310,
CCing the author there.

Thanks,
Andrew

>
> --
> Andreas Schwab, schwab@linux-m68k.org
> GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
> "And now for something completely different."
  
juzhe.zhong@rivai.ai Aug. 21, 2022, 12:05 a.m. UTC | #3
Hi, it seems that this warning still report if I revert my patch. Am I right? Feel free to correct me. Maybe I need to try it again?



juzhe.zhong@rivai.ai
 
From: Andrew Pinski
Date: 2022-08-21 07:53
To: Andreas Schwab
CC: juzhe.zhong; gcc-patches; kito.cheng; andrew; Richard Guenther
Subject: Re: [PATCH] RISC-V: Add runtime invariant support
On Sat, Aug 20, 2022 at 3:34 PM Andreas Schwab <schwab@linux-m68k.org> wrote:
>
> This breaks bootstrap:
>
> ../../gcc/tree-vect-loop-manip.cc: In function 'void vect_gen_vector_loop_niters(loop_vec_info, tree, tree_node**, tree_node**, bool)':
> ../../gcc/tree-vect-loop-manip.cc:1981:26: error: 'const_vf' may be used uninitialized [-Werror=maybe-uninitialized]
>  1981 |   unsigned HOST_WIDE_INT const_vf;
>       |                          ^~~~~~~~
> cc1plus: all warnings being treated as errors
> make[3]: *** [Makefile:1146: tree-vect-loop-manip.o] Error 1
> make[2]: *** [Makefile:4977: all-stage2-gcc] Error 2
> make[1]: *** [Makefile:30363: stage2-bubble] Error 2
> make: *** [Makefile:1065: all] Error 2
 
 
This looks like a real uninitialized variable issue.
I even can't tell if the paths that lead to using const_vf will be
always set so how we expect GCC to do the same.
The code that uses const_vf was added with r11-5820-cdcbef3c3310,
CCing the author there.
 
Thanks,
Andrew
 
>
> --
> Andreas Schwab, schwab@linux-m68k.org
> GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
> "And now for something completely different."
  
Andrew Pinski Aug. 21, 2022, 12:18 a.m. UTC | #4
On Sat, Aug 20, 2022 at 5:06 PM 钟居哲 <juzhe.zhong@rivai.ai> wrote:
>
> Hi, it seems that this warning still report if I revert my patch. Am I right? Feel free to correct me. Maybe I need to try it again?

The warning will not be still there. The reason is NUM_POLY_INT_COEFFS
defaults to 1 which means vf.is_constant (&const_vf) will always
return true and will always set const_vf.
I don't know why the warning does not happen on aarch64-linux-gnu (the
other target where NUM_POLY_INT_COEFFS is set to 2) though; it just
might be slightly different IR which causes the warning mechanism not
to warn.

Thanks,
Andrew Pinski


>
> ________________________________
> juzhe.zhong@rivai.ai
>
>
> From: Andrew Pinski
> Date: 2022-08-21 07:53
> To: Andreas Schwab
> CC: juzhe.zhong; gcc-patches; kito.cheng; andrew; Richard Guenther
> Subject: Re: [PATCH] RISC-V: Add runtime invariant support
> On Sat, Aug 20, 2022 at 3:34 PM Andreas Schwab <schwab@linux-m68k.org> wrote:
> >
> > This breaks bootstrap:
> >
> > ../../gcc/tree-vect-loop-manip.cc: In function 'void vect_gen_vector_loop_niters(loop_vec_info, tree, tree_node**, tree_node**, bool)':
> > ../../gcc/tree-vect-loop-manip.cc:1981:26: error: 'const_vf' may be used uninitialized [-Werror=maybe-uninitialized]
> >  1981 |   unsigned HOST_WIDE_INT const_vf;
> >       |                          ^~~~~~~~
> > cc1plus: all warnings being treated as errors
> > make[3]: *** [Makefile:1146: tree-vect-loop-manip.o] Error 1
> > make[2]: *** [Makefile:4977: all-stage2-gcc] Error 2
> > make[1]: *** [Makefile:30363: stage2-bubble] Error 2
> > make: *** [Makefile:1065: all] Error 2
>
>
> This looks like a real uninitialized variable issue.
> I even can't tell if the paths that lead to using const_vf will be
> always set so how we expect GCC to do the same.
> The code that uses const_vf was added with r11-5820-cdcbef3c3310,
> CCing the author there.
>
> Thanks,
> Andrew
>
> >
> > --
> > Andreas Schwab, schwab@linux-m68k.org
> > GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
> > "And now for something completely different."
>
  
juzhe.zhong@rivai.ai Aug. 21, 2022, 12:28 a.m. UTC | #5
OK. Thank you. I am gonna try it again and fix this in RISC-V port.



juzhe.zhong@rivai.ai
 
From: Andrew Pinski
Date: 2022-08-21 08:18
To: 钟居哲
CC: Andreas Schwab; gcc-patches; kito.cheng; andrew; rguenther
Subject: Re: Re: [PATCH] RISC-V: Add runtime invariant support
On Sat, Aug 20, 2022 at 5:06 PM 钟居哲 <juzhe.zhong@rivai.ai> wrote:
>
> Hi, it seems that this warning still report if I revert my patch. Am I right? Feel free to correct me. Maybe I need to try it again?
 
The warning will not be still there. The reason is NUM_POLY_INT_COEFFS
defaults to 1 which means vf.is_constant (&const_vf) will always
return true and will always set const_vf.
I don't know why the warning does not happen on aarch64-linux-gnu (the
other target where NUM_POLY_INT_COEFFS is set to 2) though; it just
might be slightly different IR which causes the warning mechanism not
to warn.
 
Thanks,
Andrew Pinski
 
 
>
> ________________________________
> juzhe.zhong@rivai.ai
>
>
> From: Andrew Pinski
> Date: 2022-08-21 07:53
> To: Andreas Schwab
> CC: juzhe.zhong; gcc-patches; kito.cheng; andrew; Richard Guenther
> Subject: Re: [PATCH] RISC-V: Add runtime invariant support
> On Sat, Aug 20, 2022 at 3:34 PM Andreas Schwab <schwab@linux-m68k.org> wrote:
> >
> > This breaks bootstrap:
> >
> > ../../gcc/tree-vect-loop-manip.cc: In function 'void vect_gen_vector_loop_niters(loop_vec_info, tree, tree_node**, tree_node**, bool)':
> > ../../gcc/tree-vect-loop-manip.cc:1981:26: error: 'const_vf' may be used uninitialized [-Werror=maybe-uninitialized]
> >  1981 |   unsigned HOST_WIDE_INT const_vf;
> >       |                          ^~~~~~~~
> > cc1plus: all warnings being treated as errors
> > make[3]: *** [Makefile:1146: tree-vect-loop-manip.o] Error 1
> > make[2]: *** [Makefile:4977: all-stage2-gcc] Error 2
> > make[1]: *** [Makefile:30363: stage2-bubble] Error 2
> > make: *** [Makefile:1065: all] Error 2
>
>
> This looks like a real uninitialized variable issue.
> I even can't tell if the paths that lead to using const_vf will be
> always set so how we expect GCC to do the same.
> The code that uses const_vf was added with r11-5820-cdcbef3c3310,
> CCing the author there.
>
> Thanks,
> Andrew
>
> >
> > --
> > Andreas Schwab, schwab@linux-m68k.org
> > GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
> > "And now for something completely different."
>
  
Andrew Pinski Aug. 21, 2022, 3:52 a.m. UTC | #6
On Sat, Aug 20, 2022 at 5:29 PM 钟居哲 <juzhe.zhong@rivai.ai> wrote:
>
> OK. Thank you. I am gonna try it again and fix this in RISC-V port.

The fix is not in the RISC-V port, the fix needs to happen in
vect_gen_vector_loop_niters (tree-vect-loop-manip.cc).
I described why the code is broken, the second use of const_vf is not
connected at all to vf.is_constant (&const_vf) so it will be
uninitilized there.

Thanks,
Andrew

>
> ________________________________
> juzhe.zhong@rivai.ai
>
>
> From: Andrew Pinski
> Date: 2022-08-21 08:18
> To: 钟居哲
> CC: Andreas Schwab; gcc-patches; kito.cheng; andrew; rguenther
> Subject: Re: Re: [PATCH] RISC-V: Add runtime invariant support
> On Sat, Aug 20, 2022 at 5:06 PM 钟居哲 <juzhe.zhong@rivai.ai> wrote:
> >
> > Hi, it seems that this warning still report if I revert my patch. Am I right? Feel free to correct me. Maybe I need to try it again?
>
> The warning will not be still there. The reason is NUM_POLY_INT_COEFFS
> defaults to 1 which means vf.is_constant (&const_vf) will always
> return true and will always set const_vf.
> I don't know why the warning does not happen on aarch64-linux-gnu (the
> other target where NUM_POLY_INT_COEFFS is set to 2) though; it just
> might be slightly different IR which causes the warning mechanism not
> to warn.
>
> Thanks,
> Andrew Pinski
>
>
> >
> > ________________________________
> > juzhe.zhong@rivai.ai
> >
> >
> > From: Andrew Pinski
> > Date: 2022-08-21 07:53
> > To: Andreas Schwab
> > CC: juzhe.zhong; gcc-patches; kito.cheng; andrew; Richard Guenther
> > Subject: Re: [PATCH] RISC-V: Add runtime invariant support
> > On Sat, Aug 20, 2022 at 3:34 PM Andreas Schwab <schwab@linux-m68k.org> wrote:
> > >
> > > This breaks bootstrap:
> > >
> > > ../../gcc/tree-vect-loop-manip.cc: In function 'void vect_gen_vector_loop_niters(loop_vec_info, tree, tree_node**, tree_node**, bool)':
> > > ../../gcc/tree-vect-loop-manip.cc:1981:26: error: 'const_vf' may be used uninitialized [-Werror=maybe-uninitialized]
> > >  1981 |   unsigned HOST_WIDE_INT const_vf;
> > >       |                          ^~~~~~~~
> > > cc1plus: all warnings being treated as errors
> > > make[3]: *** [Makefile:1146: tree-vect-loop-manip.o] Error 1
> > > make[2]: *** [Makefile:4977: all-stage2-gcc] Error 2
> > > make[1]: *** [Makefile:30363: stage2-bubble] Error 2
> > > make: *** [Makefile:1065: all] Error 2
> >
> >
> > This looks like a real uninitialized variable issue.
> > I even can't tell if the paths that lead to using const_vf will be
> > always set so how we expect GCC to do the same.
> > The code that uses const_vf was added with r11-5820-cdcbef3c3310,
> > CCing the author there.
> >
> > Thanks,
> > Andrew
> >
> > >
> > > --
> > > Andreas Schwab, schwab@linux-m68k.org
> > > GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
> > > "And now for something completely different."
> >
>
  
Richard Biener Aug. 22, 2022, 6:14 a.m. UTC | #7
On Sat, 20 Aug 2022, Andrew Pinski wrote:

> On Sat, Aug 20, 2022 at 3:34 PM Andreas Schwab <schwab@linux-m68k.org> wrote:
> >
> > This breaks bootstrap:
> >
> > ../../gcc/tree-vect-loop-manip.cc: In function 'void vect_gen_vector_loop_niters(loop_vec_info, tree, tree_node**, tree_node**, bool)':
> > ../../gcc/tree-vect-loop-manip.cc:1981:26: error: 'const_vf' may be used uninitialized [-Werror=maybe-uninitialized]
> >  1981 |   unsigned HOST_WIDE_INT const_vf;
> >       |                          ^~~~~~~~
> > cc1plus: all warnings being treated as errors
> > make[3]: *** [Makefile:1146: tree-vect-loop-manip.o] Error 1
> > make[2]: *** [Makefile:4977: all-stage2-gcc] Error 2
> > make[1]: *** [Makefile:30363: stage2-bubble] Error 2
> > make: *** [Makefile:1065: all] Error 2
> 
> 
> This looks like a real uninitialized variable issue.
> I even can't tell if the paths that lead to using const_vf will be
> always set so how we expect GCC to do the same.
> The code that uses const_vf was added with r11-5820-cdcbef3c3310,
> CCing the author there.

The key is

  tree log_vf = NULL_TREE;
...
  unsigned HOST_WIDE_INT const_vf;
  if (vf.is_constant (&const_vf)
      && !LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo))
    {
...
      log_vf = build_int_cst (type, exact_log2 (const_vf));
...
    }
...
      if (stmts != NULL && log_vf)
        {
... use const_vf ...

so it's uninit analysis little mind that is confused.  There is code
that's supposed to handle the situation (setting flag under condition,
testing that flag instead of condition) but maybe it's too twisted
here.  One could refector this as

 bool const_vf_p = vf.is_constant (&const_vf);
 if (const_vf_p
     && ...)
...
   if (stmts != NULL && const_vf_p)
...

and hope uninits mind is good enough to see log_vf is not used
uninitialized.

I can also look into why uninit doesn't get it, but preprocessed
source would be handy then.

Richard.
  
Richard Biener Aug. 23, 2022, 9:34 a.m. UTC | #8
On Mon, Aug 22, 2022 at 8:15 AM Richard Biener via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> On Sat, 20 Aug 2022, Andrew Pinski wrote:
>
> > On Sat, Aug 20, 2022 at 3:34 PM Andreas Schwab <schwab@linux-m68k.org> wrote:
> > >
> > > This breaks bootstrap:
> > >
> > > ../../gcc/tree-vect-loop-manip.cc: In function 'void vect_gen_vector_loop_niters(loop_vec_info, tree, tree_node**, tree_node**, bool)':
> > > ../../gcc/tree-vect-loop-manip.cc:1981:26: error: 'const_vf' may be used uninitialized [-Werror=maybe-uninitialized]
> > >  1981 |   unsigned HOST_WIDE_INT const_vf;
> > >       |                          ^~~~~~~~
> > > cc1plus: all warnings being treated as errors
> > > make[3]: *** [Makefile:1146: tree-vect-loop-manip.o] Error 1
> > > make[2]: *** [Makefile:4977: all-stage2-gcc] Error 2
> > > make[1]: *** [Makefile:30363: stage2-bubble] Error 2
> > > make: *** [Makefile:1065: all] Error 2
> >
> >
> > This looks like a real uninitialized variable issue.
> > I even can't tell if the paths that lead to using const_vf will be
> > always set so how we expect GCC to do the same.
> > The code that uses const_vf was added with r11-5820-cdcbef3c3310,
> > CCing the author there.
>
> The key is
>
>   tree log_vf = NULL_TREE;
> ...
>   unsigned HOST_WIDE_INT const_vf;
>   if (vf.is_constant (&const_vf)
>       && !LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo))
>     {
> ...
>       log_vf = build_int_cst (type, exact_log2 (const_vf));
> ...
>     }
> ...
>       if (stmts != NULL && log_vf)
>         {
> ... use const_vf ...
>
> so it's uninit analysis little mind that is confused.  There is code
> that's supposed to handle the situation (setting flag under condition,
> testing that flag instead of condition) but maybe it's too twisted
> here.  One could refector this as
>
>  bool const_vf_p = vf.is_constant (&const_vf);
>  if (const_vf_p
>      && ...)
> ...
>    if (stmts != NULL && const_vf_p)
> ...
>
> and hope uninits mind is good enough to see log_vf is not used
> uninitialized.
>
> I can also look into why uninit doesn't get it, but preprocessed
> source would be handy then.

Btw, the riscv speciality is

gcc/config/riscv/riscv.h:#define LOGICAL_OP_NON_SHORT_CIRCUIT 0

with --param logical-op-non-short-circuit=1 the diagnostic does not occur.

>
> Richard.
  
juzhe.zhong@rivai.ai Aug. 24, 2022, 1:02 a.m. UTC | #9
I tried #define LOGICAL_OP_NON_SHORT_CIRCUIT 1 in RISC-V port. The warning is still there.
Are you considering this patch:https://gcc.gnu.org/pipermail/gcc-patches/2022-August/600120.html 
to solve this issue ? Or you are trying another solution to fix this ?



juzhe.zhong@rivai.ai
 
From: Richard Biener
Date: 2022-08-23 17:34
To: Richard Biener
CC: Andrew Pinski; GCC Patches; Andrew Waterman; Andreas Schwab; Kito Cheng; juzhe.zhong
Subject: Re: [PATCH] RISC-V: Add runtime invariant support
On Mon, Aug 22, 2022 at 8:15 AM Richard Biener via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> On Sat, 20 Aug 2022, Andrew Pinski wrote:
>
> > On Sat, Aug 20, 2022 at 3:34 PM Andreas Schwab <schwab@linux-m68k.org> wrote:
> > >
> > > This breaks bootstrap:
> > >
> > > ../../gcc/tree-vect-loop-manip.cc: In function 'void vect_gen_vector_loop_niters(loop_vec_info, tree, tree_node**, tree_node**, bool)':
> > > ../../gcc/tree-vect-loop-manip.cc:1981:26: error: 'const_vf' may be used uninitialized [-Werror=maybe-uninitialized]
> > >  1981 |   unsigned HOST_WIDE_INT const_vf;
> > >       |                          ^~~~~~~~
> > > cc1plus: all warnings being treated as errors
> > > make[3]: *** [Makefile:1146: tree-vect-loop-manip.o] Error 1
> > > make[2]: *** [Makefile:4977: all-stage2-gcc] Error 2
> > > make[1]: *** [Makefile:30363: stage2-bubble] Error 2
> > > make: *** [Makefile:1065: all] Error 2
> >
> >
> > This looks like a real uninitialized variable issue.
> > I even can't tell if the paths that lead to using const_vf will be
> > always set so how we expect GCC to do the same.
> > The code that uses const_vf was added with r11-5820-cdcbef3c3310,
> > CCing the author there.
>
> The key is
>
>   tree log_vf = NULL_TREE;
> ...
>   unsigned HOST_WIDE_INT const_vf;
>   if (vf.is_constant (&const_vf)
>       && !LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo))
>     {
> ...
>       log_vf = build_int_cst (type, exact_log2 (const_vf));
> ...
>     }
> ...
>       if (stmts != NULL && log_vf)
>         {
> ... use const_vf ...
>
> so it's uninit analysis little mind that is confused.  There is code
> that's supposed to handle the situation (setting flag under condition,
> testing that flag instead of condition) but maybe it's too twisted
> here.  One could refector this as
>
>  bool const_vf_p = vf.is_constant (&const_vf);
>  if (const_vf_p
>      && ...)
> ...
>    if (stmts != NULL && const_vf_p)
> ...
>
> and hope uninits mind is good enough to see log_vf is not used
> uninitialized.
>
> I can also look into why uninit doesn't get it, but preprocessed
> source would be handy then.
 
Btw, the riscv speciality is
 
gcc/config/riscv/riscv.h:#define LOGICAL_OP_NON_SHORT_CIRCUIT 0
 
with --param logical-op-non-short-circuit=1 the diagnostic does not occur.
 
>
> Richard.
  

Patch

diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
index e98db2cb574..79e0c1d5589 100644
--- a/gcc/config/riscv/predicates.md
+++ b/gcc/config/riscv/predicates.md
@@ -71,7 +71,7 @@ 
 {
   /* Don't handle multi-word moves this way; we don't want to introduce
      the individual word-mode moves until after reload.  */
-  if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
+  if (GET_MODE_SIZE (mode).to_constant () > UNITS_PER_WORD)
     return false;
 
   /* Check whether the constant can be loaded in a single
diff --git a/gcc/config/riscv/riscv-modes.def b/gcc/config/riscv/riscv-modes.def
index 5cf2fc8e9e6..b47909ef78b 100644
--- a/gcc/config/riscv/riscv-modes.def
+++ b/gcc/config/riscv/riscv-modes.def
@@ -21,3 +21,15 @@  along with GCC; see the file COPYING3.  If not see
 
 FLOAT_MODE (HF, 2, ieee_half_format);
 FLOAT_MODE (TF, 16, ieee_quad_format);
+
+/* TODO:According to RISC-V 'V' ISA spec, the maximun vector length can
+   be 65536 for a single vector register which means the vector mode in
+   GCC can be maximum = 65536 * 8 bits (LMUL=8). However, 'GET_MODE_SIZE'
+   is using poly_uint16/unsigned short which will overflow if we specify
+   vector-length = 65536. To support this feature, we need to change the
+   codes outside the RISC-V port. We will support it in the future.  */
+#define MAX_BITSIZE_MODE_ANY_MODE (4096 * 8)
+
+/* Coefficient 1 is multiplied by the number of 64-bit/32-bit chunks in a vector
+ * minus one.  */
+#define NUM_POLY_INT_COEFFS 2
\ No newline at end of file
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 20c2381c21a..2bc0ef06f93 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -64,7 +64,7 @@  extern rtx riscv_legitimize_call_address (rtx);
 extern void riscv_set_return_address (rtx, rtx);
 extern bool riscv_expand_block_move (rtx, rtx, rtx);
 extern rtx riscv_return_addr (int, rtx);
-extern HOST_WIDE_INT riscv_initial_elimination_offset (int, int);
+extern poly_int64 riscv_initial_elimination_offset (int, int);
 extern void riscv_expand_prologue (void);
 extern void riscv_expand_epilogue (int);
 extern bool riscv_epilogue_uses (unsigned int);
diff --git a/gcc/config/riscv/riscv-sr.cc b/gcc/config/riscv/riscv-sr.cc
index 694f90c1583..7248f04d68f 100644
--- a/gcc/config/riscv/riscv-sr.cc
+++ b/gcc/config/riscv/riscv-sr.cc
@@ -247,7 +247,7 @@  riscv_remove_unneeded_save_restore_calls (void)
   /* We'll adjust stack size after this optimization, that require update every
      sp use site, which could be unsafe, so we decide to turn off this
      optimization if there are any arguments put on stack.  */
-  if (crtl->args.size != 0)
+  if (known_ne (crtl->args.size, 0))
     return;
 
   /* Will point to the first instruction of the function body, after the
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 9d70974c893..5ae3e7fe857 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -100,7 +100,7 @@  enum riscv_address_type {
 /* Information about a function's frame layout.  */
 struct GTY(())  riscv_frame_info {
   /* The size of the frame in bytes.  */
-  HOST_WIDE_INT total_size;
+  poly_int64 total_size;
 
   /* Bit X is set if the function saves or restores GPR X.  */
   unsigned int mask;
@@ -112,17 +112,17 @@  struct GTY(())  riscv_frame_info {
   unsigned save_libcall_adjustment;
 
   /* Offsets of fixed-point and floating-point save areas from frame bottom */
-  HOST_WIDE_INT gp_sp_offset;
-  HOST_WIDE_INT fp_sp_offset;
+  poly_int64 gp_sp_offset;
+  poly_int64 fp_sp_offset;
 
   /* Offset of virtual frame pointer from stack pointer/frame bottom */
-  HOST_WIDE_INT frame_pointer_offset;
+  poly_int64 frame_pointer_offset;
 
   /* Offset of hard frame pointer from stack pointer/frame bottom */
-  HOST_WIDE_INT hard_frame_pointer_offset;
+  poly_int64 hard_frame_pointer_offset;
 
   /* The offset of arg_pointer_rtx from the bottom of the frame.  */
-  HOST_WIDE_INT arg_pointer_offset;
+  poly_int64 arg_pointer_offset;
 };
 
 enum riscv_privilege_levels {
@@ -255,6 +255,12 @@  static const struct riscv_tune_param *tune_param;
 /* Which automaton to use for tuning.  */
 enum riscv_microarchitecture_type riscv_microarchitecture;
 
+/* The number of chunks in a single vector register.  */
+poly_uint16 riscv_vector_chunks;
+
+/* The number of bytes in a vector chunk.  */
+unsigned riscv_bytes_per_vector_chunk;
+
 /* Index R is the smallest register class that contains register R.  */
 const enum reg_class riscv_regno_to_class[FIRST_PSEUDO_REGISTER] = {
   GR_REGS,	GR_REGS,	GR_REGS,	GR_REGS,
@@ -807,8 +813,8 @@  riscv_valid_offset_p (rtx x, machine_mode mode)
 
   /* We may need to split multiword moves, so make sure that every word
      is accessible.  */
-  if (GET_MODE_SIZE (mode) > UNITS_PER_WORD
-      && !SMALL_OPERAND (INTVAL (x) + GET_MODE_SIZE (mode) - UNITS_PER_WORD))
+  if (GET_MODE_SIZE (mode).to_constant () > UNITS_PER_WORD
+      && !SMALL_OPERAND (INTVAL (x) + GET_MODE_SIZE (mode).to_constant () - UNITS_PER_WORD))
     return false;
 
   return true;
@@ -872,7 +878,7 @@  riscv_valid_lo_sum_p (enum riscv_symbol_type sym_type, machine_mode mode,
   else
     {
       align = GET_MODE_ALIGNMENT (mode);
-      size = GET_MODE_BITSIZE (mode);
+      size = GET_MODE_BITSIZE (mode).to_constant ();
     }
 
   /* We may need to split multiword moves, so make sure that each word
@@ -1013,7 +1019,7 @@  riscv_address_insns (rtx x, machine_mode mode, bool might_split_p)
   /* BLKmode is used for single unaligned loads and stores and should
      not count as a multiword mode. */
   if (mode != BLKmode && might_split_p)
-    n += (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+    n += (GET_MODE_SIZE (mode).to_constant () + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
 
   if (addr.type == ADDRESS_LO_SUM)
     n += riscv_symbol_insns (addr.symbol_type) - 1;
@@ -1106,9 +1112,9 @@  riscv_load_store_insns (rtx mem, rtx_insn *insn)
 
   /* Try to prove that INSN does not need to be split.  */
   might_split_p = true;
-  if (GET_MODE_BITSIZE (mode) <= 32)
+  if (GET_MODE_BITSIZE (mode).to_constant () <= 32)
     might_split_p = false;
-  else if (GET_MODE_BITSIZE (mode) == 64)
+  else if (GET_MODE_BITSIZE (mode).to_constant () == 64)
     {
       set = single_set (insn);
       if (set && !riscv_split_64bit_move_p (SET_DEST (set), SET_SRC (set)))
@@ -1625,7 +1631,7 @@  riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
        (set (reg:QI target) (subreg:QI (reg:DI temp) 0))
      with auto-sign/zero extend.  */
   if (GET_MODE_CLASS (mode) == MODE_INT
-      && GET_MODE_SIZE (mode) < UNITS_PER_WORD
+      && GET_MODE_SIZE (mode).to_constant () < UNITS_PER_WORD
       && can_create_pseudo_p ()
       && MEM_P (src))
     {
@@ -1650,7 +1656,7 @@  riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
 	     improve cse.  */
 	  machine_mode promoted_mode = mode;
 	  if (GET_MODE_CLASS (mode) == MODE_INT
-	      && GET_MODE_SIZE (mode) < UNITS_PER_WORD)
+	      && GET_MODE_SIZE (mode).to_constant () < UNITS_PER_WORD)
 	    promoted_mode = word_mode;
 
 	  if (splittable_const_int_operand (src, mode))
@@ -1748,7 +1754,7 @@  riscv_immediate_operand_p (int code, HOST_WIDE_INT x)
 static int
 riscv_binary_cost (rtx x, int single_insns, int double_insns)
 {
-  if (GET_MODE_SIZE (GET_MODE (x)) == UNITS_PER_WORD * 2)
+  if (GET_MODE_SIZE (GET_MODE (x)).to_constant () == UNITS_PER_WORD * 2)
     return COSTS_N_INSNS (double_insns);
   return COSTS_N_INSNS (single_insns);
 }
@@ -1881,7 +1887,7 @@  riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
       return false;
 
     case NOT:
-      *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) > UNITS_PER_WORD ? 2 : 1);
+      *total = COSTS_N_INSNS (GET_MODE_SIZE (mode).to_constant () > UNITS_PER_WORD ? 2 : 1);
       return false;
 
     case AND:
@@ -2128,7 +2134,7 @@  riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
       if (float_mode_p)
 	*total = tune_param->fp_add[mode == DFmode];
       else
-	*total = COSTS_N_INSNS (GET_MODE_SIZE (mode) > UNITS_PER_WORD ? 4 : 1);
+	*total = COSTS_N_INSNS (GET_MODE_SIZE (mode).to_constant () > UNITS_PER_WORD ? 4 : 1);
       return false;
 
     case MULT:
@@ -2137,7 +2143,7 @@  riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
       else if (!TARGET_MUL)
 	/* Estimate the cost of a library call.  */
 	*total = COSTS_N_INSNS (speed ? 32 : 6);
-      else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
+      else if (GET_MODE_SIZE (mode).to_constant () > UNITS_PER_WORD)
 	*total = 3 * tune_param->int_mul[0] + COSTS_N_INSNS (2);
       else if (!speed)
 	*total = COSTS_N_INSNS (1);
@@ -2301,8 +2307,8 @@  riscv_output_move (rtx dest, rtx src)
   dest_code = GET_CODE (dest);
   src_code = GET_CODE (src);
   mode = GET_MODE (dest);
-  dbl_p = (GET_MODE_SIZE (mode) == 8);
-  width = GET_MODE_SIZE (mode);
+  dbl_p = (GET_MODE_SIZE (mode).to_constant () == 8);
+  width = GET_MODE_SIZE (mode).to_constant ();
 
   if (dbl_p && riscv_split_64bit_move_p (dest, src))
     return "#";
@@ -2578,7 +2584,7 @@  static void
 riscv_extend_comparands (rtx_code code, rtx *op0, rtx *op1)
 {
   /* Comparisons consider all XLEN bits, so extend sub-XLEN values.  */
-  if (GET_MODE_SIZE (word_mode) > GET_MODE_SIZE (GET_MODE (*op0)))
+  if (GET_MODE_SIZE (word_mode) > GET_MODE_SIZE (GET_MODE (*op0)).to_constant ())
     {
       /* It is more profitable to zero-extend QImode values.  But not if the
 	 first operand has already been sign-extended, and the second one is
@@ -2941,7 +2947,7 @@  riscv_flatten_aggregate_field (const_tree type,
 	if (n != 0)
 	  return -1;
 
-	HOST_WIDE_INT elt_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (type)));
+	HOST_WIDE_INT elt_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (type))).to_constant ();
 
 	if (elt_size <= UNITS_PER_FP_ARG)
 	  {
@@ -2959,9 +2965,9 @@  riscv_flatten_aggregate_field (const_tree type,
     default:
       if (n < 2
 	  && ((SCALAR_FLOAT_TYPE_P (type)
-	       && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_FP_ARG)
+	       && GET_MODE_SIZE (TYPE_MODE (type)).to_constant () <= UNITS_PER_FP_ARG)
 	      || (INTEGRAL_TYPE_P (type)
-		  && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_WORD)))
+		  && GET_MODE_SIZE (TYPE_MODE (type)).to_constant () <= UNITS_PER_WORD)))
 	{
 	  fields[n].type = type;
 	  fields[n].offset = offset;
@@ -3197,7 +3203,7 @@  riscv_get_arg_info (struct riscv_arg_info *info, const CUMULATIVE_ARGS *cum,
     }
 
   /* Work out the size of the argument.  */
-  num_bytes = type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
+  num_bytes = type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode).to_constant ();
   num_words = (num_bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
 
   /* Doubleword-aligned varargs start on an even register boundary.  */
@@ -3291,7 +3297,7 @@  riscv_function_value (const_tree type, const_tree func, machine_mode mode)
 static bool
 riscv_pass_by_reference (cumulative_args_t cum_v, const function_arg_info &arg)
 {
-  HOST_WIDE_INT size = arg.type_size_in_bytes ();
+  HOST_WIDE_INT size = arg.type_size_in_bytes ().to_constant ();;
   struct riscv_arg_info info;
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
@@ -3920,7 +3926,7 @@  riscv_elf_select_rtx_section (machine_mode mode, rtx x,
 {
   section *s = default_elf_select_rtx_section (mode, x, align);
 
-  if (riscv_size_ok_for_small_data_p (GET_MODE_SIZE (mode)))
+  if (riscv_size_ok_for_small_data_p (GET_MODE_SIZE (mode).to_constant ()))
     {
       if (startswith (s->named.name, ".rodata.cst"))
 	{
@@ -4072,11 +4078,24 @@  riscv_save_libcall_count (unsigned mask)
 
 static HOST_WIDE_INT riscv_first_stack_step (struct riscv_frame_info *frame);
 
+/* Handle stack align for poly_int.  */
+static poly_int64
+riscv_stack_align (poly_int64 value)
+{
+  return aligned_upper_bound (value, PREFERRED_STACK_BOUNDARY / 8);
+}
+
+static HOST_WIDE_INT
+riscv_stack_align (HOST_WIDE_INT value)
+{
+  return RISCV_STACK_ALIGN (value);
+}
+
 static void
 riscv_compute_frame_info (void)
 {
   struct riscv_frame_info *frame;
-  HOST_WIDE_INT offset;
+  poly_int64 offset;
   bool interrupt_save_prologue_temp = false;
   unsigned int regno, i, num_x_saved = 0, num_f_saved = 0;
 
@@ -4087,7 +4106,7 @@  riscv_compute_frame_info (void)
   if (cfun->machine->interrupt_handler_p)
     {
       HOST_WIDE_INT step1 = riscv_first_stack_step (frame);
-      if (! SMALL_OPERAND (frame->total_size - step1))
+      if (! POLY_SMALL_OPERAND_P ((frame->total_size - step1)))
 	interrupt_save_prologue_temp = true;
     }
 
@@ -4117,23 +4136,23 @@  riscv_compute_frame_info (void)
     }
 
   /* At the bottom of the frame are any outgoing stack arguments. */
-  offset = RISCV_STACK_ALIGN (crtl->outgoing_args_size);
+  offset = riscv_stack_align (crtl->outgoing_args_size);
   /* Next are local stack variables. */
-  offset += RISCV_STACK_ALIGN (get_frame_size ());
+  offset += riscv_stack_align (get_frame_size ());
   /* The virtual frame pointer points above the local variables. */
   frame->frame_pointer_offset = offset;
   /* Next are the callee-saved FPRs. */
   if (frame->fmask)
-    offset += RISCV_STACK_ALIGN (num_f_saved * UNITS_PER_FP_REG);
+    offset += riscv_stack_align (num_f_saved * UNITS_PER_FP_REG);
   frame->fp_sp_offset = offset - UNITS_PER_FP_REG;
   /* Next are the callee-saved GPRs. */
   if (frame->mask)
     {
-      unsigned x_save_size = RISCV_STACK_ALIGN (num_x_saved * UNITS_PER_WORD);
+      unsigned x_save_size = riscv_stack_align (num_x_saved * UNITS_PER_WORD);
       unsigned num_save_restore = 1 + riscv_save_libcall_count (frame->mask);
 
       /* Only use save/restore routines if they don't alter the stack size.  */
-      if (RISCV_STACK_ALIGN (num_save_restore * UNITS_PER_WORD) == x_save_size)
+      if (riscv_stack_align (num_save_restore * UNITS_PER_WORD) == x_save_size)
 	{
 	  /* Libcall saves/restores 3 registers at once, so we need to
 	     allocate 12 bytes for callee-saved register.  */
@@ -4149,9 +4168,9 @@  riscv_compute_frame_info (void)
   /* The hard frame pointer points above the callee-saved GPRs. */
   frame->hard_frame_pointer_offset = offset;
   /* Above the hard frame pointer is the callee-allocated varags save area. */
-  offset += RISCV_STACK_ALIGN (cfun->machine->varargs_size);
+  offset += riscv_stack_align (cfun->machine->varargs_size);
   /* Next is the callee-allocated area for pretend stack arguments.  */
-  offset += RISCV_STACK_ALIGN (crtl->args.pretend_args_size);
+  offset += riscv_stack_align (crtl->args.pretend_args_size);
   /* Arg pointer must be below pretend args, but must be above alignment
      padding.  */
   frame->arg_pointer_offset = offset - crtl->args.pretend_args_size;
@@ -4159,7 +4178,7 @@  riscv_compute_frame_info (void)
   /* Next points the incoming stack pointer and any incoming arguments. */
 
   /* Only use save/restore routines when the GPRs are atop the frame.  */
-  if (frame->hard_frame_pointer_offset != frame->total_size)
+  if (known_ne (frame->hard_frame_pointer_offset, frame->total_size))
     frame->save_libcall_adjustment = 0;
 }
 
@@ -4176,10 +4195,10 @@  riscv_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
    or argument pointer.  TO is either the stack pointer or hard frame
    pointer.  */
 
-HOST_WIDE_INT
+poly_int64
 riscv_initial_elimination_offset (int from, int to)
 {
-  HOST_WIDE_INT src, dest;
+  poly_int64 src, dest;
 
   riscv_compute_frame_info ();
 
@@ -4223,7 +4242,7 @@  riscv_set_return_address (rtx address, rtx scratch)
 
   gcc_assert (BITSET_P (cfun->machine->frame.mask, RETURN_ADDR_REGNUM));
   slot_address = riscv_add_offset (scratch, stack_pointer_rtx,
-				  cfun->machine->frame.gp_sp_offset);
+				  cfun->machine->frame.gp_sp_offset.to_constant());
   riscv_emit_move (gen_frame_mem (GET_MODE (address), slot_address), address);
 }
 
@@ -4250,13 +4269,13 @@  riscv_save_restore_reg (machine_mode mode, int regno,
    of the frame.  */
 
 static void
-riscv_for_each_saved_reg (HOST_WIDE_INT sp_offset, riscv_save_restore_fn fn,
+riscv_for_each_saved_reg (poly_int64 sp_offset, riscv_save_restore_fn fn,
 			  bool epilogue, bool maybe_eh_return)
 {
   HOST_WIDE_INT offset;
 
   /* Save the link register and s-registers. */
-  offset = cfun->machine->frame.gp_sp_offset - sp_offset;
+  offset = (cfun->machine->frame.gp_sp_offset - sp_offset).to_constant ();
   for (unsigned int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
     if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
       {
@@ -4287,14 +4306,14 @@  riscv_for_each_saved_reg (HOST_WIDE_INT sp_offset, riscv_save_restore_fn fn,
 
   /* This loop must iterate over the same space as its companion in
      riscv_compute_frame_info.  */
-  offset = cfun->machine->frame.fp_sp_offset - sp_offset;
+  offset = (cfun->machine->frame.fp_sp_offset - sp_offset).to_constant ();
   for (unsigned int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
     if (BITSET_P (cfun->machine->frame.fmask, regno - FP_REG_FIRST))
       {
 	machine_mode mode = TARGET_DOUBLE_FLOAT ? DFmode : SFmode;
 
 	riscv_save_restore_reg (mode, regno, offset, fn);
-	offset -= GET_MODE_SIZE (mode);
+	offset -= GET_MODE_SIZE (mode).to_constant ();
       }
 }
 
@@ -4336,21 +4355,21 @@  riscv_restore_reg (rtx reg, rtx mem)
 static HOST_WIDE_INT
 riscv_first_stack_step (struct riscv_frame_info *frame)
 {
-  if (SMALL_OPERAND (frame->total_size))
-    return frame->total_size;
+  if (SMALL_OPERAND (frame->total_size.to_constant()))
+    return frame->total_size.to_constant();
 
   HOST_WIDE_INT min_first_step =
-    RISCV_STACK_ALIGN (frame->total_size - frame->fp_sp_offset);
+    RISCV_STACK_ALIGN ((frame->total_size - frame->fp_sp_offset).to_constant());
   HOST_WIDE_INT max_first_step = IMM_REACH / 2 - PREFERRED_STACK_BOUNDARY / 8;
-  HOST_WIDE_INT min_second_step = frame->total_size - max_first_step;
+  HOST_WIDE_INT min_second_step = frame->total_size.to_constant() - max_first_step;
   gcc_assert (min_first_step <= max_first_step);
 
   /* As an optimization, use the least-significant bits of the total frame
      size, so that the second adjustment step is just LUI + ADD.  */
   if (!SMALL_OPERAND (min_second_step)
-      && frame->total_size % IMM_REACH < IMM_REACH / 2
-      && frame->total_size % IMM_REACH >= min_first_step)
-    return frame->total_size % IMM_REACH;
+      && frame->total_size.to_constant() % IMM_REACH < IMM_REACH / 2
+      && frame->total_size.to_constant() % IMM_REACH >= min_first_step)
+    return frame->total_size.to_constant() % IMM_REACH;
 
   if (TARGET_RVC)
     {
@@ -4423,7 +4442,7 @@  void
 riscv_expand_prologue (void)
 {
   struct riscv_frame_info *frame = &cfun->machine->frame;
-  HOST_WIDE_INT size = frame->total_size;
+  HOST_WIDE_INT size = frame->total_size.to_constant ();
   unsigned mask = frame->mask;
   rtx insn;
 
@@ -4466,7 +4485,7 @@  riscv_expand_prologue (void)
   if (frame_pointer_needed)
     {
       insn = gen_add3_insn (hard_frame_pointer_rtx, stack_pointer_rtx,
-			    GEN_INT (frame->hard_frame_pointer_offset - size));
+			    GEN_INT ((frame->hard_frame_pointer_offset - size).to_constant ()));
       RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
 
       riscv_emit_stack_tie ();
@@ -4532,7 +4551,7 @@  riscv_expand_epilogue (int style)
      Start off by assuming that no registers need to be restored.  */
   struct riscv_frame_info *frame = &cfun->machine->frame;
   unsigned mask = frame->mask;
-  HOST_WIDE_INT step1 = frame->total_size;
+  HOST_WIDE_INT step1 = frame->total_size.to_constant ();
   HOST_WIDE_INT step2 = 0;
   bool use_restore_libcall = ((style == NORMAL_RETURN)
 			      && riscv_use_save_libcall (frame));
@@ -4540,8 +4559,8 @@  riscv_expand_epilogue (int style)
   rtx insn;
 
   /* We need to add memory barrier to prevent read from deallocated stack.  */
-  bool need_barrier_p = (get_frame_size ()
-			 + cfun->machine->frame.arg_pointer_offset) != 0;
+  bool need_barrier_p
+    = known_ne (get_frame_size (), cfun->machine->frame.arg_pointer_offset);
 
   if (cfun->machine->naked_p)
     {
@@ -4568,7 +4587,7 @@  riscv_expand_epilogue (int style)
       riscv_emit_stack_tie ();
       need_barrier_p = false;
 
-      rtx adjust = GEN_INT (-frame->hard_frame_pointer_offset);
+      rtx adjust = GEN_INT (-frame->hard_frame_pointer_offset.to_constant ());
       if (!SMALL_OPERAND (INTVAL (adjust)))
 	{
 	  riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode), adjust);
@@ -4582,7 +4601,7 @@  riscv_expand_epilogue (int style)
       rtx dwarf = NULL_RTX;
       rtx cfa_adjust_value = gen_rtx_PLUS (
 			       Pmode, hard_frame_pointer_rtx,
-			       GEN_INT (-frame->hard_frame_pointer_offset));
+			       GEN_INT (-frame->hard_frame_pointer_offset.to_constant ()));
       rtx cfa_adjust_rtx = gen_rtx_SET (stack_pointer_rtx, cfa_adjust_value);
       dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, cfa_adjust_rtx, dwarf);
       RTX_FRAME_RELATED_P (insn) = 1;
@@ -4599,7 +4618,7 @@  riscv_expand_epilogue (int style)
     }
 
   /* Set TARGET to BASE + STEP1.  */
-  if (step1 > 0)
+  if (known_gt (step1, 0))
     {
       /* Emit a barrier to prevent loads from a deallocated stack.  */
       riscv_emit_stack_tie ();
@@ -4725,7 +4744,7 @@  riscv_epilogue_uses (unsigned int regno)
 bool
 riscv_can_use_return_insn (void)
 {
-  return (reload_completed && cfun->machine->frame.total_size == 0
+  return (reload_completed && known_eq (cfun->machine->frame.total_size, 0)
 	  && ! cfun->machine->interrupt_handler_p);
 }
 
@@ -4825,7 +4844,7 @@  static bool
 riscv_secondary_memory_needed (machine_mode mode, reg_class_t class1,
 			       reg_class_t class2)
 {
-  return (GET_MODE_SIZE (mode) > UNITS_PER_WORD
+  return (GET_MODE_SIZE (mode).to_constant () > UNITS_PER_WORD
 	  && (class1 == FP_REGS) != (class2 == FP_REGS));
 }
 
@@ -4848,10 +4867,10 @@  static unsigned int
 riscv_hard_regno_nregs (unsigned int regno, machine_mode mode)
 {
   if (FP_REG_P (regno))
-    return (GET_MODE_SIZE (mode) + UNITS_PER_FP_REG - 1) / UNITS_PER_FP_REG;
+    return (GET_MODE_SIZE (mode).to_constant () + UNITS_PER_FP_REG - 1) / UNITS_PER_FP_REG;
 
   /* All other registers are word-sized.  */
-  return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+  return (GET_MODE_SIZE (mode).to_constant () + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
 }
 
 /* Implement TARGET_HARD_REGNO_MODE_OK.  */
@@ -5058,6 +5077,38 @@  riscv_init_machine_status (void)
   return ggc_cleared_alloc<machine_function> ();
 }
 
+/* Return the VLEN value associated with -march.  
+   TODO: So far we only support length-agnostic value. */
+
+static poly_uint16
+riscv_convert_vector_bits (void)
+{
+  /* The runtime invariant is only meaningful when vector is enabled. */
+  if (!TARGET_VECTOR)
+    return 0;
+
+  if (TARGET_VECTOR_ELEN_64 || TARGET_VECTOR_ELEN_FP_64)
+    {
+      /* When targetting Zve64* (ELEN = 64) extensions, we should use 64-bit
+     chunk size. Runtime invariant: The single indeterminate represent the
+     number of 64-bit chunks in a vector beyond minimum length of 64 bits. Thus
+     the number of bytes in a vector is 8 + 8 * x1 which is riscv_vector_chunks
+     * 8 = poly_int (8, 8). */
+      riscv_bytes_per_vector_chunk = 8;
+    }
+  else
+    {
+      /* When targetting Zve32* (ELEN = 32) extensions, we should use 32-bit
+     chunk size. Runtime invariant: The single indeterminate represent the
+     number of 32-bit chunks in a vector beyond minimum length of 32 bits. Thus
+     the number of bytes in a vector is 4 + 4 * x1 which is riscv_vector_chunks
+     * 4 = poly_int (4, 4).  */
+      riscv_bytes_per_vector_chunk = 4;
+    }
+
+  return poly_uint16 (1, 1);
+}
+
 /* Implement TARGET_OPTION_OVERRIDE.  */
 
 static void
@@ -5204,6 +5255,8 @@  riscv_option_override (void)
       riscv_stack_protector_guard_offset = offs;
     }
 
+  /* Convert -march to a chunks count.  */
+  riscv_vector_chunks = riscv_convert_vector_bits ();
 }
 
 /* Implement TARGET_CONDITIONAL_REGISTER_USAGE.  */
@@ -5561,7 +5614,7 @@  riscv_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
     return promote_mode (type, mode, punsignedp);
 
   unsignedp = *punsignedp;
-  PROMOTE_MODE (mode, unsignedp, type);
+  PROMOTE_MODE (as_a <scalar_mode> (mode), unsignedp, type);
   *punsignedp = unsignedp;
   return mode;
 }
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index 6f7f4d3fbdc..4b07c5487c6 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -522,6 +522,10 @@  enum reg_class
 #define SMALL_OPERAND(VALUE) \
   ((unsigned HOST_WIDE_INT) (VALUE) + IMM_REACH/2 < IMM_REACH)
 
+#define POLY_SMALL_OPERAND_P(POLY_VALUE)		\
+  (POLY_VALUE.is_constant () ?				\
+     SMALL_OPERAND (POLY_VALUE.to_constant ()) : false)
+     
 /* True if VALUE can be loaded into a register using LUI.  */
 
 #define LUI_OPERAND(VALUE)						\
@@ -952,6 +956,11 @@  while (0)
 extern const enum reg_class riscv_regno_to_class[];
 extern bool riscv_slow_unaligned_access_p;
 extern unsigned riscv_stack_boundary;
+extern unsigned riscv_bytes_per_vector_chunk;
+extern poly_uint16 riscv_vector_chunks;
+/* The number of bits and bytes in a RVV vector.  */
+#define BITS_PER_RISCV_VECTOR (poly_uint16 (riscv_vector_chunks * riscv_bytes_per_vector_chunk * 8))
+#define BYTES_PER_RISCV_VECTOR (poly_uint16 (riscv_vector_chunks * riscv_bytes_per_vector_chunk))
 #endif
 
 #define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 493f00cdb80..c517ae0d0f7 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -2162,7 +2162,7 @@ 
        (lshiftrt:GPR (match_dup 3) (match_dup 2)))]
 {
   /* Op2 is a VOIDmode constant, so get the mode size from op1.  */
-  operands[2] = GEN_INT (GET_MODE_BITSIZE (GET_MODE (operands[1]))
+  operands[2] = GEN_INT (GET_MODE_BITSIZE (GET_MODE (operands[1])).to_constant ()
 			 - exact_log2 (INTVAL (operands[2]) + 1));
 })