[llvm] 4077882 - [GVN][NFC] Add MSSA checks in tests 2/N (#137814)
via llvm-commits
llvm-commits at lists.llvm.org
Wed May 14 21:59:45 PDT 2025
Author: Madhur Amilkanthwar
Date: 2025-05-15T10:29:41+05:30
New Revision: 40778822f7191d6f10fa36d9036133370a12bd9a
URL: https://github.com/llvm/llvm-project/commit/40778822f7191d6f10fa36d9036133370a12bd9a
DIFF: https://github.com/llvm/llvm-project/commit/40778822f7191d6f10fa36d9036133370a12bd9a.diff
LOG: [GVN][NFC] Add MSSA checks in tests 2/N (#137814)
The previous patch in this series is #130261
Added:
Modified:
llvm/test/Transforms/GVN/phi.ll
llvm/test/Transforms/GVN/pre-compare.ll
llvm/test/Transforms/GVN/readattrs.ll
llvm/test/Transforms/GVN/setjmp.ll
llvm/test/Transforms/GVN/tbaa.ll
llvm/test/Transforms/GVN/vscale.ll
Removed:
################################################################################
diff --git a/llvm/test/Transforms/GVN/phi.ll b/llvm/test/Transforms/GVN/phi.ll
index 5d4f227132a6f..5b607f7559c1b 100644
--- a/llvm/test/Transforms/GVN/phi.ll
+++ b/llvm/test/Transforms/GVN/phi.ll
@@ -1,5 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=gvn < %s | FileCheck %s
+; RUN: opt -S -passes=gvn < %s | FileCheck --check-prefixes=CHECK,MDEP %s
+; RUN: opt -S -passes='gvn<memoryssa;no-memdep>' < %s | FileCheck %s
define i64 @test1(i1 %c, i64 %a, i64 %b) {
@@ -198,3 +199,5 @@ next:
%phi = phi i64 [%a, %merge]
ret i64 %phi
}
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; MDEP: {{.*}}
diff --git a/llvm/test/Transforms/GVN/pre-compare.ll b/llvm/test/Transforms/GVN/pre-compare.ll
index ea8fbce01bd6c..574d40dfb71d5 100644
--- a/llvm/test/Transforms/GVN/pre-compare.ll
+++ b/llvm/test/Transforms/GVN/pre-compare.ll
@@ -1,4 +1,6 @@
-; RUN: opt -passes=gvn -S < %s | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -passes=gvn -S < %s | FileCheck --check-prefixes=CHECK,MDEP %s
+; RUN: opt -passes='gvn<memoryssa;no-memdep>' -S < %s | FileCheck --check-prefixes=CHECK,MSSA %s
; C source:
;
@@ -37,6 +39,28 @@
@.str3 = private unnamed_addr constant [12 x i8] c"step 2: %d\0A\00", align 1
define void @f(i32 %x) noreturn nounwind uwtable ssp {
+; CHECK-LABEL: define void @f(
+; CHECK-SAME: i32 [[X:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], 1
+; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_COND_PREHEADER:.*]], label %[[IF_THEN:.*]]
+; CHECK: [[IF_THEN]]:
+; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[X]], 2
+; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP1]], ptr @.str, ptr @.str1
+; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @puts(ptr [[COND]]) #[[ATTR1:[0-9]+]]
+; CHECK-NEXT: br label %[[FOR_COND_PREHEADER]]
+; CHECK: [[FOR_COND_PREHEADER]]:
+; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i32 [[X]], 2
+; CHECK-NEXT: br label %[[FOR_COND:.*]]
+; CHECK: [[FOR_COND]]:
+; CHECK-NEXT: [[CALL2:%.*]] = tail call i32 @puts(ptr @.str2) #[[ATTR1]]
+; CHECK-NEXT: br i1 [[CMP3]], label %[[FOR_COND_BACKEDGE:.*]], label %[[IF_END5:.*]]
+; CHECK: [[IF_END5]]:
+; CHECK-NEXT: [[CALL6:%.*]] = tail call i32 (ptr, ...) @printf(ptr @.str3, i32 [[X]]) #[[ATTR1]]
+; CHECK-NEXT: br label %[[FOR_COND_BACKEDGE]]
+; CHECK: [[FOR_COND_BACKEDGE]]:
+; CHECK-NEXT: br label %[[FOR_COND]]
+;
entry:
%cmp = icmp eq i32 %x, 1
br i1 %cmp, label %for.cond.preheader, label %if.then
@@ -66,3 +90,6 @@ for.cond.backedge: ; preds = %if.end5, %for.cond
declare i32 @puts(ptr nocapture) nounwind
declare i32 @printf(ptr nocapture, ...) nounwind
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; MDEP: {{.*}}
+; MSSA: {{.*}}
diff --git a/llvm/test/Transforms/GVN/readattrs.ll b/llvm/test/Transforms/GVN/readattrs.ll
index b16c53adc0d4d..be018834014d5 100644
--- a/llvm/test/Transforms/GVN/readattrs.ll
+++ b/llvm/test/Transforms/GVN/readattrs.ll
@@ -1,4 +1,6 @@
-; RUN: opt -passes=gvn -S -o - < %s | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -passes=gvn -S -o - < %s | FileCheck --check-prefixes=CHECK,MDEP %s
+; RUN: opt -passes='gvn<memoryssa;no-memdep>' -S -o - < %s | FileCheck --check-prefixes=CHECK,MSSA %s
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
target triple = "x86_64-unknown-linux-gnu"
@@ -6,12 +8,24 @@ target triple = "x86_64-unknown-linux-gnu"
declare void @use(ptr readonly nocapture)
define i8 @test() {
+; MDEP-LABEL: define i8 @test() {
+; MDEP-NEXT: [[A:%.*]] = alloca i8, align 1
+; MDEP-NEXT: store i8 1, ptr [[A]], align 1
+; MDEP-NEXT: call void @use(ptr [[A]])
+; MDEP-NEXT: ret i8 1
+;
+; MSSA-LABEL: define i8 @test() {
+; MSSA-NEXT: [[A:%.*]] = alloca i8, align 1
+; MSSA-NEXT: store i8 1, ptr [[A]], align 1
+; MSSA-NEXT: call void @use(ptr [[A]])
+; MSSA-NEXT: [[B:%.*]] = load i8, ptr [[A]], align 1
+; MSSA-NEXT: ret i8 [[B]]
+;
%a = alloca i8
store i8 1, ptr %a
call void @use(ptr %a)
%b = load i8, ptr %a
ret i8 %b
-; CHECK-LABEL: define i8 @test(
-; CHECK: call void @use(ptr %a)
-; CHECK-NEXT: ret i8 1
}
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; CHECK: {{.*}}
diff --git a/llvm/test/Transforms/GVN/setjmp.ll b/llvm/test/Transforms/GVN/setjmp.ll
index 07b7028346760..7777038f89cb1 100644
--- a/llvm/test/Transforms/GVN/setjmp.ll
+++ b/llvm/test/Transforms/GVN/setjmp.ll
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -S -passes=gvn < %s | FileCheck %s
-
+; RUN: opt -S -passes=gvn < %s | FileCheck --check-prefixes=CHECK,MDEP %s
+; RUN: opt -S -passes='gvn<memoryssa;no-memdep>' -verify-analysis-invalidation < %s | FileCheck --check-prefixes=CHECK,MSSA %s
declare i32 @setjmp() returns_twice
declare void @longjmp()
declare ptr @malloc(i64)
@@ -38,18 +38,32 @@ if.end:
; We are still allowed to optimize non-volatile accesses to allocas.
define i32 @test_alloca() {
-; CHECK-LABEL: define i32 @test_alloca() {
-; CHECK-NEXT: [[ALLOC:%.*]] = alloca i43, align 8
-; CHECK-NEXT: store i32 10, ptr [[ALLOC]], align 4
-; CHECK-NEXT: [[SJ:%.*]] = call i32 @setjmp()
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[SJ]], 0
-; CHECK-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]
-; CHECK: [[IF_THEN]]:
-; CHECK-NEXT: store i32 20, ptr [[ALLOC]], align 4
-; CHECK-NEXT: call void @longjmp()
-; CHECK-NEXT: unreachable
-; CHECK: [[IF_END]]:
-; CHECK-NEXT: ret i32 10
+; MDEP-LABEL: define i32 @test_alloca() {
+; MDEP-NEXT: [[ALLOC:%.*]] = alloca i43, align 8
+; MDEP-NEXT: store i32 10, ptr [[ALLOC]], align 4
+; MDEP-NEXT: [[SJ:%.*]] = call i32 @setjmp()
+; MDEP-NEXT: [[CMP:%.*]] = icmp eq i32 [[SJ]], 0
+; MDEP-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]
+; MDEP: [[IF_THEN]]:
+; MDEP-NEXT: store i32 20, ptr [[ALLOC]], align 4
+; MDEP-NEXT: call void @longjmp()
+; MDEP-NEXT: unreachable
+; MDEP: [[IF_END]]:
+; MDEP-NEXT: ret i32 10
+;
+; MSSA-LABEL: define i32 @test_alloca() {
+; MSSA-NEXT: [[ALLOC:%.*]] = alloca i43, align 8
+; MSSA-NEXT: store i32 10, ptr [[ALLOC]], align 4
+; MSSA-NEXT: [[SJ:%.*]] = call i32 @setjmp()
+; MSSA-NEXT: [[CMP:%.*]] = icmp eq i32 [[SJ]], 0
+; MSSA-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]
+; MSSA: [[IF_THEN]]:
+; MSSA-NEXT: store i32 20, ptr [[ALLOC]], align 4
+; MSSA-NEXT: call void @longjmp()
+; MSSA-NEXT: unreachable
+; MSSA: [[IF_END]]:
+; MSSA-NEXT: [[RES:%.*]] = load i32, ptr [[ALLOC]], align 4
+; MSSA-NEXT: ret i32 [[RES]]
;
%alloc = alloca i43
store i32 10, ptr %alloc, align 4
diff --git a/llvm/test/Transforms/GVN/tbaa.ll b/llvm/test/Transforms/GVN/tbaa.ll
index b5dd3867bdbc2..366dfeca8b758 100644
--- a/llvm/test/Transforms/GVN/tbaa.ll
+++ b/llvm/test/Transforms/GVN/tbaa.ll
@@ -1,12 +1,20 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -passes=gvn -S < %s | FileCheck %s
+; RUN: opt -passes=gvn -S < %s | FileCheck --check-prefixes=CHECK,MDEP %s
+; RUN: opt -passes='gvn<memoryssa;no-memdep>' -S < %s | FileCheck --check-prefixes=CHECK,MSSA %s
define i32 @test1(ptr %p, ptr %q) {
-; CHECK-LABEL: define i32 @test1(
-; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
-; CHECK-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA0:![0-9]+]]
-; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]]
-; CHECK-NEXT: ret i32 [[C]]
+; MDEP-LABEL: define i32 @test1(
+; MDEP-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; MDEP-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA0:![0-9]+]]
+; MDEP-NEXT: [[C:%.*]] = add i32 [[A]], [[A]]
+; MDEP-NEXT: ret i32 [[C]]
+;
+; MSSA-LABEL: define i32 @test1(
+; MSSA-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; MSSA-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA0:![0-9]+]]
+; MSSA-NEXT: [[B:%.*]] = call i32 @foo(ptr [[P]])
+; MSSA-NEXT: [[C:%.*]] = add i32 [[A]], [[B]]
+; MSSA-NEXT: ret i32 [[C]]
;
%a = call i32 @foo(ptr %p), !tbaa !0
%b = call i32 @foo(ptr %p)
@@ -15,11 +23,18 @@ define i32 @test1(ptr %p, ptr %q) {
}
define i32 @test2(ptr %p, ptr %q) {
-; CHECK-LABEL: define i32 @test2(
-; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
-; CHECK-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA0]]
-; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]]
-; CHECK-NEXT: ret i32 [[C]]
+; MDEP-LABEL: define i32 @test2(
+; MDEP-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; MDEP-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA0]]
+; MDEP-NEXT: [[C:%.*]] = add i32 [[A]], [[A]]
+; MDEP-NEXT: ret i32 [[C]]
+;
+; MSSA-LABEL: define i32 @test2(
+; MSSA-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; MSSA-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA0]]
+; MSSA-NEXT: [[B:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA0]]
+; MSSA-NEXT: [[C:%.*]] = add i32 [[A]], [[B]]
+; MSSA-NEXT: ret i32 [[C]]
;
%a = call i32 @foo(ptr %p), !tbaa !0
%b = call i32 @foo(ptr %p), !tbaa !0
@@ -28,11 +43,18 @@ define i32 @test2(ptr %p, ptr %q) {
}
define i32 @test3(ptr %p, ptr %q) {
-; CHECK-LABEL: define i32 @test3(
-; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
-; CHECK-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA4:![0-9]+]]
-; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]]
-; CHECK-NEXT: ret i32 [[C]]
+; MDEP-LABEL: define i32 @test3(
+; MDEP-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; MDEP-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA4:![0-9]+]]
+; MDEP-NEXT: [[C:%.*]] = add i32 [[A]], [[A]]
+; MDEP-NEXT: ret i32 [[C]]
+;
+; MSSA-LABEL: define i32 @test3(
+; MSSA-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; MSSA-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA4:![0-9]+]]
+; MSSA-NEXT: [[B:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA4]]
+; MSSA-NEXT: [[C:%.*]] = add i32 [[A]], [[B]]
+; MSSA-NEXT: ret i32 [[C]]
;
%a = call i32 @foo(ptr %p), !tbaa !3
%b = call i32 @foo(ptr %p), !tbaa !3
@@ -41,11 +63,18 @@ define i32 @test3(ptr %p, ptr %q) {
}
define i32 @test4(ptr %p, ptr %q) {
-; CHECK-LABEL: define i32 @test4(
-; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
-; CHECK-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA6:![0-9]+]]
-; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]]
-; CHECK-NEXT: ret i32 [[C]]
+; MDEP-LABEL: define i32 @test4(
+; MDEP-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; MDEP-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA6:![0-9]+]]
+; MDEP-NEXT: [[C:%.*]] = add i32 [[A]], [[A]]
+; MDEP-NEXT: ret i32 [[C]]
+;
+; MSSA-LABEL: define i32 @test4(
+; MSSA-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; MSSA-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA6:![0-9]+]]
+; MSSA-NEXT: [[B:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA0]]
+; MSSA-NEXT: [[C:%.*]] = add i32 [[A]], [[B]]
+; MSSA-NEXT: ret i32 [[C]]
;
%a = call i32 @foo(ptr %p), !tbaa !1
%b = call i32 @foo(ptr %p), !tbaa !0
@@ -54,11 +83,18 @@ define i32 @test4(ptr %p, ptr %q) {
}
define i32 @test5(ptr %p, ptr %q) {
-; CHECK-LABEL: define i32 @test5(
-; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
-; CHECK-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA0]]
-; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]]
-; CHECK-NEXT: ret i32 [[C]]
+; MDEP-LABEL: define i32 @test5(
+; MDEP-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; MDEP-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA0]]
+; MDEP-NEXT: [[C:%.*]] = add i32 [[A]], [[A]]
+; MDEP-NEXT: ret i32 [[C]]
+;
+; MSSA-LABEL: define i32 @test5(
+; MSSA-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; MSSA-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA0]]
+; MSSA-NEXT: [[B:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA6]]
+; MSSA-NEXT: [[C:%.*]] = add i32 [[A]], [[B]]
+; MSSA-NEXT: ret i32 [[C]]
;
%a = call i32 @foo(ptr %p), !tbaa !0
%b = call i32 @foo(ptr %p), !tbaa !1
@@ -67,11 +103,18 @@ define i32 @test5(ptr %p, ptr %q) {
}
define i32 @test6(ptr %p, ptr %q) {
-; CHECK-LABEL: define i32 @test6(
-; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
-; CHECK-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA0]]
-; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]]
-; CHECK-NEXT: ret i32 [[C]]
+; MDEP-LABEL: define i32 @test6(
+; MDEP-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; MDEP-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA0]]
+; MDEP-NEXT: [[C:%.*]] = add i32 [[A]], [[A]]
+; MDEP-NEXT: ret i32 [[C]]
+;
+; MSSA-LABEL: define i32 @test6(
+; MSSA-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; MSSA-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA0]]
+; MSSA-NEXT: [[B:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA4]]
+; MSSA-NEXT: [[C:%.*]] = add i32 [[A]], [[B]]
+; MSSA-NEXT: ret i32 [[C]]
;
%a = call i32 @foo(ptr %p), !tbaa !0
%b = call i32 @foo(ptr %p), !tbaa !3
@@ -80,11 +123,18 @@ define i32 @test6(ptr %p, ptr %q) {
}
define i32 @test7(ptr %p, ptr %q) {
-; CHECK-LABEL: define i32 @test7(
-; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
-; CHECK-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA7:![0-9]+]]
-; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]]
-; CHECK-NEXT: ret i32 [[C]]
+; MDEP-LABEL: define i32 @test7(
+; MDEP-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; MDEP-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA7:![0-9]+]]
+; MDEP-NEXT: [[C:%.*]] = add i32 [[A]], [[A]]
+; MDEP-NEXT: ret i32 [[C]]
+;
+; MSSA-LABEL: define i32 @test7(
+; MSSA-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; MSSA-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA7:![0-9]+]]
+; MSSA-NEXT: [[B:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA4]]
+; MSSA-NEXT: [[C:%.*]] = add i32 [[A]], [[B]]
+; MSSA-NEXT: ret i32 [[C]]
;
%a = call i32 @foo(ptr %p), !tbaa !4
%b = call i32 @foo(ptr %p), !tbaa !3
@@ -93,10 +143,18 @@ define i32 @test7(ptr %p, ptr %q) {
}
define i32 @test8(ptr %p, ptr %q) {
-; CHECK-LABEL: define i32 @test8(
-; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
-; CHECK-NEXT: store i32 15, ptr [[P]], align 4
-; CHECK-NEXT: ret i32 0
+; MDEP-LABEL: define i32 @test8(
+; MDEP-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; MDEP-NEXT: store i32 15, ptr [[P]], align 4
+; MDEP-NEXT: ret i32 0
+;
+; MSSA-LABEL: define i32 @test8(
+; MSSA-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; MSSA-NEXT: [[A:%.*]] = load i32, ptr [[Q]], align 4, !tbaa [[TBAA10:![0-9]+]]
+; MSSA-NEXT: store i32 15, ptr [[P]], align 4
+; MSSA-NEXT: [[B:%.*]] = load i32, ptr [[Q]], align 4, !tbaa [[TBAA10]]
+; MSSA-NEXT: [[C:%.*]] = sub i32 [[A]], [[B]]
+; MSSA-NEXT: ret i32 [[C]]
;
; Since we know the location is invariant, we can forward the
; load across the potentially aliasing store.
@@ -109,10 +167,18 @@ define i32 @test8(ptr %p, ptr %q) {
}
define i32 @test9(ptr %p, ptr %q) {
-; CHECK-LABEL: define i32 @test9(
-; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
-; CHECK-NEXT: call void @clobber()
-; CHECK-NEXT: ret i32 0
+; MDEP-LABEL: define i32 @test9(
+; MDEP-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; MDEP-NEXT: call void @clobber()
+; MDEP-NEXT: ret i32 0
+;
+; MSSA-LABEL: define i32 @test9(
+; MSSA-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; MSSA-NEXT: [[A:%.*]] = load i32, ptr [[Q]], align 4, !tbaa [[TBAA10]]
+; MSSA-NEXT: call void @clobber()
+; MSSA-NEXT: [[B:%.*]] = load i32, ptr [[Q]], align 4, !tbaa [[TBAA10]]
+; MSSA-NEXT: [[C:%.*]] = sub i32 [[A]], [[B]]
+; MSSA-NEXT: ret i32 [[C]]
;
; Since we know the location is invariant, we can forward the
; load across the potentially aliasing store (within the call).
@@ -127,11 +193,18 @@ define i32 @test9(ptr %p, ptr %q) {
define i32 @test10(ptr %p, ptr %q) {
; If one access encloses the other, then the merged access is the enclosed one
; and not just the common final access type.
-; CHECK-LABEL: define i32 @test10(
-; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
-; CHECK-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA10:![0-9]+]]
-; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]]
-; CHECK-NEXT: ret i32 [[C]]
+; MDEP-LABEL: define i32 @test10(
+; MDEP-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; MDEP-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA10:![0-9]+]]
+; MDEP-NEXT: [[C:%.*]] = add i32 [[A]], [[A]]
+; MDEP-NEXT: ret i32 [[C]]
+;
+; MSSA-LABEL: define i32 @test10(
+; MSSA-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; MSSA-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA13:![0-9]+]]
+; MSSA-NEXT: [[B:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA17:![0-9]+]]
+; MSSA-NEXT: [[C:%.*]] = add i32 [[A]], [[B]]
+; MSSA-NEXT: ret i32 [[C]]
;
%a = call i32 @foo(ptr %p), !tbaa !15 ; TAG_X_i
%b = call i32 @foo(ptr %p), !tbaa !19 ; TAG_Y_x_i
@@ -165,18 +238,40 @@ declare i32 @foo(ptr) readonly
!9 = !{!"yet another root"}
!10 = !{!"node", !9, i64 1}
;.
-; CHECK: [[TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0}
-; CHECK: [[META1]] = !{!"C", [[META2:![0-9]+]]}
-; CHECK: [[META2]] = !{!"A", [[META3:![0-9]+]]}
-; CHECK: [[META3]] = !{!"tbaa root"}
-; CHECK: [[TBAA4]] = !{[[META5:![0-9]+]], [[META5]], i64 0}
-; CHECK: [[META5]] = !{!"B", [[META2]]}
-; CHECK: [[TBAA6]] = !{[[META2]], [[META2]], i64 0}
-; CHECK: [[TBAA7]] = !{[[META8:![0-9]+]], [[META8]], i64 0}
-; CHECK: [[META8]] = !{!"scalar type", [[META9:![0-9]+]]}
-; CHECK: [[META9]] = !{!"another root"}
-; CHECK: [[TBAA10]] = !{[[META11:![0-9]+]], [[META12:![0-9]+]], i64 0}
-; CHECK: [[META11]] = !{!"struct X", [[META12]], i64 0}
-; CHECK: [[META12]] = !{!"int", [[META13:![0-9]+]], i64 0}
-; CHECK: [[META13]] = !{!"char", [[META3]], i64 0}
+; MDEP: [[TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0}
+; MDEP: [[META1]] = !{!"C", [[META2:![0-9]+]]}
+; MDEP: [[META2]] = !{!"A", [[META3:![0-9]+]]}
+; MDEP: [[META3]] = !{!"tbaa root"}
+; MDEP: [[TBAA4]] = !{[[META5:![0-9]+]], [[META5]], i64 0}
+; MDEP: [[META5]] = !{!"B", [[META2]]}
+; MDEP: [[TBAA6]] = !{[[META2]], [[META2]], i64 0}
+; MDEP: [[TBAA7]] = !{[[META8:![0-9]+]], [[META8]], i64 0}
+; MDEP: [[META8]] = !{!"scalar type", [[META9:![0-9]+]]}
+; MDEP: [[META9]] = !{!"another root"}
+; MDEP: [[TBAA10]] = !{[[META11:![0-9]+]], [[META12:![0-9]+]], i64 0}
+; MDEP: [[META11]] = !{!"struct X", [[META12]], i64 0}
+; MDEP: [[META12]] = !{!"int", [[META13:![0-9]+]], i64 0}
+; MDEP: [[META13]] = !{!"char", [[META3]], i64 0}
+;.
+; MSSA: [[TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0}
+; MSSA: [[META1]] = !{!"C", [[META2:![0-9]+]]}
+; MSSA: [[META2]] = !{!"A", [[META3:![0-9]+]]}
+; MSSA: [[META3]] = !{!"tbaa root"}
+; MSSA: [[TBAA4]] = !{[[META5:![0-9]+]], [[META5]], i64 0}
+; MSSA: [[META5]] = !{!"B", [[META2]]}
+; MSSA: [[TBAA6]] = !{[[META2]], [[META2]], i64 0}
+; MSSA: [[TBAA7]] = !{[[META8:![0-9]+]], [[META8]], i64 0}
+; MSSA: [[META8]] = !{!"scalar type", [[META9:![0-9]+]]}
+; MSSA: [[META9]] = !{!"another root"}
+; MSSA: [[TBAA10]] = !{[[META11:![0-9]+]], [[META11]], i64 0, i64 1}
+; MSSA: [[META11]] = !{!"node", [[META12:![0-9]+]]}
+; MSSA: [[META12]] = !{!"yet another root"}
+; MSSA: [[TBAA13]] = !{[[META14:![0-9]+]], [[META15:![0-9]+]], i64 0}
+; MSSA: [[META14]] = !{!"struct X", [[META15]], i64 0}
+; MSSA: [[META15]] = !{!"int", [[META16:![0-9]+]], i64 0}
+; MSSA: [[META16]] = !{!"char", [[META3]], i64 0}
+; MSSA: [[TBAA17]] = !{[[META18:![0-9]+]], [[META15]], i64 0}
+; MSSA: [[META18]] = !{!"struct Y", [[META14]], i64 0}
;.
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; CHECK: {{.*}}
diff --git a/llvm/test/Transforms/GVN/vscale.ll b/llvm/test/Transforms/GVN/vscale.ll
index d7b07b9891c41..646a67d15d392 100644
--- a/llvm/test/Transforms/GVN/vscale.ll
+++ b/llvm/test/Transforms/GVN/vscale.ll
@@ -1,14 +1,22 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S < %s -passes=gvn,dce | FileCheck %s
+; RUN: opt -S < %s -passes=gvn,dce | FileCheck --check-prefixes=CHECK,MDEP %s
+; RUN: opt -S < %s -passes='gvn<memoryssa;no-memdep>',dce | FileCheck --check-prefixes=CHECK,MSSA %s
; Analyze Load from clobbering Load.
define <vscale x 4 x i32> @load_store_clobber_load(ptr %p) {
-; CHECK-LABEL: @load_store_clobber_load(
-; CHECK-NEXT: [[LOAD1:%.*]] = load <vscale x 4 x i32>, ptr [[P:%.*]], align 16
-; CHECK-NEXT: store <vscale x 4 x i32> zeroinitializer, ptr undef, align 16
-; CHECK-NEXT: [[ADD:%.*]] = add <vscale x 4 x i32> [[LOAD1]], [[LOAD1]]
-; CHECK-NEXT: ret <vscale x 4 x i32> [[ADD]]
+; MDEP-LABEL: @load_store_clobber_load(
+; MDEP-NEXT: [[LOAD1:%.*]] = load <vscale x 4 x i32>, ptr [[P:%.*]], align 16
+; MDEP-NEXT: store <vscale x 4 x i32> zeroinitializer, ptr undef, align 16
+; MDEP-NEXT: [[ADD:%.*]] = add <vscale x 4 x i32> [[LOAD1]], [[LOAD1]]
+; MDEP-NEXT: ret <vscale x 4 x i32> [[ADD]]
+;
+; MSSA-LABEL: @load_store_clobber_load(
+; MSSA-NEXT: [[LOAD1:%.*]] = load <vscale x 4 x i32>, ptr [[P:%.*]], align 16
+; MSSA-NEXT: store <vscale x 4 x i32> zeroinitializer, ptr undef, align 16
+; MSSA-NEXT: [[LOAD2:%.*]] = load <vscale x 4 x i32>, ptr [[P]], align 16
+; MSSA-NEXT: [[ADD:%.*]] = add <vscale x 4 x i32> [[LOAD1]], [[LOAD2]]
+; MSSA-NEXT: ret <vscale x 4 x i32> [[ADD]]
;
%load1 = load <vscale x 4 x i32>, ptr %p
store <vscale x 4 x i32> zeroinitializer, ptr undef
@@ -33,11 +41,18 @@ define <vscale x 4 x i32> @load_store_clobber_load_mayalias(ptr %p, ptr %p2) {
}
define <vscale x 4 x i32> @load_store_clobber_load_noalias(ptr noalias %p, ptr noalias %p2) {
-; CHECK-LABEL: @load_store_clobber_load_noalias(
-; CHECK-NEXT: [[LOAD1:%.*]] = load <vscale x 4 x i32>, ptr [[P:%.*]], align 16
-; CHECK-NEXT: store <vscale x 4 x i32> zeroinitializer, ptr [[P2:%.*]], align 16
-; CHECK-NEXT: [[ADD:%.*]] = add <vscale x 4 x i32> [[LOAD1]], [[LOAD1]]
-; CHECK-NEXT: ret <vscale x 4 x i32> [[ADD]]
+; MDEP-LABEL: @load_store_clobber_load_noalias(
+; MDEP-NEXT: [[LOAD1:%.*]] = load <vscale x 4 x i32>, ptr [[P:%.*]], align 16
+; MDEP-NEXT: store <vscale x 4 x i32> zeroinitializer, ptr [[P2:%.*]], align 16
+; MDEP-NEXT: [[ADD:%.*]] = add <vscale x 4 x i32> [[LOAD1]], [[LOAD1]]
+; MDEP-NEXT: ret <vscale x 4 x i32> [[ADD]]
+;
+; MSSA-LABEL: @load_store_clobber_load_noalias(
+; MSSA-NEXT: [[LOAD1:%.*]] = load <vscale x 4 x i32>, ptr [[P:%.*]], align 16
+; MSSA-NEXT: store <vscale x 4 x i32> zeroinitializer, ptr [[P2:%.*]], align 16
+; MSSA-NEXT: [[LOAD2:%.*]] = load <vscale x 4 x i32>, ptr [[P]], align 16
+; MSSA-NEXT: [[ADD:%.*]] = add <vscale x 4 x i32> [[LOAD1]], [[LOAD2]]
+; MSSA-NEXT: ret <vscale x 4 x i32> [[ADD]]
;
%load1 = load <vscale x 4 x i32>, ptr %p
store <vscale x 4 x i32> zeroinitializer, ptr %p2
@@ -48,11 +63,18 @@ define <vscale x 4 x i32> @load_store_clobber_load_noalias(ptr noalias %p, ptr n
; BasicAA return MayAlias for %gep1,%gep2, could improve as MustAlias.
define i32 @load_clobber_load_gep1(ptr %p) {
-; CHECK-LABEL: @load_clobber_load_gep1(
-; CHECK-NEXT: [[GEP1:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P:%.*]], i64 0, i64 1
-; CHECK-NEXT: [[LOAD1:%.*]] = load i32, ptr [[GEP1]], align 4
-; CHECK-NEXT: [[ADD:%.*]] = add i32 [[LOAD1]], [[LOAD1]]
-; CHECK-NEXT: ret i32 [[ADD]]
+; MDEP-LABEL: @load_clobber_load_gep1(
+; MDEP-NEXT: [[GEP1:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P:%.*]], i64 0, i64 1
+; MDEP-NEXT: [[LOAD1:%.*]] = load i32, ptr [[GEP1]], align 4
+; MDEP-NEXT: [[ADD:%.*]] = add i32 [[LOAD1]], [[LOAD1]]
+; MDEP-NEXT: ret i32 [[ADD]]
+;
+; MSSA-LABEL: @load_clobber_load_gep1(
+; MSSA-NEXT: [[GEP1:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P:%.*]], i64 0, i64 1
+; MSSA-NEXT: [[LOAD1:%.*]] = load i32, ptr [[GEP1]], align 4
+; MSSA-NEXT: [[LOAD2:%.*]] = load i32, ptr [[GEP1]], align 4
+; MSSA-NEXT: [[ADD:%.*]] = add i32 [[LOAD1]], [[LOAD2]]
+; MSSA-NEXT: ret i32 [[ADD]]
;
%gep1 = getelementptr <vscale x 4 x i32>, ptr %p, i64 0, i64 1
%load1 = load i32, ptr %gep1
@@ -132,9 +154,14 @@ define <vscale x 4 x i32> @load_clobber_load_sideeffect(ptr %p) {
; Analyze Load from clobbering Store.
define <vscale x 4 x i32> @store_forward_to_load(ptr %p) {
-; CHECK-LABEL: @store_forward_to_load(
-; CHECK-NEXT: store <vscale x 4 x i32> zeroinitializer, ptr [[P:%.*]], align 16
-; CHECK-NEXT: ret <vscale x 4 x i32> zeroinitializer
+; MDEP-LABEL: @store_forward_to_load(
+; MDEP-NEXT: store <vscale x 4 x i32> zeroinitializer, ptr [[P:%.*]], align 16
+; MDEP-NEXT: ret <vscale x 4 x i32> zeroinitializer
+;
+; MSSA-LABEL: @store_forward_to_load(
+; MSSA-NEXT: store <vscale x 4 x i32> zeroinitializer, ptr [[P:%.*]], align 16
+; MSSA-NEXT: [[LOAD:%.*]] = load <vscale x 4 x i32>, ptr [[P]], align 16
+; MSSA-NEXT: ret <vscale x 4 x i32> [[LOAD]]
;
store <vscale x 4 x i32> zeroinitializer, ptr %p
%load = load <vscale x 4 x i32>, ptr %p
@@ -174,9 +201,15 @@ define i32 @store_clobber_load() {
declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1)
define i32 @memset_clobber_load(ptr %p) {
-; CHECK-LABEL: @memset_clobber_load(
-; CHECK-NEXT: tail call void @llvm.memset.p0.i64(ptr [[P:%.*]], i8 1, i64 200, i1 false)
-; CHECK-NEXT: ret i32 16843009
+; MDEP-LABEL: @memset_clobber_load(
+; MDEP-NEXT: tail call void @llvm.memset.p0.i64(ptr [[P:%.*]], i8 1, i64 200, i1 false)
+; MDEP-NEXT: ret i32 16843009
+;
+; MSSA-LABEL: @memset_clobber_load(
+; MSSA-NEXT: tail call void @llvm.memset.p0.i64(ptr [[P:%.*]], i8 1, i64 200, i1 false)
+; MSSA-NEXT: [[GEP:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P]], i64 0, i64 5
+; MSSA-NEXT: [[LOAD:%.*]] = load i32, ptr [[GEP]], align 4
+; MSSA-NEXT: ret i32 [[LOAD]]
;
tail call void @llvm.memset.p0.i64(ptr %p, i8 1, i64 200, i1 false)
%gep = getelementptr <vscale x 4 x i32>, ptr %p, i64 0, i64 5
@@ -214,15 +247,28 @@ define i32 @memset_clobber_load_nonconst_index(ptr %p, i64 %idx1, i64 %idx2) {
; Load elimination across BBs
define ptr @load_from_alloc_replaced_with_undef() {
-; CHECK-LABEL: @load_from_alloc_replaced_with_undef(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[A:%.*]] = alloca <vscale x 4 x i32>, align 16
-; CHECK-NEXT: br i1 undef, label [[IF_END:%.*]], label [[IF_THEN:%.*]]
-; CHECK: if.then:
-; CHECK-NEXT: store <vscale x 4 x i32> zeroinitializer, ptr [[A]], align 16
-; CHECK-NEXT: br label [[IF_END]]
-; CHECK: if.end:
-; CHECK-NEXT: ret ptr [[A]]
+; MDEP-LABEL: @load_from_alloc_replaced_with_undef(
+; MDEP-NEXT: entry:
+; MDEP-NEXT: [[A:%.*]] = alloca <vscale x 4 x i32>, align 16
+; MDEP-NEXT: br i1 undef, label [[IF_END:%.*]], label [[IF_THEN:%.*]]
+; MDEP: if.then:
+; MDEP-NEXT: store <vscale x 4 x i32> zeroinitializer, ptr [[A]], align 16
+; MDEP-NEXT: br label [[IF_END]]
+; MDEP: if.end:
+; MDEP-NEXT: ret ptr [[A]]
+;
+; MSSA-LABEL: @load_from_alloc_replaced_with_undef(
+; MSSA-NEXT: entry:
+; MSSA-NEXT: [[A:%.*]] = alloca <vscale x 4 x i32>, align 16
+; MSSA-NEXT: [[GEP:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[A]], i64 0, i64 1
+; MSSA-NEXT: [[LOAD:%.*]] = load i32, ptr [[GEP]], align 4
+; MSSA-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[LOAD]], 0
+; MSSA-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
+; MSSA: if.then:
+; MSSA-NEXT: store <vscale x 4 x i32> zeroinitializer, ptr [[A]], align 16
+; MSSA-NEXT: br label [[IF_END]]
+; MSSA: if.end:
+; MSSA-NEXT: ret ptr [[A]]
;
entry:
%a = alloca <vscale x 4 x i32>
@@ -240,16 +286,29 @@ if.end:
}
define i32 @redundant_load_elimination_1(ptr %p) {
-; CHECK-LABEL: @redundant_load_elimination_1(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[GEP:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P:%.*]], i64 1, i64 1
-; CHECK-NEXT: [[LOAD1:%.*]] = load i32, ptr [[GEP]], align 4
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[LOAD1]], 0
-; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
-; CHECK: if.then:
-; CHECK-NEXT: br label [[IF_END]]
-; CHECK: if.end:
-; CHECK-NEXT: ret i32 [[LOAD1]]
+; MDEP-LABEL: @redundant_load_elimination_1(
+; MDEP-NEXT: entry:
+; MDEP-NEXT: [[GEP:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P:%.*]], i64 1, i64 1
+; MDEP-NEXT: [[LOAD1:%.*]] = load i32, ptr [[GEP]], align 4
+; MDEP-NEXT: [[CMP:%.*]] = icmp eq i32 [[LOAD1]], 0
+; MDEP-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+; MDEP: if.then:
+; MDEP-NEXT: br label [[IF_END]]
+; MDEP: if.end:
+; MDEP-NEXT: ret i32 [[LOAD1]]
+;
+; MSSA-LABEL: @redundant_load_elimination_1(
+; MSSA-NEXT: entry:
+; MSSA-NEXT: [[GEP:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P:%.*]], i64 1, i64 1
+; MSSA-NEXT: [[LOAD1:%.*]] = load i32, ptr [[GEP]], align 4
+; MSSA-NEXT: [[CMP:%.*]] = icmp eq i32 [[LOAD1]], 0
+; MSSA-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+; MSSA: if.then:
+; MSSA-NEXT: [[LOAD2:%.*]] = load i32, ptr [[GEP]], align 4
+; MSSA-NEXT: br label [[IF_END]]
+; MSSA: if.end:
+; MSSA-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOAD2]], [[IF_THEN]] ], [ [[LOAD1]], [[ENTRY:%.*]] ]
+; MSSA-NEXT: ret i32 [[RESULT]]
;
entry:
%gep = getelementptr <vscale x 4 x i32>, ptr %p, i64 1, i64 1
@@ -300,17 +359,30 @@ if.else:
}
define void @redundant_load_elimination_zero_index(i1 %c, ptr %p, ptr %q) {
-; CHECK-LABEL: @redundant_load_elimination_zero_index(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[GEP1:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P:%.*]], i64 0, i64 1
-; CHECK-NEXT: store i32 0, ptr [[GEP1]], align 4
-; CHECK-NEXT: store i32 1, ptr [[P]], align 4
-; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
-; CHECK: if.then:
-; CHECK-NEXT: store i32 0, ptr [[Q:%.*]], align 4
-; CHECK-NEXT: ret void
-; CHECK: if.else:
-; CHECK-NEXT: ret void
+; MDEP-LABEL: @redundant_load_elimination_zero_index(
+; MDEP-NEXT: entry:
+; MDEP-NEXT: [[GEP1:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P:%.*]], i64 0, i64 1
+; MDEP-NEXT: store i32 0, ptr [[GEP1]], align 4
+; MDEP-NEXT: store i32 1, ptr [[P]], align 4
+; MDEP-NEXT: br i1 [[C:%.*]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
+; MDEP: if.then:
+; MDEP-NEXT: store i32 0, ptr [[Q:%.*]], align 4
+; MDEP-NEXT: ret void
+; MDEP: if.else:
+; MDEP-NEXT: ret void
+;
+; MSSA-LABEL: @redundant_load_elimination_zero_index(
+; MSSA-NEXT: entry:
+; MSSA-NEXT: [[GEP1:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P:%.*]], i64 0, i64 1
+; MSSA-NEXT: store i32 0, ptr [[GEP1]], align 4
+; MSSA-NEXT: store i32 1, ptr [[P]], align 4
+; MSSA-NEXT: br i1 [[C:%.*]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
+; MSSA: if.then:
+; MSSA-NEXT: [[T:%.*]] = load i32, ptr [[GEP1]], align 4
+; MSSA-NEXT: store i32 [[T]], ptr [[Q:%.*]], align 4
+; MSSA-NEXT: ret void
+; MSSA: if.else:
+; MSSA-NEXT: ret void
;
entry:
%gep1 = getelementptr <vscale x 4 x i32>, ptr %p, i64 0, i64 1
@@ -328,19 +400,34 @@ if.else:
}
define void @redundant_load_elimination_zero_index_1(i1 %c, ptr %p, ptr %q, i64 %i) {
-; CHECK-LABEL: @redundant_load_elimination_zero_index_1(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[J:%.*]] = add i64 [[I:%.*]], 1
-; CHECK-NEXT: [[GEP1:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P:%.*]], i64 0, i64 [[J]]
-; CHECK-NEXT: store i32 0, ptr [[GEP1]], align 4
-; CHECK-NEXT: [[GEP2:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P]], i64 0, i64 [[I]]
-; CHECK-NEXT: store i32 1, ptr [[GEP2]], align 4
-; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
-; CHECK: if.then:
-; CHECK-NEXT: store i32 0, ptr [[Q:%.*]], align 4
-; CHECK-NEXT: ret void
-; CHECK: if.else:
-; CHECK-NEXT: ret void
+; MDEP-LABEL: @redundant_load_elimination_zero_index_1(
+; MDEP-NEXT: entry:
+; MDEP-NEXT: [[J:%.*]] = add i64 [[I:%.*]], 1
+; MDEP-NEXT: [[GEP1:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P:%.*]], i64 0, i64 [[J]]
+; MDEP-NEXT: store i32 0, ptr [[GEP1]], align 4
+; MDEP-NEXT: [[GEP2:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P]], i64 0, i64 [[I]]
+; MDEP-NEXT: store i32 1, ptr [[GEP2]], align 4
+; MDEP-NEXT: br i1 [[C:%.*]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
+; MDEP: if.then:
+; MDEP-NEXT: store i32 0, ptr [[Q:%.*]], align 4
+; MDEP-NEXT: ret void
+; MDEP: if.else:
+; MDEP-NEXT: ret void
+;
+; MSSA-LABEL: @redundant_load_elimination_zero_index_1(
+; MSSA-NEXT: entry:
+; MSSA-NEXT: [[J:%.*]] = add i64 [[I:%.*]], 1
+; MSSA-NEXT: [[GEP1:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P:%.*]], i64 0, i64 [[J]]
+; MSSA-NEXT: store i32 0, ptr [[GEP1]], align 4
+; MSSA-NEXT: [[GEP2:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P]], i64 0, i64 [[I]]
+; MSSA-NEXT: store i32 1, ptr [[GEP2]], align 4
+; MSSA-NEXT: br i1 [[C:%.*]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
+; MSSA: if.then:
+; MSSA-NEXT: [[T:%.*]] = load i32, ptr [[GEP1]], align 4
+; MSSA-NEXT: store i32 [[T]], ptr [[Q:%.*]], align 4
+; MSSA-NEXT: ret void
+; MSSA: if.else:
+; MSSA-NEXT: ret void
;
entry:
%j = add i64 %i, 1
@@ -391,10 +478,15 @@ if.else:
; Different sizes / types
define <vscale x 16 x i8> @load_v16i8_store_v4i32_forward_load(ptr %p, <vscale x 4 x i32> %x) {
-; CHECK-LABEL: @load_v16i8_store_v4i32_forward_load(
-; CHECK-NEXT: store <vscale x 4 x i32> [[X:%.*]], ptr [[P:%.*]], align 16
-; CHECK-NEXT: [[LOAD:%.*]] = bitcast <vscale x 4 x i32> [[X]] to <vscale x 16 x i8>
-; CHECK-NEXT: ret <vscale x 16 x i8> [[LOAD]]
+; MDEP-LABEL: @load_v16i8_store_v4i32_forward_load(
+; MDEP-NEXT: store <vscale x 4 x i32> [[X:%.*]], ptr [[P:%.*]], align 16
+; MDEP-NEXT: [[TMP1:%.*]] = bitcast <vscale x 4 x i32> [[X]] to <vscale x 16 x i8>
+; MDEP-NEXT: ret <vscale x 16 x i8> [[TMP1]]
+;
+; MSSA-LABEL: @load_v16i8_store_v4i32_forward_load(
+; MSSA-NEXT: store <vscale x 4 x i32> [[X:%.*]], ptr [[P:%.*]], align 16
+; MSSA-NEXT: [[LOAD:%.*]] = load <vscale x 16 x i8>, ptr [[P]], align 16
+; MSSA-NEXT: ret <vscale x 16 x i8> [[LOAD]]
;
store <vscale x 4 x i32> %x, ptr %p
%load = load <vscale x 16 x i8>, ptr %p
@@ -402,10 +494,15 @@ define <vscale x 16 x i8> @load_v16i8_store_v4i32_forward_load(ptr %p, <vscale x
}
define <vscale x 4 x float> @load_v4f32_store_v4i32_forward_load(ptr %p, <vscale x 4 x i32> %x) {
-; CHECK-LABEL: @load_v4f32_store_v4i32_forward_load(
-; CHECK-NEXT: store <vscale x 4 x i32> [[X:%.*]], ptr [[P:%.*]], align 16
-; CHECK-NEXT: [[LOAD:%.*]] = bitcast <vscale x 4 x i32> [[X]] to <vscale x 4 x float>
-; CHECK-NEXT: ret <vscale x 4 x float> [[LOAD]]
+; MDEP-LABEL: @load_v4f32_store_v4i32_forward_load(
+; MDEP-NEXT: store <vscale x 4 x i32> [[X:%.*]], ptr [[P:%.*]], align 16
+; MDEP-NEXT: [[TMP1:%.*]] = bitcast <vscale x 4 x i32> [[X]] to <vscale x 4 x float>
+; MDEP-NEXT: ret <vscale x 4 x float> [[TMP1]]
+;
+; MSSA-LABEL: @load_v4f32_store_v4i32_forward_load(
+; MSSA-NEXT: store <vscale x 4 x i32> [[X:%.*]], ptr [[P:%.*]], align 16
+; MSSA-NEXT: [[LOAD:%.*]] = load <vscale x 4 x float>, ptr [[P]], align 16
+; MSSA-NEXT: ret <vscale x 4 x float> [[LOAD]]
;
store <vscale x 4 x i32> %x, ptr %p
%load = load <vscale x 4 x float>, ptr %p
@@ -413,10 +510,15 @@ define <vscale x 4 x float> @load_v4f32_store_v4i32_forward_load(ptr %p, <vscale
}
define <vscale x 4 x float> @load_v4f32_store_v16i8_forward_load(ptr %p, <vscale x 16 x i8> %x) {
-; CHECK-LABEL: @load_v4f32_store_v16i8_forward_load(
-; CHECK-NEXT: store <vscale x 16 x i8> [[X:%.*]], ptr [[P:%.*]], align 16
-; CHECK-NEXT: [[LOAD:%.*]] = bitcast <vscale x 16 x i8> [[X]] to <vscale x 4 x float>
-; CHECK-NEXT: ret <vscale x 4 x float> [[LOAD]]
+; MDEP-LABEL: @load_v4f32_store_v16i8_forward_load(
+; MDEP-NEXT: store <vscale x 16 x i8> [[X:%.*]], ptr [[P:%.*]], align 16
+; MDEP-NEXT: [[TMP1:%.*]] = bitcast <vscale x 16 x i8> [[X]] to <vscale x 4 x float>
+; MDEP-NEXT: ret <vscale x 4 x float> [[TMP1]]
+;
+; MSSA-LABEL: @load_v4f32_store_v16i8_forward_load(
+; MSSA-NEXT: store <vscale x 16 x i8> [[X:%.*]], ptr [[P:%.*]], align 16
+; MSSA-NEXT: [[LOAD:%.*]] = load <vscale x 4 x float>, ptr [[P]], align 16
+; MSSA-NEXT: ret <vscale x 4 x float> [[LOAD]]
;
store <vscale x 16 x i8> %x, ptr %p
%load = load <vscale x 4 x float>, ptr %p
@@ -424,10 +526,15 @@ define <vscale x 4 x float> @load_v4f32_store_v16i8_forward_load(ptr %p, <vscale
}
define <vscale x 4 x i32> @load_v4i32_store_v4f32_forward_load(ptr %p, <vscale x 4 x float> %x) {
-; CHECK-LABEL: @load_v4i32_store_v4f32_forward_load(
-; CHECK-NEXT: store <vscale x 4 x float> [[X:%.*]], ptr [[P:%.*]], align 16
-; CHECK-NEXT: [[LOAD:%.*]] = bitcast <vscale x 4 x float> [[X]] to <vscale x 4 x i32>
-; CHECK-NEXT: ret <vscale x 4 x i32> [[LOAD]]
+; MDEP-LABEL: @load_v4i32_store_v4f32_forward_load(
+; MDEP-NEXT: store <vscale x 4 x float> [[X:%.*]], ptr [[P:%.*]], align 16
+; MDEP-NEXT: [[TMP1:%.*]] = bitcast <vscale x 4 x float> [[X]] to <vscale x 4 x i32>
+; MDEP-NEXT: ret <vscale x 4 x i32> [[TMP1]]
+;
+; MSSA-LABEL: @load_v4i32_store_v4f32_forward_load(
+; MSSA-NEXT: store <vscale x 4 x float> [[X:%.*]], ptr [[P:%.*]], align 16
+; MSSA-NEXT: [[LOAD:%.*]] = load <vscale x 4 x i32>, ptr [[P]], align 16
+; MSSA-NEXT: ret <vscale x 4 x i32> [[LOAD]]
;
store <vscale x 4 x float> %x, ptr %p
%load = load <vscale x 4 x i32>, ptr %p
@@ -494,11 +601,16 @@ define <vscale x 2 x i32> @load_v2i32_store_v4i32_forward_load_offsetc(ptr %p, <
}
define <vscale x 2 x ptr> @load_v2p0_store_v4i32_forward_load(ptr %p, <vscale x 4 x i32> %x) {
-; CHECK-LABEL: @load_v2p0_store_v4i32_forward_load(
-; CHECK-NEXT: store <vscale x 4 x i32> [[X:%.*]], ptr [[P:%.*]], align 16
-; CHECK-NEXT: [[TMP1:%.*]] = bitcast <vscale x 4 x i32> [[X]] to <vscale x 2 x i64>
-; CHECK-NEXT: [[LOAD:%.*]] = inttoptr <vscale x 2 x i64> [[TMP1]] to <vscale x 2 x ptr>
-; CHECK-NEXT: ret <vscale x 2 x ptr> [[LOAD]]
+; MDEP-LABEL: @load_v2p0_store_v4i32_forward_load(
+; MDEP-NEXT: store <vscale x 4 x i32> [[X:%.*]], ptr [[P:%.*]], align 16
+; MDEP-NEXT: [[TMP1:%.*]] = bitcast <vscale x 4 x i32> [[X]] to <vscale x 2 x i64>
+; MDEP-NEXT: [[TMP2:%.*]] = inttoptr <vscale x 2 x i64> [[TMP1]] to <vscale x 2 x ptr>
+; MDEP-NEXT: ret <vscale x 2 x ptr> [[TMP2]]
+;
+; MSSA-LABEL: @load_v2p0_store_v4i32_forward_load(
+; MSSA-NEXT: store <vscale x 4 x i32> [[X:%.*]], ptr [[P:%.*]], align 16
+; MSSA-NEXT: [[LOAD:%.*]] = load <vscale x 2 x ptr>, ptr [[P]], align 16
+; MSSA-NEXT: ret <vscale x 2 x ptr> [[LOAD]]
;
store <vscale x 4 x i32> %x, ptr %p
%load = load <vscale x 2 x ptr>, ptr %p
@@ -506,10 +618,15 @@ define <vscale x 2 x ptr> @load_v2p0_store_v4i32_forward_load(ptr %p, <vscale x
}
define <vscale x 2 x i64> @load_v2i64_store_v2p0_forward_load(ptr %p, <vscale x 2 x ptr> %x) {
-; CHECK-LABEL: @load_v2i64_store_v2p0_forward_load(
-; CHECK-NEXT: store <vscale x 2 x ptr> [[X:%.*]], ptr [[P:%.*]], align 16
-; CHECK-NEXT: [[LOAD:%.*]] = ptrtoint <vscale x 2 x ptr> [[X]] to <vscale x 2 x i64>
-; CHECK-NEXT: ret <vscale x 2 x i64> [[LOAD]]
+; MDEP-LABEL: @load_v2i64_store_v2p0_forward_load(
+; MDEP-NEXT: store <vscale x 2 x ptr> [[X:%.*]], ptr [[P:%.*]], align 16
+; MDEP-NEXT: [[TMP1:%.*]] = ptrtoint <vscale x 2 x ptr> [[X]] to <vscale x 2 x i64>
+; MDEP-NEXT: ret <vscale x 2 x i64> [[TMP1]]
+;
+; MSSA-LABEL: @load_v2i64_store_v2p0_forward_load(
+; MSSA-NEXT: store <vscale x 2 x ptr> [[X:%.*]], ptr [[P:%.*]], align 16
+; MSSA-NEXT: [[LOAD:%.*]] = load <vscale x 2 x i64>, ptr [[P]], align 16
+; MSSA-NEXT: ret <vscale x 2 x i64> [[LOAD]]
;
store <vscale x 2 x ptr> %x, ptr %p
%load = load <vscale x 2 x i64>, ptr %p
@@ -539,9 +656,14 @@ define <16 x i8> @load_v16i8_store_nxv4i32_forward_load(ptr %p, <vscale x 4 x i3
}
define <vscale x 16 x i8> @load_v16i8_store_v4i32_forward_constant(ptr %p) {
-; CHECK-LABEL: @load_v16i8_store_v4i32_forward_constant(
-; CHECK-NEXT: store <vscale x 4 x i32> splat (i32 4), ptr [[P:%.*]], align 16
-; CHECK-NEXT: ret <vscale x 16 x i8> bitcast (<vscale x 4 x i32> splat (i32 4) to <vscale x 16 x i8>)
+; MDEP-LABEL: @load_v16i8_store_v4i32_forward_constant(
+; MDEP-NEXT: store <vscale x 4 x i32> splat (i32 4), ptr [[P:%.*]], align 16
+; MDEP-NEXT: ret <vscale x 16 x i8> bitcast (<vscale x 4 x i32> splat (i32 4) to <vscale x 16 x i8>)
+;
+; MSSA-LABEL: @load_v16i8_store_v4i32_forward_constant(
+; MSSA-NEXT: store <vscale x 4 x i32> splat (i32 4), ptr [[P:%.*]], align 16
+; MSSA-NEXT: [[LOAD:%.*]] = load <vscale x 16 x i8>, ptr [[P]], align 16
+; MSSA-NEXT: ret <vscale x 16 x i8> [[LOAD]]
;
store <vscale x 4 x i32> splat (i32 4), ptr %p
%load = load <vscale x 16 x i8>, ptr %p
@@ -571,35 +693,65 @@ define {<vscale x 16 x i8>} @load_v16i8_store_v4i32_struct_forward_load(ptr %p,
}
define { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } @bigexample({ <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } %a) vscale_range(1,16) {
-; CHECK-LABEL: @bigexample(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[REF_TMP:%.*]] = alloca { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> }, align 16
-; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 -1, ptr nonnull [[REF_TMP]])
-; CHECK-NEXT: [[A_ELT:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } [[A:%.*]], 0
-; CHECK-NEXT: store <vscale x 4 x i32> [[A_ELT]], ptr [[REF_TMP]], align 16
-; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
-; CHECK-NEXT: [[TMP1:%.*]] = shl i64 [[TMP0]], 4
-; CHECK-NEXT: [[REF_TMP_REPACK1:%.*]] = getelementptr inbounds i8, ptr [[REF_TMP]], i64 [[TMP1]]
-; CHECK-NEXT: [[A_ELT2:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } [[A]], 1
-; CHECK-NEXT: store <vscale x 4 x i32> [[A_ELT2]], ptr [[REF_TMP_REPACK1]], align 16
-; CHECK-NEXT: [[TMP3:%.*]] = shl i64 [[TMP0]], 5
-; CHECK-NEXT: [[REF_TMP_REPACK3:%.*]] = getelementptr inbounds i8, ptr [[REF_TMP]], i64 [[TMP3]]
-; CHECK-NEXT: [[A_ELT4:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } [[A]], 2
-; CHECK-NEXT: store <vscale x 4 x i32> [[A_ELT4]], ptr [[REF_TMP_REPACK3]], align 16
-; CHECK-NEXT: [[TMP5:%.*]] = mul i64 [[TMP0]], 48
-; CHECK-NEXT: [[REF_TMP_REPACK5:%.*]] = getelementptr inbounds i8, ptr [[REF_TMP]], i64 [[TMP5]]
-; CHECK-NEXT: [[A_ELT6:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } [[A]], 3
-; CHECK-NEXT: store <vscale x 4 x i32> [[A_ELT6]], ptr [[REF_TMP_REPACK5]], align 16
-; CHECK-NEXT: [[DOTUNPACK:%.*]] = bitcast <vscale x 4 x i32> [[A_ELT]] to <vscale x 16 x i8>
-; CHECK-NEXT: [[TMP6:%.*]] = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } poison, <vscale x 16 x i8> [[DOTUNPACK]], 0
-; CHECK-NEXT: [[DOTUNPACK8:%.*]] = bitcast <vscale x 4 x i32> [[A_ELT2]] to <vscale x 16 x i8>
-; CHECK-NEXT: [[TMP9:%.*]] = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP6]], <vscale x 16 x i8> [[DOTUNPACK8]], 1
-; CHECK-NEXT: [[DOTUNPACK10:%.*]] = bitcast <vscale x 4 x i32> [[A_ELT4]] to <vscale x 16 x i8>
-; CHECK-NEXT: [[TMP12:%.*]] = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP9]], <vscale x 16 x i8> [[DOTUNPACK10]], 2
-; CHECK-NEXT: [[DOTUNPACK12:%.*]] = bitcast <vscale x 4 x i32> [[A_ELT6]] to <vscale x 16 x i8>
-; CHECK-NEXT: [[TMP15:%.*]] = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP12]], <vscale x 16 x i8> [[DOTUNPACK12]], 3
-; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 -1, ptr nonnull [[REF_TMP]])
-; CHECK-NEXT: ret { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP15]]
+; MDEP-LABEL: @bigexample(
+; MDEP-NEXT: entry:
+; MDEP-NEXT: [[REF_TMP:%.*]] = alloca { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> }, align 16
+; MDEP-NEXT: call void @llvm.lifetime.start.p0(i64 -1, ptr nonnull [[REF_TMP]])
+; MDEP-NEXT: [[A_ELT:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } [[A:%.*]], 0
+; MDEP-NEXT: store <vscale x 4 x i32> [[A_ELT]], ptr [[REF_TMP]], align 16
+; MDEP-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
+; MDEP-NEXT: [[TMP1:%.*]] = shl i64 [[TMP0]], 4
+; MDEP-NEXT: [[REF_TMP_REPACK1:%.*]] = getelementptr inbounds i8, ptr [[REF_TMP]], i64 [[TMP1]]
+; MDEP-NEXT: [[A_ELT2:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } [[A]], 1
+; MDEP-NEXT: store <vscale x 4 x i32> [[A_ELT2]], ptr [[REF_TMP_REPACK1]], align 16
+; MDEP-NEXT: [[TMP2:%.*]] = shl i64 [[TMP0]], 5
+; MDEP-NEXT: [[REF_TMP_REPACK3:%.*]] = getelementptr inbounds i8, ptr [[REF_TMP]], i64 [[TMP2]]
+; MDEP-NEXT: [[A_ELT4:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } [[A]], 2
+; MDEP-NEXT: store <vscale x 4 x i32> [[A_ELT4]], ptr [[REF_TMP_REPACK3]], align 16
+; MDEP-NEXT: [[TMP3:%.*]] = mul i64 [[TMP0]], 48
+; MDEP-NEXT: [[REF_TMP_REPACK5:%.*]] = getelementptr inbounds i8, ptr [[REF_TMP]], i64 [[TMP3]]
+; MDEP-NEXT: [[A_ELT6:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } [[A]], 3
+; MDEP-NEXT: store <vscale x 4 x i32> [[A_ELT6]], ptr [[REF_TMP_REPACK5]], align 16
+; MDEP-NEXT: [[TMP4:%.*]] = bitcast <vscale x 4 x i32> [[A_ELT]] to <vscale x 16 x i8>
+; MDEP-NEXT: [[TMP5:%.*]] = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } poison, <vscale x 16 x i8> [[TMP4]], 0
+; MDEP-NEXT: [[TMP6:%.*]] = bitcast <vscale x 4 x i32> [[A_ELT2]] to <vscale x 16 x i8>
+; MDEP-NEXT: [[TMP7:%.*]] = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP5]], <vscale x 16 x i8> [[TMP6]], 1
+; MDEP-NEXT: [[TMP8:%.*]] = bitcast <vscale x 4 x i32> [[A_ELT4]] to <vscale x 16 x i8>
+; MDEP-NEXT: [[TMP9:%.*]] = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP7]], <vscale x 16 x i8> [[TMP8]], 2
+; MDEP-NEXT: [[TMP10:%.*]] = bitcast <vscale x 4 x i32> [[A_ELT6]] to <vscale x 16 x i8>
+; MDEP-NEXT: [[TMP11:%.*]] = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP9]], <vscale x 16 x i8> [[TMP10]], 3
+; MDEP-NEXT: call void @llvm.lifetime.end.p0(i64 -1, ptr nonnull [[REF_TMP]])
+; MDEP-NEXT: ret { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP11]]
+;
+; MSSA-LABEL: @bigexample(
+; MSSA-NEXT: entry:
+; MSSA-NEXT: [[REF_TMP:%.*]] = alloca { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> }, align 16
+; MSSA-NEXT: call void @llvm.lifetime.start.p0(i64 -1, ptr nonnull [[REF_TMP]])
+; MSSA-NEXT: [[A_ELT:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } [[A:%.*]], 0
+; MSSA-NEXT: store <vscale x 4 x i32> [[A_ELT]], ptr [[REF_TMP]], align 16
+; MSSA-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
+; MSSA-NEXT: [[TMP1:%.*]] = shl i64 [[TMP0]], 4
+; MSSA-NEXT: [[REF_TMP_REPACK1:%.*]] = getelementptr inbounds i8, ptr [[REF_TMP]], i64 [[TMP1]]
+; MSSA-NEXT: [[A_ELT2:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } [[A]], 1
+; MSSA-NEXT: store <vscale x 4 x i32> [[A_ELT2]], ptr [[REF_TMP_REPACK1]], align 16
+; MSSA-NEXT: [[TMP2:%.*]] = shl i64 [[TMP0]], 5
+; MSSA-NEXT: [[REF_TMP_REPACK3:%.*]] = getelementptr inbounds i8, ptr [[REF_TMP]], i64 [[TMP2]]
+; MSSA-NEXT: [[A_ELT4:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } [[A]], 2
+; MSSA-NEXT: store <vscale x 4 x i32> [[A_ELT4]], ptr [[REF_TMP_REPACK3]], align 16
+; MSSA-NEXT: [[TMP3:%.*]] = mul i64 [[TMP0]], 48
+; MSSA-NEXT: [[REF_TMP_REPACK5:%.*]] = getelementptr inbounds i8, ptr [[REF_TMP]], i64 [[TMP3]]
+; MSSA-NEXT: [[A_ELT6:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } [[A]], 3
+; MSSA-NEXT: store <vscale x 4 x i32> [[A_ELT6]], ptr [[REF_TMP_REPACK5]], align 16
+; MSSA-NEXT: [[DOTUNPACK:%.*]] = load <vscale x 16 x i8>, ptr [[REF_TMP]], align 16
+; MSSA-NEXT: [[TMP4:%.*]] = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } poison, <vscale x 16 x i8> [[DOTUNPACK]], 0
+; MSSA-NEXT: [[DOTUNPACK8:%.*]] = load <vscale x 16 x i8>, ptr [[REF_TMP_REPACK1]], align 16
+; MSSA-NEXT: [[TMP5:%.*]] = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP4]], <vscale x 16 x i8> [[DOTUNPACK8]], 1
+; MSSA-NEXT: [[DOTUNPACK10:%.*]] = load <vscale x 16 x i8>, ptr [[REF_TMP_REPACK3]], align 16
+; MSSA-NEXT: [[TMP6:%.*]] = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP5]], <vscale x 16 x i8> [[DOTUNPACK10]], 2
+; MSSA-NEXT: [[DOTUNPACK12:%.*]] = load <vscale x 16 x i8>, ptr [[REF_TMP_REPACK5]], align 16
+; MSSA-NEXT: [[TMP7:%.*]] = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP6]], <vscale x 16 x i8> [[DOTUNPACK12]], 3
+; MSSA-NEXT: call void @llvm.lifetime.end.p0(i64 -1, ptr nonnull [[REF_TMP]])
+; MSSA-NEXT: ret { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP7]]
;
entry:
%ref.tmp = alloca { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> }, align 16
@@ -643,12 +795,21 @@ entry:
}
define <vscale x 4 x float> @scalable_store_to_fixed_load(<vscale x 4 x float> %.coerce) vscale_range(4,4) {
-; CHECK-LABEL: @scalable_store_to_fixed_load(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[RETVAL:%.*]] = alloca { <16 x float> }, align 64
-; CHECK-NEXT: [[TMP0:%.*]] = fadd <vscale x 4 x float> [[DOTCOERCE:%.*]], [[DOTCOERCE]]
-; CHECK-NEXT: store <vscale x 4 x float> [[TMP0]], ptr [[RETVAL]], align 16
-; CHECK-NEXT: ret <vscale x 4 x float> [[TMP0]]
+; MDEP-LABEL: @scalable_store_to_fixed_load(
+; MDEP-NEXT: entry:
+; MDEP-NEXT: [[RETVAL:%.*]] = alloca { <16 x float> }, align 64
+; MDEP-NEXT: [[TMP0:%.*]] = fadd <vscale x 4 x float> [[DOTCOERCE:%.*]], [[DOTCOERCE]]
+; MDEP-NEXT: store <vscale x 4 x float> [[TMP0]], ptr [[RETVAL]], align 16
+; MDEP-NEXT: ret <vscale x 4 x float> [[TMP0]]
+;
+; MSSA-LABEL: @scalable_store_to_fixed_load(
+; MSSA-NEXT: entry:
+; MSSA-NEXT: [[RETVAL:%.*]] = alloca { <16 x float> }, align 64
+; MSSA-NEXT: [[TMP0:%.*]] = fadd <vscale x 4 x float> [[DOTCOERCE:%.*]], [[DOTCOERCE]]
+; MSSA-NEXT: store <vscale x 4 x float> [[TMP0]], ptr [[RETVAL]], align 16
+; MSSA-NEXT: [[TMP1:%.*]] = load <16 x float>, ptr [[RETVAL]], align 64
+; MSSA-NEXT: [[CAST_SCALABLE:%.*]] = tail call <vscale x 4 x float> @llvm.vector.insert.nxv4f32.v16f32(<vscale x 4 x float> poison, <16 x float> [[TMP1]], i64 0)
+; MSSA-NEXT: ret <vscale x 4 x float> [[CAST_SCALABLE]]
;
entry:
%retval = alloca { <16 x float> }
@@ -661,11 +822,19 @@ entry:
; Here, only the lower bound for the vscale is known, but this is enough to allow a forward to a load to 16 elements.
define <vscale x 4 x float> @scalable_store_to_fixed_load_only_lower_bound(<vscale x 4 x float> %a) vscale_range(4) {
-; CHECK-LABEL: @scalable_store_to_fixed_load_only_lower_bound(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[RETVAL:%.*]] = alloca { <vscale x 4 x float> }, align 16
-; CHECK-NEXT: store <vscale x 4 x float> [[A:%.*]], ptr [[RETVAL]], align 16
-; CHECK-NEXT: ret <vscale x 4 x float> [[A]]
+; MDEP-LABEL: @scalable_store_to_fixed_load_only_lower_bound(
+; MDEP-NEXT: entry:
+; MDEP-NEXT: [[RETVAL:%.*]] = alloca { <vscale x 4 x float> }, align 16
+; MDEP-NEXT: store <vscale x 4 x float> [[A:%.*]], ptr [[RETVAL]], align 16
+; MDEP-NEXT: ret <vscale x 4 x float> [[A]]
+;
+; MSSA-LABEL: @scalable_store_to_fixed_load_only_lower_bound(
+; MSSA-NEXT: entry:
+; MSSA-NEXT: [[RETVAL:%.*]] = alloca { <vscale x 4 x float> }, align 16
+; MSSA-NEXT: store <vscale x 4 x float> [[A:%.*]], ptr [[RETVAL]], align 16
+; MSSA-NEXT: [[TMP0:%.*]] = load <16 x float>, ptr [[RETVAL]], align 64
+; MSSA-NEXT: [[CAST_SCALABLE:%.*]] = tail call <vscale x 4 x float> @llvm.vector.insert.nxv4f32.v16f32(<vscale x 4 x float> poison, <16 x float> [[TMP0]], i64 0)
+; MSSA-NEXT: ret <vscale x 4 x float> [[CAST_SCALABLE]]
;
entry:
%retval = alloca { <vscale x 4 x float> }
@@ -752,12 +921,19 @@ entry:
; This function does not have a fixed vscale, but the loaded vector is still known
; to be smaller or equal in size compared to the stored vector.
define <4 x float> @scalable_store_to_small_fixed_load(<vscale x 4 x float> %a) {
-; CHECK-LABEL: @scalable_store_to_small_fixed_load(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[PTR:%.*]] = alloca <vscale x 4 x float>, align 16
-; CHECK-NEXT: store <vscale x 4 x float> [[A:%.*]], ptr [[PTR]], align 16
-; CHECK-NEXT: [[TMP0:%.*]] = call <4 x float> @llvm.vector.extract.v4f32.nxv4f32(<vscale x 4 x float> [[A]], i64 0)
-; CHECK-NEXT: ret <4 x float> [[TMP0]]
+; MDEP-LABEL: @scalable_store_to_small_fixed_load(
+; MDEP-NEXT: entry:
+; MDEP-NEXT: [[PTR:%.*]] = alloca <vscale x 4 x float>, align 16
+; MDEP-NEXT: store <vscale x 4 x float> [[A:%.*]], ptr [[PTR]], align 16
+; MDEP-NEXT: [[TMP0:%.*]] = call <4 x float> @llvm.vector.extract.v4f32.nxv4f32(<vscale x 4 x float> [[A]], i64 0)
+; MDEP-NEXT: ret <4 x float> [[TMP0]]
+;
+; MSSA-LABEL: @scalable_store_to_small_fixed_load(
+; MSSA-NEXT: entry:
+; MSSA-NEXT: [[PTR:%.*]] = alloca <vscale x 4 x float>, align 16
+; MSSA-NEXT: store <vscale x 4 x float> [[A:%.*]], ptr [[PTR]], align 16
+; MSSA-NEXT: [[TMP0:%.*]] = load <4 x float>, ptr [[PTR]], align 16
+; MSSA-NEXT: ret <4 x float> [[TMP0]]
;
entry:
%ptr = alloca <vscale x 4 x float>
More information about the llvm-commits
mailing list