]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Avoid duplicate vector initializations during RTL expansion.
authorRoger Sayle <roger@nextmovesoftware.com>
Tue, 13 Jun 2023 16:20:31 +0000 (17:20 +0100)
committerRoger Sayle <roger@nextmovesoftware.com>
Tue, 13 Jun 2023 16:20:31 +0000 (17:20 +0100)
This middle-end patch avoids some redundant RTL for vector initialization
during RTL expansion.  For the simple test case:

typedef __int128 v1ti __attribute__ ((__vector_size__ (16)));
__int128 key;

v1ti foo() {
    return (v1ti){key};
}

the middle-end currently expands:

(set (reg:V1TI 85) (const_vector:V1TI [ (const_int 0) ]))

(set (reg:V1TI 85) (mem/c:V1TI (symbol_ref:DI ("key"))))

where we create a dead instruction that initializes the vector to zero,
immediately followed by a set of the entire vector.  This patch skips
this zeroing instruction when the vector has only a single element.
It also updates the code to indicate when we've cleared the vector,
so that we don't need to initialize zero elements.

2023-06-13  Roger Sayle  <roger@nextmovesoftware.com>

gcc/ChangeLog
* expr.cc (store_constructor) <case VECTOR_TYPE>: Don't bother
clearing vectors with only a single element.  Set CLEARED if the
vector was initialized to zero.

gcc/expr.cc

index 868fa6e4ccabec9092cc1ef8934b500bab3be03c..62cd8facf75643c3c8310386df986a2b6cd5dc40 100644 (file)
@@ -7531,8 +7531,11 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size,
          }
 
        /* Inform later passes that the old value is dead.  */
-       if (!cleared && !vector && REG_P (target))
-         emit_move_insn (target, CONST0_RTX (mode));
+       if (!cleared && !vector && REG_P (target) && maybe_gt (n_elts, 1u))
+         {
+           emit_move_insn (target, CONST0_RTX (mode));
+           cleared = 1;
+         }
 
         if (MEM_P (target))
          alias = MEM_ALIAS_SET (target);