https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83707
Will Schmidt <willschm at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |willschm at gcc dot gnu.org --- Comment #2 from Will Schmidt <willschm at gcc dot gnu.org> --- The troublesome snippet of code reads as so ( from gcc/testsuite/g++.dg/eh/simd-3.C ) " int main(void) { v v1 = vt; try { thrower(); } catch (int x) { } v2 = v1; if (memcmp(&v2,&vt,...)) abort(); " where thrower() is a function meant to scramble contents of the VSRs. And the problem (that we abort during the test run) occurs when any non-zero optimization level is specified, due to vt != v2. high-level debug suggests that we are not storing the v1=vt result to memory, (only to a reg), so the call to thrower clobbers the contents, and we ultimately fail. When built with -O0, on the "v1 = vt" statement, i can see (.expand dump) ;; Generating RTL for gimple basic block 2 ;; v1_5 ={v} vt; (insn # # # (set (reg:SI 129) (high:SI (symbol_ref:SI ("vt") [flags 0x2] <var_decl # vt>))) "/home/willschm/gcc/gcc-mainline-regtest_patches/gcc/testsuite/g++.dg/eh/simd-3.C":56# (nil)) (insn # # # (set (reg/f:SI 128) (lo_sum:SI (reg:SI 129) (symbol_ref:SI ("vt") [flags 0x2] <var_decl # vt>))) "/home/willschm/gcc/gcc-mainline-regtest_patches/gcc/testsuite/g++.dg/eh/simd-3.C":56# (expr_list:REG_EQUAL (symbol_ref:SI ("vt") [flags 0x2] <var_decl # vt>) (nil))) (insn # # # (set (reg:V4SI 130) (mem/v/c:V4SI (reg/f:SI 128) [1 vt+0 S16 A128])) "/home/willschm/gcc/gcc-mainline-regtest_patches/gcc/testsuite/g++.dg/eh/simd-3.C":56# (nil)) (insn # # 0 (set (mem/c:V4SI (plus:SI (reg/f:SI 116 virtual-stack-vars) (const_int 8 [0x8])) [1 v1+0 S16 A128]) (reg:V4SI 130)) "/home/willschm/gcc/gcc-mainline-regtest_patches/gcc/testsuite/g++.dg/eh/simd-3.C":56# (nil)) ;; thrower (); Noting the "set (mem/c..." statement. This code works, in that the v1 value survives the call to thrower. When built with -O1, that chunk of the dump now reads: ;; v1_4 ={v} vt; (insn # # # (set (reg:SI 128) (high:SI (symbol_ref:SI ("*.LANCHOR1") [flags 0x182]))) "/home/willschm/gcc/gcc-mainline-regtest_patches/gcc/testsuite/g++.dg/eh/simd-3.C":56# (nil)) (insn # # # (set (reg/f:SI 127) (lo_sum:SI (reg:SI 128) (symbol_ref:SI ("*.LANCHOR1") [flags 0x182]))) "/home/willschm/gcc/gcc-mainline-regtest_patches/gcc/testsuite/g++.dg/eh/simd-3.C":56# (expr_list:REG_EQUAL (symbol_ref:SI ("*.LANCHOR1") [flags 0x182]) (nil))) (insn # # 0 (set (reg/v:V4SI 123 [ v1 ]) (mem/v/c:V4SI (reg/f:SI 127) [1 vt+0 S16 A128])) "/home/willschm/gcc/gcc-mainline-regtest_patches/gcc/testsuite/g++.dg/eh/simd-3.C":56# (nil)) ;; thrower (); And here, note that this is a "set (reg". There is no "set (mem" until after the "v2 = v1" statement, after the call to thrower(). This seems to fit with what I see via objdump : (working code) xx <main>: xx: 94 21 ff c0 stwu r1,-64(r1) xx: 7c 08 02 a6 mflr r0 xx: 90 01 00 44 stw r0,68(r1) xx: 93 e1 00 3c stw r31,60(r1) xx: 7c 3f 0b 78 mr r31,r1 xx: 3d 20 10 02 lis r9,4098 xx: 39 29 00 40 addi r9,r9,64 xx: 7c 00 4e 18 lxvw4x vs0,0,r9 <- load. xx: 39 20 00 10 li r9,16 xx: 7c 1f 4f 18 stxvw4x vs0,r31,r9 <- store. xx: 4b ff ff 61 bl 1000074c <_Z7throwerv> versus (failing code): xx <main>: xx: 94 21 ff d0 stwu r1,-48(r1) xx: 7c 08 02 a6 mflr r0 xx: 90 01 00 34 stw r0,52(r1) xx: 38 00 00 10 li r0,16 xx: 7f e1 01 ce stvx v31,r1,r0 xx: 3d 20 10 02 lis r9,4098 xx: 39 29 00 40 addi r9,r9,64 xx: 7f e0 4e 19 lxvw4x vs63,0,r9 <- load, no store. xx: 4b ff ff 89 bl 100006f0 <_Z7throwerv> most previous tree dump before expand (232t.optimized) shows bb2 having: <bb 2> : v1_5 ={v} vt; thrower (); versus <bb 2> [local count: 1073741825]: v1_4 ={v} vt; thrower ();