+
+; Fold a gep offset into a truncating store.
+
+; CHECK-LABEL: store_i8_with_folded_gep_offset:
+; CHECK: i32.store8 $discard=, 24($0), $pop0{{$}}
+define void @store_i8_with_folded_gep_offset(i8* %p) {
+ %s = getelementptr inbounds i8, i8* %p, i32 24
+ store i8 0, i8* %s
+ ret void
+}
+
+; Fold the offsets when lowering aggregate loads and stores.
+
+; CHECK-LABEL: aggregate_load_store:
+; CHECK: i32.load $2=, 0($0){{$}}
+; CHECK: i32.load $3=, 4($0){{$}}
+; CHECK: i32.load $4=, 8($0){{$}}
+; CHECK: i32.load $push0=, 12($0){{$}}
+; CHECK: i32.store $discard=, 12($1), $pop0{{$}}
+; CHECK: i32.store $discard=, 8($1), $4{{$}}
+; CHECK: i32.store $discard=, 4($1), $3{{$}}
+; CHECK: i32.store $discard=, 0($1), $2{{$}}
+define void @aggregate_load_store({i32,i32,i32,i32}* %p, {i32,i32,i32,i32}* %q) {
+ ; volatile so that things stay in order for the tests above
+ %t = load volatile {i32,i32,i32,i32}, {i32, i32,i32,i32}* %p
+ store volatile {i32,i32,i32,i32} %t, {i32, i32,i32,i32}* %q
+ ret void
+}
+
+; Fold the offsets when lowering aggregate return values.
+
+; CHECK-LABEL: aggregate_return:
+; CHECK: i32.const $push0=, 0{{$}}
+; CHECK: i32.store $push1=, 12($0), $pop0{{$}}
+; CHECK: i32.store $push2=, 8($0), $pop1{{$}}
+; CHECK: i32.store $push3=, 4($0), $pop2{{$}}
+; CHECK: i32.store $discard=, 0($0), $pop3{{$}}
+define {i32,i32,i32,i32} @aggregate_return() {
+ ret {i32,i32,i32,i32} zeroinitializer
+}