On 7/20/2026 6:31 AM, Richard Biener wrote:
The following adds simplification of a scalar mode vec_select wrapping
a vec_concat.  combine sees

(insn 7 4 8 2 (set (reg:V2DF 106)
         (vec_concat:V2DF (plus:DF (vec_select:DF (reg/v:V2DF 101 [ p ])
                     (parallel [
                             (const_int 0 [0])
                         ]))
                 (vec_select:DF (reg/v:V2DF 101 [ p ])
                     (parallel [
                             (const_int 1 [0x1])
                         ])))
             (plus:DF (vec_select:DF (reg/v:V2DF 101 [ p ])
                     (parallel [
                             (const_int 0 [0])
                         ]))
                 (vec_select:DF (reg/v:V2DF 101 [ p ])
                     (parallel [
                             (const_int 1 [0x1])
                         ]))))) "t.c":5:11 3234 {*sse3_haddv2df3}
      (expr_list:REG_DEAD (reg/v:V2DF 101 [ p ])
         (nil)))
(insn 8 7 9 2 (set (reg:DF 105)
         (vec_select:DF (reg:V2DF 106)
             (parallel [
                     (const_int 0 [0])
                 ]))) "t.c":5:11 7297 {sse2_storelpd}
      (expr_list:REG_DEAD (reg:V2DF 106)
         (nil)))

and this should simplify and combine to

(set (reg:DF 105)
     (plus:DF (vec_select:DF (reg:V2DF 109 [ p ])
             (parallel [
                     (const_int 0 [0])
                 ]))
         (vec_select:DF (reg:V2DF 109 [ p ])
             (parallel [
                     (const_int 1 [0x1])
                 ]))))

which x86 can recognize (but rejects due to consting, see PR126328).
There'll be test coverage in gcc.target/i386/pr54400.c

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

The code snipped is stripped down from the vector vec_select case
but with the side_effects_p arguments fixed(?)

OK?

Thanks,
Richard.

        * simplify-rtx.cc (simplify_context::simplify_binary_operation_1):
        Simplify scalar vec_select of vec_concat.
---
  gcc/simplify-rtx.cc | 18 ++++++++++++++++++
  1 file changed, 18 insertions(+)

diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index 882a11c5760..612413bf035 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -5148,6 +5148,7 @@ simplify_ashift:
             nested VEC_SELECT expressions.  When input operand is a memory
             operand, this operation can be simplified to a simple scalar
             load from an offsetted memory address.  */
+         int l0, l1;
          int n_elts;
          if (GET_CODE (trueop0) == VEC_SELECT
              && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
@@ -5210,6 +5211,23 @@ simplify_ashift:
                                    tmp_op, gen_rtx_PARALLEL (VOIDmode, vec));
              return tmp;
            }
+         /* If we select one half of a vec_concat, return that.  */
+         else if (GET_CODE (trueop0) == VEC_CONCAT
+                  && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
+                      .is_constant (&l0))
+                  && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 1)))
+                      .is_constant (&l1)))
You never use l1, though I guess what you're really testing is that it is a constant, you don't need to know the precise constant?

Jeff

Reply via email to