// run | |
// Copyright 2017 The Go Authors. All rights reserved. | |
// Use of this source code is governed by a BSD-style | |
// license that can be found in the LICENSE file. | |
// Issue 21048: s390x merged address generation into stores | |
// to unaligned global variables. This resulted in an illegal | |
// instruction. | |
package main | |
type T struct { | |
_ [1]byte | |
a [2]byte // offset: 1 | |
_ [3]byte | |
b [2]uint16 // offset: 6 | |
_ [2]byte | |
c [2]uint32 // offset: 12 | |
_ [2]byte | |
d [2]int16 // offset: 22 | |
_ [2]byte | |
e [2]int32 // offset: 28 | |
} | |
var Source, Sink T | |
func newT() T { | |
return T{ | |
a: [2]byte{1, 2}, | |
b: [2]uint16{1, 2}, | |
c: [2]uint32{1, 2}, | |
d: [2]int16{1, 2}, | |
e: [2]int32{1, 2}, | |
} | |
} | |
//go:noinline | |
func moves() { | |
Sink.a = Source.a | |
Sink.b = Source.b | |
Sink.c = Source.c | |
Sink.d = Source.d | |
Sink.e = Source.e | |
} | |
//go:noinline | |
func loads() *T { | |
t := newT() | |
t.a = Source.a | |
t.b = Source.b | |
t.c = Source.c | |
t.d = Source.d | |
t.e = Source.e | |
return &t | |
} | |
//go:noinline | |
func stores() { | |
t := newT() | |
Sink.a = t.a | |
Sink.b = t.b | |
Sink.c = t.c | |
Sink.d = t.d | |
Sink.e = t.e | |
} | |
func main() { | |
moves() | |
loads() | |
stores() | |
} |