| ; 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]] = !{} |
| ;. |