diff options
author | Keith Randall <khr@golang.org> | 2016-09-12 13:47:55 -0700 |
---|---|---|
committer | Keith Randall <khr@golang.org> | 2016-09-12 22:41:03 +0000 |
commit | 6ca7c2055bd114c08426d3dbdee444b280b569b6 (patch) | |
tree | e1a6b9551ef3a50ed17db4fc44e0c1e9a60d9102 /src/cmd/compile/internal/ssa/flagalloc.go | |
parent | e42ae65a85079a9f39d0fb4837a78172ad898d84 (diff) | |
download | go-6ca7c2055bd114c08426d3dbdee444b280b569b6.tar.gz go-6ca7c2055bd114c08426d3dbdee444b280b569b6.zip |
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/29083
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'src/cmd/compile/internal/ssa/flagalloc.go')
-rw-r--r-- | src/cmd/compile/internal/ssa/flagalloc.go | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/src/cmd/compile/internal/ssa/flagalloc.go b/src/cmd/compile/internal/ssa/flagalloc.go index aefa81b5b3..5d1ced42b4 100644 --- a/src/cmd/compile/internal/ssa/flagalloc.go +++ b/src/cmd/compile/internal/ssa/flagalloc.go @@ -31,7 +31,7 @@ func flagalloc(f *Func) { if v == flag { flag = nil } - if opcodeTable[v.Op].clobberFlags { + if v.clobbersFlags() { flag = nil } for _, a := range v.Args { @@ -103,7 +103,7 @@ func flagalloc(f *Func) { } // Issue v. b.Values = append(b.Values, v) - if opcodeTable[v.Op].clobberFlags { + if v.clobbersFlags() { flag = nil } if v.Type.IsFlags() { @@ -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. // If v's arg is also flags, copy recursively. func copyFlags(v *Value, b *Block) *Value { |