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, "MOVLQZX", LTYPE3, AMOVLQZX,
"MOVNTIL", LTYPE3, AMOVNTIL, "MOVNTIL", LTYPE3, AMOVNTIL,
"MOVNTIQ", LTYPE3, AMOVNTIQ, "MOVNTIQ", LTYPE3, AMOVNTIQ,
"MOVQL", LTYPE3, AMOVQL,
"MOVWLSX", LTYPE3, AMOVWLSX, "MOVWLSX", LTYPE3, AMOVWLSX,
"MOVWLZX", LTYPE3, AMOVWLZX, "MOVWLZX", LTYPE3, AMOVWLZX,
"MOVWQSX", LTYPE3, AMOVWQSX, "MOVWQSX", LTYPE3, AMOVWQSX,

View file

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

View file

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

View file

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

View file

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

View file

@ -772,6 +772,7 @@ Optab optab[] =
{ AMOVNTPS, yxr_ml, Pm, 0x2b }, { AMOVNTPS, yxr_ml, Pm, 0x2b },
{ AMOVNTQ, ymr_ml, Pm, 0xe7 }, { 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 }, { 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 }, { AMOVQOZX, ymrxr, Pf3, 0xd6,0x7e },
{ AMOVSB, ynone, Pb, 0xa4 }, { AMOVSB, ynone, Pb, 0xa4 },
{ AMOVSD, yxmov, Pf2, 0x10,0x11 }, { AMOVSD, yxmov, Pf2, 0x10,0x11 },