[Bug tree-optimization/94015] New: [10 Regression] Another assignment incorrectly omitted by -foptimize-strlen
nate at thatsmathematics dot com
gcc-bugzilla@gcc.gnu.org
Tue Mar 3 14:51:00 GMT 2020
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94015
Bug ID: 94015
Summary: [10 Regression] Another assignment incorrectly omitted
by -foptimize-strlen
Product: gcc
Version: 10.0
Status: UNCONFIRMED
Keywords: wrong-code
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: nate at thatsmathematics dot com
CC: dmalcolm at gcc dot gnu.org, jakub at gcc dot gnu.org,
law at redhat dot com, marxin at gcc dot gnu.org,
msebor at gcc dot gnu.org, nate at thatsmathematics dot com
Target Milestone: ---
Created attachment 47957
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47957&action=edit
Test case
This is apparently the same bug as in bug 93982, which I don't think has been
fixed completely.
I am using trunk, commit 9b4f00dd (not sure how to make that a link?). It
includes f26688fb which was supposed to fix bug 93982. This is again a
regression from 9.2.0.
If the attached testcase is compiled with `-O1 -foptimize-strlen -fpie', or
-O2, on amd64, the function foo is miscompiled: the assignment to s[7] is
omitted. The generated assembly is:
This bug is somewhat similar to bug 93213. It is a regression from 9.2.0.
The generated assembly is:
foo:
subq $8, %rsp
call alloc
leaq .LC0(%rip), %rdx
movq %rdx, (%rax)
addq $8, %rsp
ret
9.2.0 adds `movb $0, 7(%rax)' as it should.
I wasn't able to create a test that failed at runtime on Linux, since by
default everything is loaded in the low half of memory, so the address of the
string literal has zero in its high byte and s[7] gets set to zero anyway. But
the compiler can't know that will happen. There is probably a linker or loader
option to change this, but I could not immediately figure out the correct
incantation. I can try harder if it would help.
-fdump-tree-all shows that the statement is deleted by the strlen pass, as
before. The output of the preceding pass looks like:
foo ()
{
char * s;
<bb 2> [local count: 1073741824]:
s_3 = alloc ();
MEM[(char * *)s_3] = "1234567";
MEM[(char *)s_3 + 7B] = 0;
return;
}
I didn't single step the compiler code this time, but I presume the issue is
that although the strlen pass now knows that the store in `MEM[(char * *)s_3] =
"1234567";' is the size of a pointer (8 bytes), it still thinks those 8 bytes
are the string "1234567\0" rather than its address. So it still thinks it will
result in a null byte stored at `s_3 + 7B`, making the following line
redundant.
More information about the Gcc-bugs
mailing list