Created attachment 58741 [details] Reduced example. Attempting to compile the attached file with "g++ -pthread -O1 -ftree-slp-vectorize -pipe -std=gnu++20 -fno-stack-protector" on arm64 results in a miscompilation where ObjectWriteToReadOnlyProperty returns 1 in x0 on Throw() path. Removing '-ftree-slp-vectorize' results in correct output. This is a reduced example that was extraced from nodejs code. On arm64 specifically, this is a regression caused by 33c2b70dbabc02788caabcbc66b7baeafeb95bcf, however as that commit only changes costs, the bug is most likely somewhere else.
I've debugged this already AOT. SLP generates the following: <bb 2> [local count: 1073741824]: _8 = {0, __trans_tmp_1$1_4(D)}; WriteToReadOnlyProperty_should_throw.0_1 = WriteToReadOnlyProperty_should_throw; if (WriteToReadOnlyProperty_should_throw.0_1 != 0) goto <bb 4>; [67.00%] else goto <bb 3>; [33.00%] <bb 3> [local count: 354334800]: Throw (); <bb 4> [local count: 1073741824]: # _10 = PHI <0(2), __trans_tmp_1$1_4(D)(3)> # _12 = PHI <1(2), 0(3)> # vect__12.9_6 = PHI <{ 1, 0 }(2), _8(3)> MEM[(struct Maybe *)&D.4540] = vect__12.9_6; return D.4540; ... from: <bb 2> [local count: 1073741824]: WriteToReadOnlyProperty_should_throw.0_1 = WriteToReadOnlyProperty_should_throw; if (WriteToReadOnlyProperty_should_throw.0_1 != 0) goto <bb 4>; [67.00%] else goto <bb 3>; [33.00%] <bb 3> [local count: 354334800]: Throw (); <bb 4> [local count: 1073741824]: # _10 = PHI <0(2), __trans_tmp_1$1_4(D)(3)> # _12 = PHI <1(2), 0(3)> MEM <unsigned char> [(struct Maybe *)&D.4540] = _12; MEM <unsigned char> [(struct Maybe *)&D.4540 + 1B] = _10; return D.4540; ... replacing the two MEMs with a vector. later, ccp4 decides: Visiting statement: _8 = {0, __trans_tmp_1$1_4(D)}; which is likely UNDEFINED Lattice value changed to UNDEFINED. Adding SSA edges to worklist. marking stmt to be not simulated again ... Visiting PHI node: vect__12.9_6 = PHI <{ 1, 0 }(2), _8(3)> Argument #0 (2 -> 4 executable) { 1, 0 } Value: CONSTANT { 1, 0 } Argument #1 (3 -> 4 executable) _8 Value: UNDEFINED PHI node value: CONSTANT { 1, 0 } ... <bb 2> [local count: 1073741824]: WriteToReadOnlyProperty_should_throw.0_1 = WriteToReadOnlyProperty_should_throw; if (WriteToReadOnlyProperty_should_throw.0_1 != 0) goto <bb 4>; [67.00%] else goto <bb 3>; [33.00%] <bb 3> [local count: 354334800]: Throw (); <bb 4> [local count: 1073741824]: # _12 = PHI <1(2), 0(3)> MEM[(struct Maybe *)&D.4540] = { 1, 0 }; return D.4540; and, so, as a result both branches start returning { 1, 0 }.
g:33c2b70dbabc02788caabcbc66b7baeafeb95bcf That just changed the cost model. Most likely could be reproduced with -fno-cost-model beforehand. Note there is an unitialized usage on one side of the if so that might be an iasue.
#define vect8 __attribute__((vector_size(8))) vect8 int f(int a) { int b; vect int t={1,1}; if(a) return t; return (vect8 int){0, b}; }
So this code might have undefined behavior. At the very least it is questionable.
Can you attach the original code that was failing since the reduced one is questionable?
The failing function is at https://github.com/nodejs/node/blob/main/deps/v8/src/objects/objects.cc#L2521 , the RETURN_FAILURE macro is defined at https://github.com/nodejs/node/blob/main/deps/v8/src/execution/isolate.h#L384 and the Maybe class is defined at https://github.com/nodejs/node/blob/main/deps/v8/include/v8-maybe.h#L32
Can you attach the full preprocessed source instead of just linking?
The question comes is this defined or undefined? I think it is still undefined. Changing: Maybe() : has_value_(false) {} into: Maybe() : has_value_(false), value_() {} Makes this well defined. And has no effect on if value_ had a constructor or not.
So r12-397-gda9e6e63d1ae22 introduced ccp after the slp vectorizer. Also it happens on x86_64 with -fno-vect-cost-model.
Other links for completeness (don't fit in See Also right now, need to ping overseers about applying the patches for that...): * https://issues.chromium.org/issues/42203868 * https://issues.chromium.org/issues/42204492
I think the bug is in CCPs likely_value, it doesn't see the constant operand in the CTOR but only the undefined one and thus makes it UNDEFINED instead of CONSTNAT.
The master branch has been updated by Richard Biener <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:1ea551514b9c285d801ac5ab8d78b22483ff65af commit r15-2255-g1ea551514b9c285d801ac5ab8d78b22483ff65af Author: Richard Biener <rguenther@suse.de> Date: Wed Jul 24 13:16:35 2024 +0200 tree-optimization/116057 - wrong code with CCP and vector CTORs The following fixes an issue with CCPs likely_value when faced with a vector CTOR containing undef SSA names and constants. This should be classified as CONSTANT and not UNDEFINED. PR tree-optimization/116057 * tree-ssa-ccp.cc (likely_value): Also walk CTORs in stmt operands to look for constants. * gcc.dg/torture/pr116057.c: New testcase.
This fixed the CCP issue. I think there's a SLP issue as well in that it inserts the uninit use where it wasn't used before. Ideally we'd insert this invariant only on the edge 3->4 - I will see if I can fix that as well.
Created attachment 58750 [details] Full preprocessed source part 1
Created attachment 58751 [details] Full preprocessed source part 2
The releases/gcc-14 branch has been updated by Richard Biener <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:a7f1b00ed69810ce7f000d385a60e148d0228d48 commit r14-10520-ga7f1b00ed69810ce7f000d385a60e148d0228d48 Author: Richard Biener <rguenther@suse.de> Date: Wed Jul 24 13:16:35 2024 +0200 tree-optimization/116057 - wrong code with CCP and vector CTORs The following fixes an issue with CCPs likely_value when faced with a vector CTOR containing undef SSA names and constants. This should be classified as CONSTANT and not UNDEFINED. PR tree-optimization/116057 * tree-ssa-ccp.cc (likely_value): Also walk CTORs in stmt operands to look for constants. * gcc.dg/torture/pr116057.c: New testcase. (cherry picked from commit 1ea551514b9c285d801ac5ab8d78b22483ff65af)
The releases/gcc-13 branch has been updated by Richard Biener <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:ef25f1dd600cc9351c80e3e018d7170e16a2c6ff commit r13-9042-gef25f1dd600cc9351c80e3e018d7170e16a2c6ff Author: Richard Biener <rguenther@suse.de> Date: Wed Jul 24 13:16:35 2024 +0200 tree-optimization/116057 - wrong code with CCP and vector CTORs The following fixes an issue with CCPs likely_value when faced with a vector CTOR containing undef SSA names and constants. This should be classified as CONSTANT and not UNDEFINED. PR tree-optimization/116057 * tree-ssa-ccp.cc (likely_value): Also walk CTORs in stmt operands to look for constants. * gcc.dg/torture/pr116057.c: New testcase. (cherry picked from commit 1ea551514b9c285d801ac5ab8d78b22483ff65af)
The releases/gcc-12 branch has been updated by Richard Biener <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:c8b549857d968d634a74709112e5acc9f9caf35c commit r12-10895-gc8b549857d968d634a74709112e5acc9f9caf35c Author: Richard Biener <rguenther@suse.de> Date: Wed Jul 24 13:16:35 2024 +0200 tree-optimization/116057 - wrong code with CCP and vector CTORs The following fixes an issue with CCPs likely_value when faced with a vector CTOR containing undef SSA names and constants. This should be classified as CONSTANT and not UNDEFINED. PR tree-optimization/116057 * tree-ssa-ccp.cc (likely_value): Also walk CTORs in stmt operands to look for constants. * gcc.dg/torture/pr116057.c: New testcase. (cherry picked from commit 1ea551514b9c285d801ac5ab8d78b22483ff65af)
Fixed.