Commit 6ca7c205 authored by Keith Randall's avatar Keith Randall

cmd/compile: fix tuple-generating flag ops as clobbering flags

If an op generates a tuple, and part of that tuple is of flags type,
then treat the op as clobbering flags.

Normally this doesn't matter because we do:

v1 = ADDS        <int32, flags>
v2 = Select0 v1  <int32>
v3 = Select1 v1  <flags>

And v3 will do the right clobbering of flags.  But in the rare
cases where we issue a tuple-with-flag op and the flag portion
is dead, then we never issue a Select1.  But v1 still clobbers flags,
so we need to respect that.

Fixes builder failure in CL 28950.

Change-Id: I589089fd81aaeaaa9750bb8d85e7b10199aaa002
Reviewed-on: https://go-review.googlesource.com/29083Reviewed-by: default avatarCherry Zhang <cherryyz@google.com>
parent e42ae65a
...@@ -31,7 +31,7 @@ func flagalloc(f *Func) { ...@@ -31,7 +31,7 @@ func flagalloc(f *Func) {
if v == flag { if v == flag {
flag = nil flag = nil
} }
if opcodeTable[v.Op].clobberFlags { if v.clobbersFlags() {
flag = nil flag = nil
} }
for _, a := range v.Args { for _, a := range v.Args {
...@@ -103,7 +103,7 @@ func flagalloc(f *Func) { ...@@ -103,7 +103,7 @@ func flagalloc(f *Func) {
} }
// Issue v. // Issue v.
b.Values = append(b.Values, v) b.Values = append(b.Values, v)
if opcodeTable[v.Op].clobberFlags { if v.clobbersFlags() {
flag = nil flag = nil
} }
if v.Type.IsFlags() { if v.Type.IsFlags() {
...@@ -134,6 +134,19 @@ func flagalloc(f *Func) { ...@@ -134,6 +134,19 @@ func flagalloc(f *Func) {
} }
} }
func (v *Value) clobbersFlags() bool {
if opcodeTable[v.Op].clobberFlags {
return true
}
if v.Type.IsTuple() && (v.Type.FieldType(0).IsFlags() || v.Type.FieldType(1).IsFlags()) {
// This case handles the possibility where a flag value is generated but never used.
// In that case, there's no corresponding Select to overwrite the flags value,
// so we must consider flags clobbered by the tuple-generating instruction.
return true
}
return false
}
// copyFlags copies v (flag generator) into b, returns the copy. // copyFlags copies v (flag generator) into b, returns the copy.
// If v's arg is also flags, copy recursively. // If v's arg is also flags, copy recursively.
func copyFlags(v *Value, b *Block) *Value { func copyFlags(v *Value, b *Block) *Value {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment