This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug rtl-optimization/67443] [5/6 regression] DSE removes required store instruction
- From: "vogt at linux dot vnet.ibm.com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Wed, 14 Oct 2015 21:32:08 +0000
- Subject: [Bug rtl-optimization/67443] [5/6 regression] DSE removes required store instruction
- Auto-submitted: auto-generated
- References: <bug-67443-4 at http dot gcc dot gnu dot org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67443
--- Comment #8 from Dominik Vogt <vogt at linux dot vnet.ibm.com> ---
Snippet of the assembly code from the test program posted in comment 4:
good compiler:
==============
# r1 is 0x******XX (XX = value to store in the f1 field)
# r3 is the target address (ps)
# r9 is 0x**YYYYYY (YYYYYY = value to store in the f2 field)
l %r2,.L25-.L24(%r13) # r2 := (uint32)0xff000000
stc %r1,0(%r3) # 8-bit-store *(char *)ps := (r1 & 0xff)
# -> ps: XX ** ** **
lr %r1,%r9 # 32-bit-load r1 := r9 -> r1 = 0x**YYYYYY
n %r2,0(%r3) # 32-bit-and r2 := r2 & *(uint32 *)ps
# -> r2 = 0xXX000000
nilh %r1,255 # 16-bit-and of bits 32-47 of r1 with 0x00ff,
i.e.
# it zeroes the top 8 bits -> r1 = 0x00YYYYYY
or %r1,%r2 # 32-bit or r1 := r1 | r2 -> 0xXX00YYYY
st %r1,0(%r3) # 32-bit store *(uint32)ps := r1
# -> ps: XX YY YY YY
.L24:
.L25:
.long -16777216
bad compiler:
=============
The stc instruction is missing, so the resulting structure has a bad value in
f1.
--
This is the modified program I used for debugging, compiled with
$ g++ -O2 -march=z900 -fPIC -std=gnu++11 t67443.cxx
---
#include <stdio.h>
__attribute__ ((noinline)) bool f(void *s) { return s ? true : false; }
int *gt;
struct s_t
{
unsigned f1: 8;
unsigned f2: 24;
};
__attribute__ ((noinline))
bool foo(int a, int **pp, s_t **pps, void *s, int **x)
{
s_t *ps = *pps;
if (!f(x))
return false;
unsigned i = **pp;
volatile register long r2 __asm__ ("r2") = 1;
if (**pp >= 999 && **x < 77)
{
ps->f1 = **x;
ps->f2 = **pp;
}
f(s);
int y;
do { y &= *gt; } while (y != 0);
__asm__ __volatile__ ("" : : : "memory", "r2","r3","r4","r5");
int z;
do { z &= *gt; } while (z != 0);
return i && x && ps && s;
}
int main(void)
{
int i1 = 999;
int *pi1 = &i1;
s_t st;
s_t *pst = &st;
int x = 55;
int *px = &x;
int t = 0;
gt = &t;
foo(1, &pi1, &pst, 0, &px);
fprintf(stderr, "f1 %u, f2 %u\n", (unsigned int)st.f1, (unsigned int)st.f2);
}
---
This prints "55 999" for the good compiler (correct) and "255 999" for the bad
compiler (wrong).