https://gcc.gnu.org/g:6967bd6c9a0be06dfa9ad3b160701e862fe2baea

commit r17-5199-g6967bd6c9a0be06dfa9ad3b160701e862fe2baea
Author: From: Jonas Hansen <[email protected]>
Date:   Wed Oct 14 07:28:06 2026 -0600

    [PATCH v2 2/2] testsuite: Keep character-array and enum DSE coverage 
[PR127416]
    
    From: Jonas Hansen <[email protected]>
    
    Retain the original character-array program in ssa-dse-1.C and check
    that DSE removes the whole-object clear overwritten by the string
    assignment, including its implicit trailing zeros. Move the enum
    variant into ssa-dse-4.C with the original partial-DSE assertion.
    
    Tested on x86_64-pc-linux-gnu with 350 expected passes and three
    unsupported cases in the DSE and related initialization regression
    selection. Both tests also pass all four compile/dump checks for
    arm-none-eabi Cortex-M0. The new character-array assertion fails with
    the saved pre-follow-up compilers, and disabling partial DSE makes
    the enum assertion fail on both targets.
    
    gcc/testsuite/ChangeLog:
    
            PR tree-optimization/127416
            * g++.dg/tree-ssa/ssa-dse-1.C (byte): Remove enum.
            (fixbuf): Restore char buffer elements. Update the dump assertion
            to check deletion of the redundant whole-object clear.
            * g++.dg/tree-ssa/ssa-dse-4.C: New test preserving the enum variant
            and partial-DSE assertion.
    
    Signed-off-by: Jonas Hansen <[email protected]>

Diff:
---
 gcc/testsuite/g++.dg/tree-ssa/ssa-dse-1.C |  14 ++--
 gcc/testsuite/g++.dg/tree-ssa/ssa-dse-4.C | 104 ++++++++++++++++++++++++++++++
 2 files changed, 110 insertions(+), 8 deletions(-)

diff --git a/gcc/testsuite/g++.dg/tree-ssa/ssa-dse-1.C 
b/gcc/testsuite/g++.dg/tree-ssa/ssa-dse-1.C
index a3dd41ff2eed..06cdfb5d6698 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/ssa-dse-1.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/ssa-dse-1.C
@@ -3,10 +3,6 @@
 
 using uint = unsigned int;
 
-// Use a byte-sized enum so the initializer remains a CONSTRUCTOR rather than
-// becoming a STRING_CST, preserving the stores this test exercises.
-enum class byte : unsigned char {};
-
 template<typename C, uint S>
 struct FixBuf
 {
@@ -75,10 +71,10 @@ template<uint N, uint S, bool BOS = 0>
 constexpr
 auto fixbuf()
 {
-       FixBuf<byte, S> fb;
-       OutBuf<byte> ob{fb};
+       FixBuf<char, S> fb;
+       OutBuf<char> ob{fb};
        for (uint i = 0; i <= N; ++i) {
-               ob << i << static_cast<byte>(i == N ? 0 : ' ');
+               ob << i << static_cast<char>(i == N ? 0 : ' ');
        }
        return BufOrSize<BOS>::Select(fb, ob);
 }
@@ -101,4 +97,6 @@ int main()
 }
 
 
-/* { dg-final { scan-tree-dump-times "MEM <char\\\[\[0-9\]+]> \\\[\\(struct 
FixBuf \\*\\)&<retval> \\+ \[0-9\]+B\\\] = {}" 1 "dse1" } } */
+// The string assignment includes the trailing zeros, making the preceding
+// whole-object clear redundant.  Keep partial DSE covered by ssa-dse-4.C.
+/* { dg-final { scan-tree-dump-times "Deleted dead store: <retval> = {};" 1 
"dse1" } } */
diff --git a/gcc/testsuite/g++.dg/tree-ssa/ssa-dse-4.C 
b/gcc/testsuite/g++.dg/tree-ssa/ssa-dse-4.C
new file mode 100644
index 000000000000..a3dd41ff2eed
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/ssa-dse-4.C
@@ -0,0 +1,104 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c++14 -O -fdump-tree-dse1-details" } */
+
+using uint = unsigned int;
+
+// Use a byte-sized enum so the initializer remains a CONSTRUCTOR rather than
+// becoming a STRING_CST, preserving the stores this test exercises.
+enum class byte : unsigned char {};
+
+template<typename C, uint S>
+struct FixBuf
+{
+       C buf[S] = {};
+};
+
+template<typename C>
+struct OutBuf
+{
+       C*      cur;
+       C*      end;
+       C*      beg;
+
+       template<uint S>
+       constexpr
+       OutBuf(FixBuf<C, S>& b) : cur{b.buf}, end{b.buf + S}, beg{b.buf} { }
+
+       OutBuf(C* b, C* e) : cur{b}, end{e} { }
+       OutBuf(C* b, uint s) : cur{b}, end{b + s} { }
+
+       constexpr
+       OutBuf& operator<<(C v)
+       {
+               if (cur < end) {
+                       *cur = v;
+               }
+               ++cur;
+               return *this;
+       }
+
+       constexpr
+       OutBuf& operator<<(uint v)
+       {
+               uint q = v / 10U;
+               uint r = v % 10U;
+               if (q) {
+                       *this << q;
+               }
+               *this << static_cast<C>(r + '0');
+               return *this;
+       }
+};
+
+template<bool BOS>
+struct BufOrSize
+{
+       template<typename C, uint S>
+       static constexpr auto Select(FixBuf<C, S>& fb, OutBuf<C>&)
+       {
+               return fb;
+       }
+};
+
+template<>
+struct BufOrSize<true>
+{
+       template<typename C, uint S>
+       static constexpr auto Select(FixBuf<C, S>&, OutBuf<C>& ob)
+       {
+               return ob.cur - ob.beg;
+       }
+};
+
+// if BOS=1, it will return the size of the generated data, else the data 
itself
+template<uint N, uint S, bool BOS = 0>
+constexpr
+auto fixbuf()
+{
+       FixBuf<byte, S> fb;
+       OutBuf<byte> ob{fb};
+       for (uint i = 0; i <= N; ++i) {
+               ob << i << static_cast<byte>(i == N ? 0 : ' ');
+       }
+       return BufOrSize<BOS>::Select(fb, ob);
+}
+
+auto foo()
+{
+       constexpr auto x = fixbuf<13, 200>();
+       return x;
+}
+
+auto foo_sized()
+{
+       constexpr auto s = fixbuf<13, 0, 1>();
+       constexpr auto x = fixbuf<13, s>();
+       return x;
+}
+
+int main()
+{
+}
+
+
+/* { dg-final { scan-tree-dump-times "MEM <char\\\[\[0-9\]+]> \\\[\\(struct 
FixBuf \\*\\)&<retval> \\+ \[0-9\]+B\\\] = {}" 1 "dse1" } } */

Reply via email to