| // 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() | |
| } |