aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/flagalloc.go
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2016-09-12 13:47:55 -0700
committerKeith Randall <khr@golang.org>2016-09-12 22:41:03 +0000
commit6ca7c2055bd114c08426d3dbdee444b280b569b6 (patch)
treee1a6b9551ef3a50ed17db4fc44e0c1e9a60d9102 /src/cmd/compile/internal/ssa/flagalloc.go
parente42ae65a85079a9f39d0fb4837a78172ad898d84 (diff)
downloadgo-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.go17
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 {