}
}
+type junk struct {
+ step int
+}
+
+// flagOverwrite_ssa is intended to reproduce an issue seen where a XOR
+// was scheduled between a compare and branch, clearing flags.
+func flagOverwrite_ssa(s *junk, c int) int {
+ switch {
+ }
+ if '0' <= c && c <= '9' {
+ s.step = 0
+ return 1
+ }
+ if c == 'e' || c == 'E' {
+ s.step = 0
+ return 2
+ }
+ s.step = 0
+ return 3
+}
+
+func testFlagOverwrite() {
+ j := junk{}
+ if got := flagOverwrite_ssa(&j, ' '); got != 3 {
+ println("flagOverwrite_ssa =", got, "wanted 3")
+ failed = true
+ }
+}
+
var failed = false
func main() {
testSwitch()
testFallthrough()
+ testFlagOverwrite()
+
if failed {
panic("failed")
}
// Common regInfo
var (
gp01 = regInfo{inputs: []regMask{}, outputs: gponly}
+ gp01flags = regInfo{inputs: []regMask{}, outputs: gponly, clobbers: flags}
gp11 = regInfo{inputs: []regMask{gpsp}, outputs: gponly, clobbers: flags}
gp11nf = regInfo{inputs: []regMask{gpsp}, outputs: gponly} // nf: no flags clobbered
gp11sb = regInfo{inputs: []regMask{gpspsb}, outputs: gponly}
{name: "MOVLQSX", reg: gp11nf, asm: "MOVLQSX"}, // sign extend arg0 from int32 to int64
{name: "MOVLQZX", reg: gp11nf, asm: "MOVLQZX"}, // zero extend arg0 from int32 to int64
- {name: "MOVBconst", reg: gp01, asm: "MOVB"}, // 8 low bits of auxint
- {name: "MOVWconst", reg: gp01, asm: "MOVW"}, // 16 low bits of auxint
- {name: "MOVLconst", reg: gp01, asm: "MOVL"}, // 32 low bits of auxint
- {name: "MOVQconst", reg: gp01, asm: "MOVQ"}, // auxint
+ // clobbers flags as liblink will rewrite these to XOR reg, reg if the constant is zero
+ // TODO: revisit when issue 12405 is fixed
+ {name: "MOVBconst", reg: gp01flags, asm: "MOVB"}, // 8 low bits of auxint
+ {name: "MOVWconst", reg: gp01flags, asm: "MOVW"}, // 16 low bits of auxint
+ {name: "MOVLconst", reg: gp01flags, asm: "MOVL"}, // 32 low bits of auxint
+ {name: "MOVQconst", reg: gp01flags, asm: "MOVQ"}, // auxint
{name: "CVTSD2SL", reg: fpgp, asm: "CVTSD2SL"}, // convert float64 to int32
{name: "CVTSD2SQ", reg: fpgp, asm: "CVTSD2SQ"}, // convert float64 to int64
name: "MOVBconst",
asm: x86.AMOVB,
reg: regInfo{
+ clobbers: 8589934592, // .FLAGS
outputs: []regMask{
65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
},
name: "MOVWconst",
asm: x86.AMOVW,
reg: regInfo{
+ clobbers: 8589934592, // .FLAGS
outputs: []regMask{
65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
},
name: "MOVLconst",
asm: x86.AMOVL,
reg: regInfo{
+ clobbers: 8589934592, // .FLAGS
outputs: []regMask{
65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
},
name: "MOVQconst",
asm: x86.AMOVQ,
reg: regInfo{
+ clobbers: 8589934592, // .FLAGS
outputs: []regMask{
65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
},