blob: e425f6ea90123de89a8130b143877695d9e9b84e [file]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -S -passes=vector-combine -data-layout=e-p:64:64 < %s | FileCheck %s --check-prefix=VC
; RUN: opt -S -passes=vector-combine -data-layout=E-p:64:64 < %s | FileCheck %s --check-prefix=VC
; RUN: opt -S -passes='vector-combine,gvn' -data-layout=e-p:64:64 < %s | FileCheck %s --check-prefix=GVN
@g = global <8 x i16> zeroinitializer, align 16
; In the source, the tagged vector store uses @g while the tagged scalar load
; uses a non-zero GEP. Scalarization moves the tagged store to the same uniqued
; constant GEP as the scalar load, across an intervening untagged store.
define i16 @insert_store_invariant_group() {
; VC-LABEL: define i16 @insert_store_invariant_group() {
; VC-NEXT: store i16 1, ptr getelementptr inbounds nuw (i8, ptr @g, i64 2), align 2
; VC-NEXT: store i16 2, ptr getelementptr inbounds nuw (i8, ptr @g, i64 2), align 2
; VC-NEXT: [[R:%.*]] = load i16, ptr getelementptr inbounds nuw (i8, ptr @g, i64 2), align 2, !invariant.group [[META0:![0-9]+]]
; VC-NEXT: ret i16 [[R]]
;
; GVN-LABEL: define i16 @insert_store_invariant_group() {
; GVN-NEXT: store i16 1, ptr getelementptr inbounds nuw (i8, ptr @g, i64 2), align 2
; GVN-NEXT: store i16 2, ptr getelementptr inbounds nuw (i8, ptr @g, i64 2), align 2
; GVN-NEXT: ret i16 2
;
%v = load <8 x i16>, ptr @g, align 2
%v1 = insertelement <8 x i16> %v, i16 1, i32 1
store <8 x i16> %v1, ptr @g, align 2, !invariant.group !0
store i16 2, ptr getelementptr inbounds nuw (i8, ptr @g, i64 2), align 2
%r = load i16, ptr getelementptr inbounds nuw (i8, ptr @g, i64 2), align 2, !invariant.group !0
ret i16 %r
}
; With a non-constant base, scalarization creates a separate GEP. GVN merges it
; with %elt, exposing the invariant.group copied onto the scalar store.
define i16 @insert_store_invariant_group_argument(ptr %p) {
; VC-LABEL: define i16 @insert_store_invariant_group_argument(
; VC-SAME: ptr [[P:%.*]]) {
; VC-NEXT: [[ELT:%.*]] = getelementptr inbounds <8 x i16>, ptr [[P]], i32 0, i32 1
; VC-NEXT: [[TMP0:%.*]] = getelementptr inbounds <8 x i16>, ptr [[P]], i64 0, i64 1
; VC-NEXT: store i16 1, ptr [[TMP0]], align 2
; VC-NEXT: store i16 2, ptr [[ELT]], align 2
; VC-NEXT: [[R:%.*]] = load i16, ptr [[ELT]], align 2, !invariant.group [[META0]]
; VC-NEXT: ret i16 [[R]]
;
; GVN-LABEL: define i16 @insert_store_invariant_group_argument(
; GVN-SAME: ptr [[P:%.*]]) {
; GVN-NEXT: [[ELT:%.*]] = getelementptr inbounds <8 x i16>, ptr [[P]], i32 0, i32 1
; GVN-NEXT: store i16 1, ptr [[ELT]], align 2
; GVN-NEXT: store i16 2, ptr [[ELT]], align 2
; GVN-NEXT: ret i16 2
;
%elt = getelementptr inbounds <8 x i16>, ptr %p, i32 0, i32 1
%v = load <8 x i16>, ptr %p, align 2
%v1 = insertelement <8 x i16> %v, i16 1, i32 1
store <8 x i16> %v1, ptr %p, align 2, !invariant.group !0
store i16 2, ptr %elt, align 2
%r = load i16, ptr %elt, align 2, !invariant.group !0
ret i16 %r
}
!0 = !{}
;.
; VC: [[META0]] = !{}
;.