6a, 6c, 6l: fix copy propagation

Without an explicit signal for a truncation, copy propagation will
sometimes propagate a 32-bit truncation and end up overwriting uses of
the original 64-bit value.

This was independently discovered and fixed in Go. See:
	http://golang.org/issue/1315
	https://codereview.appspot.com/6002043/

Thanks Charles Forsyth for tips and advice.
This commit is contained in:
Aram Hăvărneanu 2014-05-30 12:28:01 +02:00
parent 17d0dea87c
commit bf0d5c8abb
6 changed files with 48 additions and 29 deletions

View file

@ -475,6 +475,7 @@ struct
"MOVLQZX", LTYPE3, AMOVLQZX,
"MOVNTIL", LTYPE3, AMOVNTIL,
"MOVNTIQ", LTYPE3, AMOVNTIQ,
"MOVQL", LTYPE3, AMOVQL,
"MOVWLSX", LTYPE3, AMOVWLSX,
"MOVWLZX", LTYPE3, AMOVWLZX,
"MOVWQSX", LTYPE3, AMOVWQSX,

View file

@ -698,6 +698,8 @@ enum as
ASWAPGS,
AMODE,
AMOVQL,
ALAST
};

View file

@ -404,6 +404,7 @@ subprop(Reg *r0)
case AMOVSL:
case AMOVSQ:
case AMOVQL:
return 0;
case AMOVL:
@ -602,6 +603,7 @@ copyu(Prog *p, Adr *v, Adr *s)
case AMOVWLZX:
case AMOVWQSX:
case AMOVWQZX:
case AMOVQL:
case AMOVSS:
case AMOVSD:

View file

@ -183,6 +183,7 @@ regopt(Prog *p)
case AMOVWLZX:
case AMOVWQSX:
case AMOVWQZX:
case AMOVQL:
case AMOVSS:
case AMOVSD:

View file

@ -767,7 +767,6 @@ gmove(Node *f, Node *t)
case CASE( TUINT, TCHAR):
case CASE( TLONG, TCHAR):
case CASE( TULONG, TCHAR):
case CASE( TIND, TCHAR):
case CASE( TCHAR, TUCHAR):
case CASE( TUCHAR, TUCHAR):
@ -777,7 +776,6 @@ gmove(Node *f, Node *t)
case CASE( TUINT, TUCHAR):
case CASE( TLONG, TUCHAR):
case CASE( TULONG, TUCHAR):
case CASE( TIND, TUCHAR):
case CASE( TSHORT, TSHORT):
case CASE( TUSHORT,TSHORT):
@ -785,7 +783,6 @@ gmove(Node *f, Node *t)
case CASE( TUINT, TSHORT):
case CASE( TLONG, TSHORT):
case CASE( TULONG, TSHORT):
case CASE( TIND, TSHORT):
case CASE( TSHORT, TUSHORT):
case CASE( TUSHORT,TUSHORT):
@ -793,42 +790,26 @@ gmove(Node *f, Node *t)
case CASE( TUINT, TUSHORT):
case CASE( TLONG, TUSHORT):
case CASE( TULONG, TUSHORT):
case CASE( TIND, TUSHORT):
case CASE( TINT, TINT):
case CASE( TUINT, TINT):
case CASE( TLONG, TINT):
case CASE( TULONG, TINT):
case CASE( TIND, TINT):
case CASE( TULONG, TINT)::
case CASE( TINT, TUINT):
case CASE( TUINT, TUINT):
case CASE( TLONG, TUINT):
case CASE( TULONG, TUINT):
case CASE( TIND, TUINT):
case CASE( TUINT, TIND):
case CASE( TVLONG, TUINT):
case CASE( TVLONG, TULONG):
case CASE( TUVLONG, TUINT):
case CASE( TUVLONG, TULONG):
*****/
a = AMOVL;
break;
case CASE( TVLONG, TCHAR):
case CASE( TVLONG, TSHORT):
case CASE( TVLONG, TINT):
case CASE( TVLONG, TLONG):
case CASE( TUVLONG, TCHAR):
case CASE( TUVLONG, TSHORT):
case CASE( TUVLONG, TINT):
case CASE( TUVLONG, TLONG):
case CASE( TINT, TIND):
case CASE( TINT, TVLONG):
case CASE( TINT, TUVLONG):
case CASE( TLONG, TVLONG):
case CASE( TINT, TIND):
case CASE( TLONG, TIND):
case CASE( TLONG, TVLONG):
case CASE( TLONG, TUVLONG):
a = AMOVLQSX;
if(f->op == OCONST) {
f->vconst &= (uvlong)0xffffffffU;
@ -844,22 +825,53 @@ gmove(Node *f, Node *t)
case CASE( TULONG, TVLONG):
case CASE( TULONG, TUVLONG):
case CASE( TULONG, TIND):
a = AMOVL; /* same effect as AMOVLQZX */
a = AMOVLQZX;
if(f->op == OCONST) {
f->vconst &= (uvlong)0xffffffffU;
a = AMOVQ;
}
break;
case CASE( TIND, TCHAR):
case CASE( TIND, TUCHAR):
case CASE( TIND, TSHORT):
case CASE( TIND, TUSHORT):
case CASE( TIND, TINT):
case CASE( TIND, TUINT):
case CASE( TIND, TLONG):
case CASE( TIND, TULONG):
case CASE( TVLONG, TCHAR):
case CASE( TVLONG, TUCHAR):
case CASE( TVLONG, TSHORT):
case CASE( TVLONG, TUSHORT):
case CASE( TVLONG, TINT):
case CASE( TVLONG, TUINT):
case CASE( TVLONG, TLONG):
case CASE( TVLONG, TULONG):
case CASE( TUVLONG, TCHAR):
case CASE( TUVLONG, TUCHAR):
case CASE( TUVLONG, TSHORT):
case CASE( TUVLONG, TUSHORT):
case CASE( TUVLONG, TINT):
case CASE( TUVLONG, TUINT):
case CASE( TUVLONG, TLONG):
case CASE( TUVLONG, TULONG):
a = AMOVQL;
if(f->op == OCONST) {
f->vconst &= 0xffffffffU;
a = AMOVL;
}
break;
case CASE( TIND, TIND):
case CASE( TIND, TVLONG):
case CASE( TVLONG, TVLONG):
case CASE( TUVLONG, TVLONG):
case CASE( TVLONG, TUVLONG):
case CASE( TUVLONG, TUVLONG):
case CASE( TIND, TUVLONG):
case CASE( TVLONG, TIND):
case CASE( TVLONG, TVLONG):
case CASE( TVLONG, TUVLONG):
case CASE( TUVLONG, TIND):
case CASE( TIND, TIND):
case CASE( TUVLONG, TVLONG):
case CASE( TUVLONG, TUVLONG):
a = AMOVQ;
break;

View file

@ -772,6 +772,7 @@ Optab optab[] =
{ AMOVNTPS, yxr_ml, Pm, 0x2b },
{ AMOVNTQ, ymr_ml, Pm, 0xe7 },
{ AMOVQ, ymovq, Pw, 0x89,0x8b,0x31,0xc7,(00),0xb8,0xc7,(00),0x6f,0x7f,0x6e,0x7e,Pf2,0xd6,Pe,0xd6,Pe,0x6e,Pe,0x7e },
{ AMOVQL, yrl_ml, Px, 0x89 },
{ AMOVQOZX, ymrxr, Pf3, 0xd6,0x7e },
{ AMOVSB, ynone, Pb, 0xa4 },
{ AMOVSD, yxmov, Pf2, 0x10,0x11 },