From bf0d5c8abbe9d4e3a145df29bee8ef2758d01884 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aram=20H=C4=83v=C4=83rneanu?= Date: Fri, 30 May 2014 12:28:01 +0200 Subject: [PATCH] 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. --- sys/src/cmd/6a/lex.c | 1 + sys/src/cmd/6c/6.out.h | 2 ++ sys/src/cmd/6c/peep.c | 2 ++ sys/src/cmd/6c/reg.c | 1 + sys/src/cmd/6c/txt.c | 70 +++++++++++++++++++++++++----------------- sys/src/cmd/6l/optab.c | 1 + 6 files changed, 48 insertions(+), 29 deletions(-) diff --git a/sys/src/cmd/6a/lex.c b/sys/src/cmd/6a/lex.c index f7c4abcd6..b2b6aee44 100644 --- a/sys/src/cmd/6a/lex.c +++ b/sys/src/cmd/6a/lex.c @@ -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, diff --git a/sys/src/cmd/6c/6.out.h b/sys/src/cmd/6c/6.out.h index 0766ea3d2..947e5a5ef 100644 --- a/sys/src/cmd/6c/6.out.h +++ b/sys/src/cmd/6c/6.out.h @@ -698,6 +698,8 @@ enum as ASWAPGS, AMODE, + + AMOVQL, ALAST }; diff --git a/sys/src/cmd/6c/peep.c b/sys/src/cmd/6c/peep.c index 351dc887d..e977b5c1f 100644 --- a/sys/src/cmd/6c/peep.c +++ b/sys/src/cmd/6c/peep.c @@ -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: diff --git a/sys/src/cmd/6c/reg.c b/sys/src/cmd/6c/reg.c index 43e21a4f3..82a32a1db 100644 --- a/sys/src/cmd/6c/reg.c +++ b/sys/src/cmd/6c/reg.c @@ -183,6 +183,7 @@ regopt(Prog *p) case AMOVWLZX: case AMOVWQSX: case AMOVWQZX: + case AMOVQL: case AMOVSS: case AMOVSD: diff --git a/sys/src/cmd/6c/txt.c b/sys/src/cmd/6c/txt.c index e3b9a9ee5..85c4f2a46 100644 --- a/sys/src/cmd/6c/txt.c +++ b/sys/src/cmd/6c/txt.c @@ -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; diff --git a/sys/src/cmd/6l/optab.c b/sys/src/cmd/6l/optab.c index 133bb1d2f..c4243b6ca 100644 --- a/sys/src/cmd/6l/optab.c +++ b/sys/src/cmd/6l/optab.c @@ -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 },