On 1/12/2026 9:49 PM, Andrew Pinski wrote:
On Mon, Jan 12, 2026 at 7:56 PM Jeffrey Law
<[email protected]> wrote:


On 1/12/2026 2:58 PM, Andrew Pinski wrote:

I think this should be closer to what I did for VEC_SHL_INSERT in
r16-4742-gfcde4c81644aec (this was based on the review where I tried
to do a similar thing as you did:
https://gcc.gnu.org/pipermail/gcc-patches/2024-July/658275.html ).

That is, in fold_const_call (in fold-const.cc) add VEC_EXTRACT case
and do similar as fold_const_vec_shl_insert.
Something like:
```
static tree
fold_const_vec_extract (tree, tree arg0, tree arg1)
{
   if (TREE_CODE (arg0) != VECTOR_CST)
     return NULL_TREE;

   /* vec_extract ( dup(CST), N) -> CST. */
   if (tree elem = uniform_vector_p (arg0))
       return elem;

   return NULL_TREE;
}
```
And also  in match.pd add:
```
(simplify
  (IFN_VEC_EXTRACT (vec_duplicate @0) @1)
   @0)
```

I don't think we need to care about the bounds check on @1 either
because then it would be undefined anyways.

Uniform vectors can come in different forms.    They can be a VEC_DUPLICATE, 
VECTOR_CST or even a CONSTRUCTOR node.  uniform_vector_p knows how to handle 
all three cases already.  So while that solution is simpler, I suspect it's 
leaving good opportunities on the floor and may not even cover the regression 
in question (I haven't checked that).
Note your current pattern only handles VECTOR_CST because that is only
valid as an operand for the function call.
For a CONSTRUCTOR or a VEC_DUPLICATE, @0 will be a SSA_NAME as
CONSTRUCTOR/VEC_DUPLICATEs are only valid if alone in a stmt and
uniform_vector_p will return false for a SSA_NAME.
ACK.


You could change the patch to be similar to what I originally did for
IFN_VEC_SHL_INSERT
(https://gcc.gnu.org/pipermail/gcc-patches/2024-July/658274.html);
though Richard had the same suggestion as I have above:
Yea, that does work for the testcase in question.

OK now?  Passed riscv{32,64}-elf.  The bootstrap tests are still in flight.


jeff

        PR target/113666
gcc/
        * fold-const-call.cc (fold_const_vec_extract): New function.
        (fold_const_call, case CFN_VEC_EXTRACT): Call it.
        * match.pd (IFN_VEC_EXTRACT): Handle extraction from a uniform
        vector.

gcc/testsuite
        * gcc.target/riscv/rvv/base/pr113666.c: New test.

diff --git a/gcc/fold-const-call.cc b/gcc/fold-const-call.cc
index 464d162cf550..aa63ced00bba 100644
--- a/gcc/fold-const-call.cc
+++ b/gcc/fold-const-call.cc
@@ -1459,6 +1459,26 @@ fold_const_vec_shl_insert (tree, tree arg0, tree arg1)
   return NULL_TREE;
 }
 
+/* Fold a call to IFN_VEC_EXTRACT (ARG0, ARG1), returning a value
+   of type TYPE.
+
+   Right now this is only handling uniform vectors, so ARG1 is not
+   used.  But it could be easily adjusted in the future to handle
+   non-uniform vectors by extracting the relevant element.  */
+
+static tree
+fold_const_vec_extract (tree, tree arg0, tree)
+{
+  if (TREE_CODE (arg0) != VECTOR_CST)
+    return NULL_TREE;
+
+  /* vec_extract ( dup(CST), CST) -> dup (CST). */
+  if (tree elem = uniform_vector_p (arg0))
+    return elem;
+
+  return NULL_TREE;
+}
+
 /* Try to evaluate:
 
       *RESULT = FN (*ARG0, *ARG1)
@@ -1865,6 +1885,9 @@ fold_const_call (combined_fn fn, tree type, tree arg0, 
tree arg1)
     case CFN_VEC_SHL_INSERT:
       return fold_const_vec_shl_insert (type, arg0, arg1);
 
+    case CFN_VEC_EXTRACT:
+      return fold_const_vec_extract (type, arg0, arg1);
+
     case CFN_UBSAN_CHECK_ADD:
     case CFN_ADD_OVERFLOW:
       subcode = PLUS_EXPR;
diff --git a/gcc/match.pd b/gcc/match.pd
index ea840502640b..ca696df8c5ab 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -12226,3 +12226,8 @@ and,
         && TYPE_UNSIGNED (type)
         && @0 == @3)
     (bit_xor (rrotate @0 @4) @2)))
+
+/* Optimize extraction from a uniform vector to a representative element as
+   long as the requested element is within range.  */
+(simplify (IFN_VEC_EXTRACT (vec_duplicate @0) INTEGER_CST@1)
+ @0)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr113666.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113666.c
new file mode 100644
index 000000000000..b1034d7676d0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113666.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" { target rv64} } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32 -O3" { target rv32} } */
+
+unsigned char a;
+
+int main() {
+  short b = a = 0;
+  for (; a != 19; a++)
+    if (a)
+      b = 32872 >> a;
+
+  if (b == 0)
+    return 0;
+  else
+    return 1;
+}
+
+/* If we vectorized, we should still be able to collapse away the VEC_EXTRACT,
+   leaving zero vector code in the final assembly.  So there should be no 
+   vsetvl instructions.  */
+/* { dg-final { scan-assembler-not {vsetivli} } } */
+
+

Reply via email to