This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug rtl-optimization/63475] New: Postreload CSE propagates aliased memory operand
- From: "ubizjak at gmail dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Tue, 07 Oct 2014 18:38:00 +0000
- Subject: [Bug rtl-optimization/63475] New: Postreload CSE propagates aliased memory operand
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63475
Bug ID: 63475
Summary: Postreload CSE propagates aliased memory operand
Product: gcc
Version: 5.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: rtl-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: ubizjak at gmail dot com
Following testcase:
--cut here--
extern void foo (void);
static char aaa = 0;
static char bbb = 0;
void bar (void)
{
char aaa_sav = aaa, bbb_sav = bbb;
aaa = 1;
bbb = 1;
foo ();
aaa = aaa_sav;
bbb = bbb_sav;
}
--cut here--
exposes the problem where posteload CSE eliminates a memory load by propagating
memory load with alignment AND over memory store (also with alignment and).
These two locations alias in the above case, the second store overwrites the
value of the first location.
This problem can be analyzed with a crosscompiler to alpha-linux-gnu and "-O2
-mexplicit-relocs".
This is expanded RTL sequence up to the call:
5: r72:DI=high(`aaa')
6: r76:DI=[r72:DI+low(`aaa')&0xfffffffffffffff8]
7: r77:DI=r72:DI+low(`aaa')
8: r75:QI#0=zero_extract(r76:DI,0x8,r77:DI<<0x3)
9: r73:DI=r75:QI#0
10: r74:DI=r73:DI<<0x38
11: r70:DI=r74:DI>>0x38
12: r78:DI=high(`bbb')
13: r82:DI=[r78:DI+low(`bbb')&0xfffffffffffffff8]
14: r83:DI=r78:DI+low(`bbb')
15: r81:QI#0=zero_extract(r82:DI,0x8,r83:DI<<0x3)
16: r79:DI=r81:QI#0
17: r80:DI=r79:DI<<0x38
18: r71:DI=r80:DI>>0x38
19: r84:DI=high(`aaa')
20: r85:QI=0x1
21: r87:DI=[r84:DI+low(`aaa')&0xfffffffffffffff8]
22: r86:DI=r84:DI+low(`aaa')
23: r87:DI=!0xff<<r86:DI<<0x3&r87:DI
24: r88:DI=zero_extend(r85:QI)<<r86:DI<<0x3
25: r88:DI=r88:DI|r87:DI
26: [r84:DI+low(`aaa')&0xfffffffffffffff8]=r88:DI
27: r89:DI=high(`bbb')
28: r90:QI=0x1
29: r92:DI=[r89:DI+low(`bbb')&0xfffffffffffffff8]
30: r91:DI=r89:DI+low(`bbb')
31: r92:DI=!0xff<<r91:DI<<0x3&r92:DI
32: r93:DI=zero_extend(r90:QI)<<r91:DI<<0x3
33: r93:DI=r93:DI|r92:DI
34: [r89:DI+low(`bbb')&0xfffffffffffffff8]=r93:DI
35: call [`foo'] argc:0
REG_CALL_DECL `foo'
Just before postreload CSE, we have:
5: $13:DI=high(`aaa')
REG_EQUIV high(`aaa')
12: $11:DI=high(`bbb')
REG_EQUIV high(`bbb')
7: $14:DI=$13:DI+low(`aaa')
REG_EQUIV `aaa'
6: $1:DI=[$13:DI+low(`aaa')&0xfffffffffffffff8]
20: $3:QI=0x1
REG_EQUIV 0x1
13: $2:DI=[$11:DI+low(`bbb')&0xfffffffffffffff8]
24: $4:DI=zero_extend($3:QI)<<$14:DI<<0x3
REG_EQUAL 0x1<<`aaa'<<0x3
23: $5:DI=!0xff<<$14:DI<<0x3&$1:DI
14: $12:DI=$11:DI+low(`bbb')
REG_EQUIV `bbb'
25: $4:DI=$4:DI|$5:DI
26: [$13:DI+low(`aaa')&0xfffffffffffffff8]=$4:DI
9: $1:DI=zero_extract($1:DI,0x8,$14:DI<<0x3)
29: $4:DI=[$11:DI+low(`bbb')&0xfffffffffffffff8]
16: $2:DI=zero_extract($2:DI,0x8,$12:DI<<0x3)
10: $1:DI=$1:DI<<0x38
17: $2:DI=$2:DI<<0x38
31: $4:DI=!0xff<<$12:DI<<0x3&$4:DI
32: $3:DI=zero_extend($3:QI)<<$12:DI<<0x3
REG_EQUAL 0x1<<`bbb'<<0x3
11: $9:DI=$1:DI>>0x38
18: $10:DI=$2:DI>>0x38
33: $3:DI=$3:DI|$4:DI
34: [$11:DI+low(`bbb')&0xfffffffffffffff8]=$3:DI
35: call [`foo'] argc:0
REG_CALL_DECL `foo'
Please note (insn 29). The new value of aaa (+ neighborhood) was stored in
(insn 26) and value of bbb (+ aliased neighborhood including value of aaa) is
read. (insn 34) stores both: aliased value of aaa and updated value of bbb.
Here comes postreload CSE:
5: $13:DI=high(`aaa')
REG_EQUIV high(`aaa')
12: $11:DI=high(`bbb')
REG_EQUIV high(`bbb')
7: $14:DI=$13:DI+low(`aaa')
REG_EQUIV `aaa'
6: $1:DI=[$13:DI+low(`aaa')&0xfffffffffffffff8]
20: $3:QI=0x1
REG_EQUIV 0x1
13: $2:DI=[$11:DI+low(`bbb')&0xfffffffffffffff8]
24: $4:DI=zero_extend($3:QI)<<$14:DI<<0x3
REG_EQUAL 0x1<<`aaa'<<0x3
23: $5:DI=!0xff<<$14:DI<<0x3&$1:DI
14: $12:DI=$11:DI+low(`bbb')
REG_EQUIV `bbb'
25: $4:DI=$4:DI|$5:DI
26: [$13:DI+low(`aaa')&0xfffffffffffffff8]=$4:DI
9: $1:DI=zero_extract($1:DI,0x8,$14:DI<<0x3)
29: $4:DI=$2:DI
16: $2:DI=zero_extract($2:DI,0x8,$12:DI<<0x3)
10: $1:DI=$1:DI<<0x38
17: $2:DI=$2:DI<<0x38
31: $4:DI=!0xff<<$12:DI<<0x3&$4:DI
32: $3:DI=zero_extend($3:QI)<<$12:DI<<0x3
REG_EQUAL 0x1<<`bbb'<<0x3
11: $9:DI=$1:DI>>0x38
18: $10:DI=$2:DI>>0x38
33: $3:DI=$3:DI|$4:DI
34: [$11:DI+low(`bbb')&0xfffffffffffffff8]=$3:DI
35: call [`foo'] argc:0
REG_CALL_DECL `foo'
Please again note (insn 29). The propagated value of bbb doesn't include
updated value in the memory location of aaa, as the propagation doesn't mind
aliased store to aaa in (insn 26). As a consequence, the final store in (insn
34) overwrites aliased location of aaa with its original value!