[llvm] [LV] Pre-commit compressing pattern tests (NFC) (PR #225109)

Benjamin Maxwell via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 21 09:51:06 PDT 2026


https://github.com/MacDue updated https://github.com/llvm/llvm-project/pull/225109

>From 26426ed215488ba1a939150b59a153bee2ed7285 Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Mon, 21 Sep 2026 15:13:47 +0000
Subject: [PATCH 1/2] [LV] Pre-commit compressing pattern tests (NFC)

This patch pre-commits tests for #214491.
---
 .../LoopVectorize/AArch64/compress-idioms.ll  | 110 +++
 .../LoopVectorize/RISCV/compress-idioms.ll    | 108 +++
 .../LoopVectorize/X86/compress-idioms.ll      | 208 ++++++
 .../compress-idioms-negative-tests.ll         | 268 +++++++
 .../LoopVectorize/compress-idioms.ll          | 679 ++++++++++++++++++
 .../compress-store-vec-epilogue.ll            |  54 ++
 6 files changed, 1427 insertions(+)
 create mode 100644 llvm/test/Transforms/LoopVectorize/AArch64/compress-idioms.ll
 create mode 100644 llvm/test/Transforms/LoopVectorize/RISCV/compress-idioms.ll
 create mode 100644 llvm/test/Transforms/LoopVectorize/X86/compress-idioms.ll
 create mode 100644 llvm/test/Transforms/LoopVectorize/compress-idioms-negative-tests.ll
 create mode 100644 llvm/test/Transforms/LoopVectorize/compress-idioms.ll
 create mode 100644 llvm/test/Transforms/LoopVectorize/compress-store-vec-epilogue.ll

diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/compress-idioms.ll b/llvm/test/Transforms/LoopVectorize/AArch64/compress-idioms.ll
new file mode 100644
index 0000000000000..2a0b26b991dcc
--- /dev/null
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/compress-idioms.ll
@@ -0,0 +1,110 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --filter-out-after "^scalar.ph:" --version 5
+; RUN: opt < %s -mtriple=aarch64 -mattr=+sve2p2 -passes=loop-vectorize -S 2>&1 | FileCheck %s
+
+; SVE compresstore/expandload vectorization (requires +sve2p2 for expandload and +sve for compresstore).
+
+define void @compress_store(ptr writeonly noalias %dst, ptr readonly %src, i32 %c, i64 %n) {
+; CHECK-LABEL: define void @compress_store(
+; CHECK-SAME: ptr noalias writeonly [[DST:%.*]], ptr readonly [[SRC:%.*]], i32 [[C:%.*]], i64 [[N:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[FOR_BODY:.*]]
+; CHECK:       [[FOR_BODY]]:
+; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[FOR_INC:.*]] ]
+; CHECK-NEXT:    [[IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IDX_1:%.*]], %[[FOR_INC]] ]
+; CHECK-NEXT:    [[SRC_PTR:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[IV]]
+; CHECK-NEXT:    [[LOAD_SRC:%.*]] = load i32, ptr [[SRC_PTR]], align 4
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[LOAD_SRC]], [[C]]
+; CHECK-NEXT:    br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[FOR_INC]]
+; CHECK:       [[IF_THEN]]:
+; CHECK-NEXT:    [[DST_PTR:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IDX]]
+; CHECK-NEXT:    store i32 [[LOAD_SRC]], ptr [[DST_PTR]], align 4
+; CHECK-NEXT:    [[IDX_NEXT:%.*]] = add nsw i64 [[IDX]], 1
+; CHECK-NEXT:    br label %[[FOR_INC]]
+; CHECK:       [[FOR_INC]]:
+; CHECK-NEXT:    [[IDX_1]] = phi i64 [ [[IDX_NEXT]], %[[IF_THEN]] ], [ [[IDX]], %[[FOR_BODY]] ]
+; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
+; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
+; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[FOR_BODY]]
+; CHECK:       [[EXIT]]:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
+  %idx = phi i64 [ 0, %entry ], [ %idx.1, %for.inc ]
+  %src.ptr = getelementptr inbounds i32, ptr %src, i64 %iv
+  %load.src = load i32, ptr %src.ptr, align 4
+  %cmp = icmp slt i32 %load.src, %c
+  br i1 %cmp, label %if.then, label %for.inc
+
+if.then:
+  %dst.ptr = getelementptr inbounds i32, ptr %dst, i64 %idx
+  store i32 %load.src, ptr %dst.ptr, align 4
+  %idx.next = add nsw i64 %idx, 1
+  br label %for.inc
+
+for.inc:
+  %idx.1 = phi i64 [ %idx.next, %if.then ], [ %idx, %for.body ]
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, %n
+  br i1 %exitcond.not, label %exit, label %for.body
+
+exit:
+  ret void
+}
+
+define void @expand_load(ptr noalias %dst, ptr readonly %src, i32 %c, i64 %n) {
+; CHECK-LABEL: define void @expand_load(
+; CHECK-SAME: ptr noalias [[DST:%.*]], ptr readonly [[SRC:%.*]], i32 [[C:%.*]], i64 [[N:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[FOR_BODY:.*]]
+; CHECK:       [[FOR_BODY]]:
+; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[FOR_INC:.*]] ]
+; CHECK-NEXT:    [[IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IDX_1:%.*]], %[[FOR_INC]] ]
+; CHECK-NEXT:    [[DST_PTR:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]]
+; CHECK-NEXT:    [[LOAD_DST:%.*]] = load i32, ptr [[DST_PTR]], align 4
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[LOAD_DST]], [[C]]
+; CHECK-NEXT:    br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[FOR_INC]]
+; CHECK:       [[IF_THEN]]:
+; CHECK-NEXT:    [[SRC_PTR:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[IDX]]
+; CHECK-NEXT:    [[LOAD_SRC:%.*]] = load i32, ptr [[SRC_PTR]], align 4
+; CHECK-NEXT:    store i32 [[LOAD_SRC]], ptr [[DST_PTR]], align 4
+; CHECK-NEXT:    [[IDX_NEXT:%.*]] = add nsw i64 [[IDX]], 1
+; CHECK-NEXT:    br label %[[FOR_INC]]
+; CHECK:       [[FOR_INC]]:
+; CHECK-NEXT:    [[IDX_1]] = phi i64 [ [[IDX_NEXT]], %[[IF_THEN]] ], [ [[IDX]], %[[FOR_BODY]] ]
+; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
+; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
+; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[FOR_BODY]]
+; CHECK:       [[EXIT]]:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
+  %idx = phi i64 [ 0, %entry ], [ %idx.1, %for.inc ]
+  %dst.ptr = getelementptr inbounds i32, ptr %dst, i64 %iv
+  %load.dst = load i32, ptr %dst.ptr, align 4
+  %cmp = icmp slt i32 %load.dst, %c
+  br i1 %cmp, label %if.then, label %for.inc
+
+if.then:
+  %src.ptr = getelementptr inbounds i32, ptr %src, i64 %idx
+  %load.src = load i32, ptr %src.ptr, align 4
+  store i32 %load.src, ptr %dst.ptr, align 4
+  %idx.next = add nsw i64 %idx, 1
+  br label %for.inc
+
+for.inc:
+  %idx.1 = phi i64 [ %idx.next, %if.then ], [ %idx, %for.body ]
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, %n
+  br i1 %exitcond.not, label %exit, label %for.body
+
+exit:
+  ret void
+}
diff --git a/llvm/test/Transforms/LoopVectorize/RISCV/compress-idioms.ll b/llvm/test/Transforms/LoopVectorize/RISCV/compress-idioms.ll
new file mode 100644
index 0000000000000..1b4f36d8e4e11
--- /dev/null
+++ b/llvm/test/Transforms/LoopVectorize/RISCV/compress-idioms.ll
@@ -0,0 +1,108 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --filter-out-after "^scalar.ph:" --version 5
+; RUN: opt < %s -mtriple=riscv64 -mattr=+v -passes=loop-vectorize -S 2>&1 | FileCheck %s
+
+define void @compress_store(ptr writeonly noalias %dst, ptr readonly %src, i32 %c, i64 %n) {
+; CHECK-LABEL: define void @compress_store(
+; CHECK-SAME: ptr noalias writeonly [[DST:%.*]], ptr readonly [[SRC:%.*]], i32 [[C:%.*]], i64 [[N:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:  [[VECTOR_PH:.*]]:
+; CHECK-NEXT:    br label %[[FOR_BODY:.*]]
+; CHECK:       [[FOR_BODY]]:
+; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[IV_NEXT:%.*]], %[[FOR_INC:.*]] ]
+; CHECK-NEXT:    [[IDX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[IDX_1:%.*]], %[[FOR_INC]] ]
+; CHECK-NEXT:    [[SRC_PTR:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[IV]]
+; CHECK-NEXT:    [[LOAD_SRC:%.*]] = load i32, ptr [[SRC_PTR]], align 4
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[LOAD_SRC]], [[C]]
+; CHECK-NEXT:    br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[FOR_INC]]
+; CHECK:       [[IF_THEN]]:
+; CHECK-NEXT:    [[DST_PTR:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IDX]]
+; CHECK-NEXT:    store i32 [[LOAD_SRC]], ptr [[DST_PTR]], align 4
+; CHECK-NEXT:    [[IDX_NEXT:%.*]] = add nsw i64 [[IDX]], 1
+; CHECK-NEXT:    br label %[[FOR_INC]]
+; CHECK:       [[FOR_INC]]:
+; CHECK-NEXT:    [[IDX_1]] = phi i64 [ [[IDX_NEXT]], %[[IF_THEN]] ], [ [[IDX]], %[[FOR_BODY]] ]
+; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
+; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
+; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[FOR_BODY]]
+; CHECK:       [[EXIT]]:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
+  %idx = phi i64 [ 0, %entry ], [ %idx.1, %for.inc ]
+  %src.ptr = getelementptr inbounds i32, ptr %src, i64 %iv
+  %load.src = load i32, ptr %src.ptr, align 4
+  %cmp = icmp slt i32 %load.src, %c
+  br i1 %cmp, label %if.then, label %for.inc
+
+if.then:
+  %dst.ptr = getelementptr inbounds i32, ptr %dst, i64 %idx
+  store i32 %load.src, ptr %dst.ptr, align 4
+  %idx.next = add nsw i64 %idx, 1
+  br label %for.inc
+
+for.inc:
+  %idx.1 = phi i64 [ %idx.next, %if.then ], [ %idx, %for.body ]
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, %n
+  br i1 %exitcond.not, label %exit, label %for.body
+
+exit:
+  ret void
+}
+
+define void @expand_load(ptr noalias %dst, ptr readonly %src, i32 %c, i64 %n) {
+; CHECK-LABEL: define void @expand_load(
+; CHECK-SAME: ptr noalias [[DST:%.*]], ptr readonly [[SRC:%.*]], i32 [[C:%.*]], i64 [[N:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:  [[IF_THEN:.*]]:
+; CHECK-NEXT:    br label %[[FOR_INC:.*]]
+; CHECK:       [[FOR_INC]]:
+; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[IF_THEN]] ], [ [[IV_NEXT:%.*]], %[[MIDDLE_BLOCK:.*]] ]
+; CHECK-NEXT:    [[CONDITIONAL_IV:%.*]] = phi i64 [ 0, %[[IF_THEN]] ], [ [[IDX_1:%.*]], %[[MIDDLE_BLOCK]] ]
+; CHECK-NEXT:    [[DST_PTR:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]]
+; CHECK-NEXT:    [[LOAD_DST:%.*]] = load i32, ptr [[DST_PTR]], align 4
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[LOAD_DST]], [[C]]
+; CHECK-NEXT:    br i1 [[CMP]], label %[[IF_THEN1:.*]], label %[[MIDDLE_BLOCK]]
+; CHECK:       [[IF_THEN1]]:
+; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[CONDITIONAL_IV]]
+; CHECK-NEXT:    [[LOAD_SRC:%.*]] = load i32, ptr [[TMP3]], align 4
+; CHECK-NEXT:    store i32 [[LOAD_SRC]], ptr [[DST_PTR]], align 4
+; CHECK-NEXT:    [[IDX_NEXT:%.*]] = add nsw i64 [[CONDITIONAL_IV]], 1
+; CHECK-NEXT:    br label %[[MIDDLE_BLOCK]]
+; CHECK:       [[MIDDLE_BLOCK]]:
+; CHECK-NEXT:    [[IDX_1]] = phi i64 [ [[IDX_NEXT]], %[[IF_THEN1]] ], [ [[CONDITIONAL_IV]], %[[FOR_INC]] ]
+; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
+; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
+; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label %[[FOR_BODY:.*]], label %[[FOR_INC]]
+; CHECK:       [[FOR_BODY]]:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
+  %idx = phi i64 [ 0, %entry ], [ %idx.1, %for.inc ]
+  %dst.ptr = getelementptr inbounds i32, ptr %dst, i64 %iv
+  %load.dst = load i32, ptr %dst.ptr, align 4
+  %cmp = icmp slt i32 %load.dst, %c
+  br i1 %cmp, label %if.then, label %for.inc
+
+if.then:
+  %src.ptr = getelementptr inbounds i32, ptr %src, i64 %idx
+  %load.src = load i32, ptr %src.ptr, align 4
+  store i32 %load.src, ptr %dst.ptr, align 4
+  %idx.next = add nsw i64 %idx, 1
+  br label %for.inc
+
+for.inc:
+  %idx.1 = phi i64 [ %idx.next, %if.then ], [ %idx, %for.body ]
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, %n
+  br i1 %exitcond.not, label %exit, label %for.body
+
+exit:
+  ret void
+}
diff --git a/llvm/test/Transforms/LoopVectorize/X86/compress-idioms.ll b/llvm/test/Transforms/LoopVectorize/X86/compress-idioms.ll
new file mode 100644
index 0000000000000..360392a834c2b
--- /dev/null
+++ b/llvm/test/Transforms/LoopVectorize/X86/compress-idioms.ll
@@ -0,0 +1,208 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --filter-out-after "^scalar.ph:" --version 5
+; RUN: opt < %s -mtriple=x86_64-- -mcpu=x86-64-v4 -passes=loop-vectorize -S 2>&1 | FileCheck %s --check-prefix=CHECK-V4
+; RUN: opt < %s -mtriple=x86_64-- -mcpu=icelake-server -passes=loop-vectorize -S 2>&1 | FileCheck %s --check-prefix=CHECK-ICELAKE
+; RUN: opt < %s -mtriple=x86_64-- -mcpu=znver4 -passes=loop-vectorize -S 2>&1 | FileCheck %s --check-prefix=CHECK-ZNVER4
+
+define void @compress_store(ptr writeonly noalias %dst, ptr readonly %src, i32 %c, i64 %n) {
+; CHECK-V4-LABEL: define void @compress_store(
+; CHECK-V4-SAME: ptr noalias writeonly [[DST:%.*]], ptr readonly [[SRC:%.*]], i32 [[C:%.*]], i64 [[N:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-V4-NEXT:  [[ENTRY:.*]]:
+; CHECK-V4-NEXT:    br label %[[FOR_BODY:.*]]
+; CHECK-V4:       [[FOR_BODY]]:
+; CHECK-V4-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[FOR_INC:.*]] ]
+; CHECK-V4-NEXT:    [[IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IDX_1:%.*]], %[[FOR_INC]] ]
+; CHECK-V4-NEXT:    [[SRC_PTR:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[IV]]
+; CHECK-V4-NEXT:    [[LOAD_SRC:%.*]] = load i32, ptr [[SRC_PTR]], align 4
+; CHECK-V4-NEXT:    [[CMP:%.*]] = icmp slt i32 [[LOAD_SRC]], [[C]]
+; CHECK-V4-NEXT:    br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[FOR_INC]]
+; CHECK-V4:       [[IF_THEN]]:
+; CHECK-V4-NEXT:    [[DST_PTR:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IDX]]
+; CHECK-V4-NEXT:    store i32 [[LOAD_SRC]], ptr [[DST_PTR]], align 4
+; CHECK-V4-NEXT:    [[IDX_NEXT:%.*]] = add nsw i64 [[IDX]], 1
+; CHECK-V4-NEXT:    br label %[[FOR_INC]]
+; CHECK-V4:       [[FOR_INC]]:
+; CHECK-V4-NEXT:    [[IDX_1]] = phi i64 [ [[IDX_NEXT]], %[[IF_THEN]] ], [ [[IDX]], %[[FOR_BODY]] ]
+; CHECK-V4-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
+; CHECK-V4-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
+; CHECK-V4-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[FOR_BODY]]
+; CHECK-V4:       [[EXIT]]:
+; CHECK-V4-NEXT:    ret void
+;
+; CHECK-ICELAKE-LABEL: define void @compress_store(
+; CHECK-ICELAKE-SAME: ptr noalias writeonly [[DST:%.*]], ptr readonly [[SRC:%.*]], i32 [[C:%.*]], i64 [[N:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-ICELAKE-NEXT:  [[ENTRY:.*]]:
+; CHECK-ICELAKE-NEXT:    br label %[[FOR_BODY:.*]]
+; CHECK-ICELAKE:       [[FOR_BODY]]:
+; CHECK-ICELAKE-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[FOR_INC:.*]] ]
+; CHECK-ICELAKE-NEXT:    [[IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IDX_1:%.*]], %[[FOR_INC]] ]
+; CHECK-ICELAKE-NEXT:    [[SRC_PTR:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[IV]]
+; CHECK-ICELAKE-NEXT:    [[LOAD_SRC:%.*]] = load i32, ptr [[SRC_PTR]], align 4
+; CHECK-ICELAKE-NEXT:    [[CMP:%.*]] = icmp slt i32 [[LOAD_SRC]], [[C]]
+; CHECK-ICELAKE-NEXT:    br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[FOR_INC]]
+; CHECK-ICELAKE:       [[IF_THEN]]:
+; CHECK-ICELAKE-NEXT:    [[DST_PTR:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IDX]]
+; CHECK-ICELAKE-NEXT:    store i32 [[LOAD_SRC]], ptr [[DST_PTR]], align 4
+; CHECK-ICELAKE-NEXT:    [[IDX_NEXT:%.*]] = add nsw i64 [[IDX]], 1
+; CHECK-ICELAKE-NEXT:    br label %[[FOR_INC]]
+; CHECK-ICELAKE:       [[FOR_INC]]:
+; CHECK-ICELAKE-NEXT:    [[IDX_1]] = phi i64 [ [[IDX_NEXT]], %[[IF_THEN]] ], [ [[IDX]], %[[FOR_BODY]] ]
+; CHECK-ICELAKE-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
+; CHECK-ICELAKE-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
+; CHECK-ICELAKE-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[FOR_BODY]]
+; CHECK-ICELAKE:       [[EXIT]]:
+; CHECK-ICELAKE-NEXT:    ret void
+;
+; CHECK-ZNVER4-LABEL: define void @compress_store(
+; CHECK-ZNVER4-SAME: ptr noalias writeonly [[DST:%.*]], ptr readonly [[SRC:%.*]], i32 [[C:%.*]], i64 [[N:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-ZNVER4-NEXT:  [[VECTOR_PH:.*]]:
+; CHECK-ZNVER4-NEXT:    br label %[[VECTOR_BODY:.*]]
+; CHECK-ZNVER4:       [[VECTOR_BODY]]:
+; CHECK-ZNVER4-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[IV_NEXT:%.*]], %[[MIDDLE_BLOCK:.*]] ]
+; CHECK-ZNVER4-NEXT:    [[CONDITIONAL_IV:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[IDX_1:%.*]], %[[MIDDLE_BLOCK]] ]
+; CHECK-ZNVER4-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[INDEX]]
+; CHECK-ZNVER4-NEXT:    [[LOAD_SRC:%.*]] = load i32, ptr [[TMP1]], align 4
+; CHECK-ZNVER4-NEXT:    [[CMP:%.*]] = icmp slt i32 [[LOAD_SRC]], [[C]]
+; CHECK-ZNVER4-NEXT:    br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[MIDDLE_BLOCK]]
+; CHECK-ZNVER4:       [[IF_THEN]]:
+; CHECK-ZNVER4-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[CONDITIONAL_IV]]
+; CHECK-ZNVER4-NEXT:    store i32 [[LOAD_SRC]], ptr [[TMP3]], align 4
+; CHECK-ZNVER4-NEXT:    [[IDX_NEXT:%.*]] = add nsw i64 [[CONDITIONAL_IV]], 1
+; CHECK-ZNVER4-NEXT:    br label %[[MIDDLE_BLOCK]]
+; CHECK-ZNVER4:       [[MIDDLE_BLOCK]]:
+; CHECK-ZNVER4-NEXT:    [[IDX_1]] = phi i64 [ [[IDX_NEXT]], %[[IF_THEN]] ], [ [[CONDITIONAL_IV]], %[[VECTOR_BODY]] ]
+; CHECK-ZNVER4-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[INDEX]], 1
+; CHECK-ZNVER4-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
+; CHECK-ZNVER4-NEXT:    br i1 [[EXITCOND_NOT]], label %[[SCALAR_PH:.*]], label %[[VECTOR_BODY]]
+; CHECK-ZNVER4:       [[SCALAR_PH]]:
+; CHECK-ZNVER4-NEXT:    ret void
+;
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
+  %idx = phi i64 [ 0, %entry ], [ %idx.1, %for.inc ]
+  %src.ptr = getelementptr inbounds i32, ptr %src, i64 %iv
+  %load.src = load i32, ptr %src.ptr, align 4
+  %cmp = icmp slt i32 %load.src, %c
+  br i1 %cmp, label %if.then, label %for.inc
+
+if.then:
+  %dst.ptr = getelementptr inbounds i32, ptr %dst, i64 %idx
+  store i32 %load.src, ptr %dst.ptr, align 4
+  %idx.next = add nsw i64 %idx, 1
+  br label %for.inc
+
+for.inc:
+  %idx.1 = phi i64 [ %idx.next, %if.then ], [ %idx, %for.body ]
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, %n
+  br i1 %exitcond.not, label %exit, label %for.body
+
+exit:
+  ret void
+}
+
+define void @expand_load(ptr noalias %dst, ptr readonly %src, i32 %c, i64 %n) {
+; CHECK-V4-LABEL: define void @expand_load(
+; CHECK-V4-SAME: ptr noalias [[DST:%.*]], ptr readonly [[SRC:%.*]], i32 [[C:%.*]], i64 [[N:%.*]]) #[[ATTR0]] {
+; CHECK-V4-NEXT:  [[VECTOR_PH:.*]]:
+; CHECK-V4-NEXT:    br label %[[VECTOR_BODY:.*]]
+; CHECK-V4:       [[VECTOR_BODY]]:
+; CHECK-V4-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[IV_NEXT:%.*]], %[[MIDDLE_BLOCK:.*]] ]
+; CHECK-V4-NEXT:    [[CONDITIONAL_IV:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[IDX_1:%.*]], %[[MIDDLE_BLOCK]] ]
+; CHECK-V4-NEXT:    [[DST_PTR:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]]
+; CHECK-V4-NEXT:    [[LOAD_DST:%.*]] = load i32, ptr [[DST_PTR]], align 4
+; CHECK-V4-NEXT:    [[CMP:%.*]] = icmp slt i32 [[LOAD_DST]], [[C]]
+; CHECK-V4-NEXT:    br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[MIDDLE_BLOCK]]
+; CHECK-V4:       [[IF_THEN]]:
+; CHECK-V4-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[CONDITIONAL_IV]]
+; CHECK-V4-NEXT:    [[LOAD_SRC:%.*]] = load i32, ptr [[TMP3]], align 4
+; CHECK-V4-NEXT:    store i32 [[LOAD_SRC]], ptr [[DST_PTR]], align 4
+; CHECK-V4-NEXT:    [[IDX_NEXT:%.*]] = add nsw i64 [[CONDITIONAL_IV]], 1
+; CHECK-V4-NEXT:    br label %[[MIDDLE_BLOCK]]
+; CHECK-V4:       [[MIDDLE_BLOCK]]:
+; CHECK-V4-NEXT:    [[IDX_1]] = phi i64 [ [[IDX_NEXT]], %[[IF_THEN]] ], [ [[CONDITIONAL_IV]], %[[VECTOR_BODY]] ]
+; CHECK-V4-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
+; CHECK-V4-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
+; CHECK-V4-NEXT:    br i1 [[EXITCOND_NOT]], label %[[SCALAR_PH:.*]], label %[[VECTOR_BODY]]
+; CHECK-V4:       [[SCALAR_PH]]:
+; CHECK-V4-NEXT:    ret void
+;
+; CHECK-ICELAKE-LABEL: define void @expand_load(
+; CHECK-ICELAKE-SAME: ptr noalias [[DST:%.*]], ptr readonly [[SRC:%.*]], i32 [[C:%.*]], i64 [[N:%.*]]) #[[ATTR0]] {
+; CHECK-ICELAKE-NEXT:  [[VECTOR_PH:.*]]:
+; CHECK-ICELAKE-NEXT:    br label %[[VECTOR_BODY:.*]]
+; CHECK-ICELAKE:       [[VECTOR_BODY]]:
+; CHECK-ICELAKE-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[IV_NEXT:%.*]], %[[MIDDLE_BLOCK:.*]] ]
+; CHECK-ICELAKE-NEXT:    [[CONDITIONAL_IV:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[IDX_1:%.*]], %[[MIDDLE_BLOCK]] ]
+; CHECK-ICELAKE-NEXT:    [[DST_PTR:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]]
+; CHECK-ICELAKE-NEXT:    [[LOAD_DST:%.*]] = load i32, ptr [[DST_PTR]], align 4
+; CHECK-ICELAKE-NEXT:    [[CMP:%.*]] = icmp slt i32 [[LOAD_DST]], [[C]]
+; CHECK-ICELAKE-NEXT:    br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[MIDDLE_BLOCK]]
+; CHECK-ICELAKE:       [[IF_THEN]]:
+; CHECK-ICELAKE-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[CONDITIONAL_IV]]
+; CHECK-ICELAKE-NEXT:    [[LOAD_SRC:%.*]] = load i32, ptr [[TMP3]], align 4
+; CHECK-ICELAKE-NEXT:    store i32 [[LOAD_SRC]], ptr [[DST_PTR]], align 4
+; CHECK-ICELAKE-NEXT:    [[IDX_NEXT:%.*]] = add nsw i64 [[CONDITIONAL_IV]], 1
+; CHECK-ICELAKE-NEXT:    br label %[[MIDDLE_BLOCK]]
+; CHECK-ICELAKE:       [[MIDDLE_BLOCK]]:
+; CHECK-ICELAKE-NEXT:    [[IDX_1]] = phi i64 [ [[IDX_NEXT]], %[[IF_THEN]] ], [ [[CONDITIONAL_IV]], %[[VECTOR_BODY]] ]
+; CHECK-ICELAKE-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
+; CHECK-ICELAKE-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
+; CHECK-ICELAKE-NEXT:    br i1 [[EXITCOND_NOT]], label %[[SCALAR_PH:.*]], label %[[VECTOR_BODY]]
+; CHECK-ICELAKE:       [[SCALAR_PH]]:
+; CHECK-ICELAKE-NEXT:    ret void
+;
+; CHECK-ZNVER4-LABEL: define void @expand_load(
+; CHECK-ZNVER4-SAME: ptr noalias [[DST:%.*]], ptr readonly [[SRC:%.*]], i32 [[C:%.*]], i64 [[N:%.*]]) #[[ATTR0]] {
+; CHECK-ZNVER4-NEXT:  [[VEC_EPILOG_SCALAR_PH:.*]]:
+; CHECK-ZNVER4-NEXT:    br label %[[FOR_BODY:.*]]
+; CHECK-ZNVER4:       [[FOR_BODY]]:
+; CHECK-ZNVER4-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[VEC_EPILOG_SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[FOR_INC:.*]] ]
+; CHECK-ZNVER4-NEXT:    [[IDX:%.*]] = phi i64 [ 0, %[[VEC_EPILOG_SCALAR_PH]] ], [ [[IDX_1:%.*]], %[[FOR_INC]] ]
+; CHECK-ZNVER4-NEXT:    [[DST_PTR:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]]
+; CHECK-ZNVER4-NEXT:    [[LOAD_DST:%.*]] = load i32, ptr [[DST_PTR]], align 4
+; CHECK-ZNVER4-NEXT:    [[CMP:%.*]] = icmp slt i32 [[LOAD_DST]], [[C]]
+; CHECK-ZNVER4-NEXT:    br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[FOR_INC]]
+; CHECK-ZNVER4:       [[IF_THEN]]:
+; CHECK-ZNVER4-NEXT:    [[SRC_PTR:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[IDX]]
+; CHECK-ZNVER4-NEXT:    [[LOAD_SRC:%.*]] = load i32, ptr [[SRC_PTR]], align 4
+; CHECK-ZNVER4-NEXT:    store i32 [[LOAD_SRC]], ptr [[DST_PTR]], align 4
+; CHECK-ZNVER4-NEXT:    [[IDX_NEXT:%.*]] = add nsw i64 [[IDX]], 1
+; CHECK-ZNVER4-NEXT:    br label %[[FOR_INC]]
+; CHECK-ZNVER4:       [[FOR_INC]]:
+; CHECK-ZNVER4-NEXT:    [[IDX_1]] = phi i64 [ [[IDX_NEXT]], %[[IF_THEN]] ], [ [[IDX]], %[[FOR_BODY]] ]
+; CHECK-ZNVER4-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
+; CHECK-ZNVER4-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
+; CHECK-ZNVER4-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[FOR_BODY]]
+; CHECK-ZNVER4:       [[EXIT]]:
+; CHECK-ZNVER4-NEXT:    ret void
+;
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
+  %idx = phi i64 [ 0, %entry ], [ %idx.1, %for.inc ]
+  %dst.ptr = getelementptr inbounds i32, ptr %dst, i64 %iv
+  %load.dst = load i32, ptr %dst.ptr, align 4
+  %cmp = icmp slt i32 %load.dst, %c
+  br i1 %cmp, label %if.then, label %for.inc
+
+if.then:
+  %src.ptr = getelementptr inbounds i32, ptr %src, i64 %idx
+  %load.src = load i32, ptr %src.ptr, align 4
+  store i32 %load.src, ptr %dst.ptr, align 4
+  %idx.next = add nsw i64 %idx, 1
+  br label %for.inc
+
+for.inc:
+  %idx.1 = phi i64 [ %idx.next, %if.then ], [ %idx, %for.body ]
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, %n
+  br i1 %exitcond.not, label %exit, label %for.body
+
+exit:
+  ret void
+}
diff --git a/llvm/test/Transforms/LoopVectorize/compress-idioms-negative-tests.ll b/llvm/test/Transforms/LoopVectorize/compress-idioms-negative-tests.ll
new file mode 100644
index 0000000000000..375e77b2de482
--- /dev/null
+++ b/llvm/test/Transforms/LoopVectorize/compress-idioms-negative-tests.ll
@@ -0,0 +1,268 @@
+; RUN: opt < %s -enable-early-exit-vectorization-with-side-effects -force-target-supports-masked-memory-ops -force-vector-width=4 -passes=loop-vectorize -disable-output -pass-remarks-missed=".*" 2>&1 | FileCheck %s
+
+; CHECK: loop not vectorized
+
+; Negative test: Conditional pointer (rather than index) increments are not supported yet (needs LAA support).
+define void @test_compress_store_with_pointer(ptr writeonly noalias %init.dst, ptr readonly %src, i32 %c, i64 %n) {
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
+  %dst = phi ptr [ %init.dst, %entry ], [ %dst.1, %for.inc ]
+  %src.ptr = getelementptr inbounds i32, ptr %src, i64 %iv
+  %load.src = load i32, ptr %src.ptr, align 4
+  %cmp = icmp slt i32 %load.src, %c
+  br i1 %cmp, label %if.then, label %for.inc
+
+if.then:
+  %dst.inc = getelementptr inbounds i8, ptr %dst, i64 4
+  store i32 %load.src, ptr %dst, align 4
+  br label %for.inc
+
+for.inc:
+  %dst.1 = phi ptr [ %dst.inc, %if.then ], [ %dst, %for.body ]
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, %n
+  br i1 %exitcond.not, label %exit, label %for.body
+
+exit:
+  ret void
+}
+
+; CHECK: loop not vectorized
+
+; Negative test: Storing the conditionally incremented phi is invalid.
+
+define void @test_store_conditionally_incremented_value(ptr writeonly noalias %dst, ptr writeonly noalias %dst2, ptr readonly %src, i32 %c, i64 %n) {
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
+  %idx = phi i32 [ 0, %entry ], [ %idx.1, %for.inc ]
+  %src.ptr = getelementptr inbounds i32, ptr %src, i64 %iv
+  %load.src = load i32, ptr %src.ptr, align 4
+  %cmp = icmp slt i32 %load.src, %c
+  br i1 %cmp, label %if.then, label %for.inc
+
+if.then:
+  %dst.ptr = getelementptr inbounds i32, ptr %dst, i64 %iv
+  store i32 %idx, ptr %dst.ptr, align 4
+  %idx.next = add nsw i32 %idx, 1
+  br label %for.inc
+
+for.inc:
+  %idx.1 = phi i32 [ %idx.next, %if.then ], [ %idx, %for.body ]
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, %n
+  br i1 %exitcond.not, label %exit, label %for.body
+
+exit:
+  ret void
+}
+
+; CHECK: loop not vectorized
+
+; Pre-increment is currently not matched as we require one use of the step instruction.
+define void @test_pre_increment_compress_store(ptr writeonly noalias %dst, ptr readonly %src, i32 %c, i64 %n) {
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
+  %idx = phi i64 [ 0, %entry ], [ %idx.1, %for.inc ]
+  %src.ptr = getelementptr inbounds i32, ptr %src, i64 %iv
+  %load.src = load i32, ptr %src.ptr, align 4
+  %cmp = icmp slt i32 %load.src, %c
+  br i1 %cmp, label %if.then, label %for.inc
+
+if.then:
+  %idx.next = add nsw i64 %idx, 1
+  %dst.ptr = getelementptr inbounds i32, ptr %dst, i64 %idx.next
+  store i32 %load.src, ptr %dst.ptr, align 4
+  br label %for.inc
+
+for.inc:
+  %idx.1 = phi i64 [ %idx.next, %if.then ], [ %idx, %for.body ]
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, %n
+  br i1 %exitcond.not, label %exit, label %for.body
+
+exit:
+  ret void
+}
+
+; CHECK: loop not vectorized
+
+; Negative test: In this case the %idx is incremented when %cond.val != 0,
+; but the store occurs when %cond.val > 100. The store mask does not match the
+; PHI mask, so the loop is not vectorized.
+define void @compress_mismatched_mask(ptr noalias %dst, ptr noalias %src, ptr noalias %cond, i64 %n) {
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
+  %idx = phi i64 [ 0, %entry ], [ %idx.next, %for.inc ]
+  %cond.ptr = getelementptr inbounds nuw [4 x i8], ptr %cond, i64 %iv
+  %cond.val = load i32, ptr %cond.ptr, align 4
+  %cond.bool = icmp eq i32 %cond.val, 0
+  br i1 %cond.bool, label %for.inc, label %if.then
+
+if.then:
+  %cmp.cond = icmp sgt i32 %cond.val, 100
+  br i1 %cmp.cond, label %if.then1, label %if.end
+
+if.then1:
+  %src.ptr = getelementptr inbounds nuw [4 x i8], ptr %src, i64 %iv
+  %src.val = load i32, ptr %src.ptr, align 4
+  %dst.ptr = getelementptr inbounds [4 x i8], ptr %dst, i64 %idx
+  store i32 %src.val, ptr %dst.ptr, align 4
+  br label %if.end
+
+if.end:
+  %inc = add nsw i64 %idx, 1
+  br label %for.inc
+
+for.inc:
+  %idx.next = phi i64 [ %inc, %if.end ], [ %idx, %for.body ]
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, %n
+  br i1 %exitcond.not, label %exit, label %for.body
+
+exit:
+  ret void
+}
+
+; CHECK: loop not vectorized
+
+; Negative test: Simple early exit loop with a compressstore. This fails in VPlan handling for early exits.
+define i32 @compress_store_with_early_exit(ptr dereferenceable(1024) %dst, ptr noalias dereferenceable(1024) %src, ptr noalias dereferenceable(1024) %cond, ptr noalias dereferenceable(1024) %exit_cond) {
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
+  %idx = phi i64 [ 0, %entry ], [ %idx.2, %for.inc ]
+  %cond.ptr = getelementptr inbounds nuw i32, ptr %cond, i64 %iv
+  %cond.val = load i32, ptr %cond.ptr, align 4
+  %compress.cond = icmp eq i32 %cond.val, 0
+  %exit.ptr = getelementptr inbounds nuw i32, ptr %exit_cond, i64 %iv
+  %exit.val = load i32, ptr %exit.ptr, align 4
+  br i1 %compress.cond, label %for.inc, label %if.then
+
+if.then:
+  %src.ptr = getelementptr inbounds nuw i32, ptr %src, i64 %iv
+  %src.val = load i32, ptr %src.ptr, align 4
+  %dst.ptr = getelementptr inbounds i32, ptr %dst, i64 %idx
+  store i32 %src.val, ptr %dst.ptr, align 4
+  %not.exit.cond = icmp eq i32 %exit.val, 0
+  %inc = add nsw i64 %idx, 1
+  br i1 %not.exit.cond, label %for.inc, label %early.exit
+
+for.inc:
+  %idx.2 = phi i64 [ %idx, %for.body ], [ %inc, %if.then ]
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, 128
+  br i1 %exitcond.not, label %early.exit, label %for.body
+
+early.exit:
+  %ret = phi i32 [ 1, %if.then ], [ 0, %for.inc ]
+  ret i32 %ret
+}
+
+; CHECK: loop not vectorized
+
+; Negative test: Using the conditional induction outside the loop is not supported.
+define i64 @out_of_loop_use_of_conditional_induction(ptr writeonly noalias %dst, ptr readonly %src, i32 %c, i64 %n) {
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
+  %idx = phi i64 [ 0, %entry ], [ %idx.1, %for.inc ]
+  %src.ptr = getelementptr inbounds i32, ptr %src, i64 %iv
+  %load.src = load i32, ptr %src.ptr, align 4
+  %cmp = icmp slt i32 %load.src, %c
+  br i1 %cmp, label %if.then, label %for.inc
+
+if.then:
+  %dst.ptr = getelementptr inbounds i32, ptr %dst, i64 %idx
+  store i32 %load.src, ptr %dst.ptr, align 4
+  %idx.next = add nsw i64 %idx, 1
+  br label %for.inc
+
+for.inc:
+  %idx.1 = phi i64 [ %idx.next, %if.then ], [ %idx, %for.body ]
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, %n
+  br i1 %exitcond.not, label %exit, label %for.body
+
+exit:
+  ret i64 %idx
+}
+
+; CHECK: loop not vectorized
+
+; Negative test: Matching an extended conditional induction index is not supported yet.
+; Note: We should be able to support this case by using the no-wrap flags on %idx.next.
+define void @test_compress_store_with_extended_index_with_nsw(ptr writeonly noalias %dst, ptr readonly %src, i32 %c, i64 %n) {
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
+  %idx = phi i32 [ 0, %entry ], [ %idx.1, %for.inc ]
+  %src.ptr = getelementptr inbounds i32, ptr %src, i64 %iv
+  %load.src = load i32, ptr %src.ptr, align 4
+  %cmp = icmp slt i32 %load.src, %c
+  br i1 %cmp, label %if.then, label %for.inc
+
+if.then:
+  %dst.idx = sext i32 %idx to i64
+  %dst.ptr = getelementptr inbounds i32, ptr %dst, i64 %dst.idx
+  store i32 %load.src, ptr %dst.ptr, align 4
+  %idx.next = add nsw i32 %idx, 1
+  br label %for.inc
+
+for.inc:
+  %idx.1 = phi i32 [ %idx.next, %if.then ], [ %idx, %for.body ]
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, %n
+  br i1 %exitcond.not, label %exit, label %for.body
+
+exit:
+  ret void
+}
+
+; CHECK: loop not vectorized
+
+; Negative test: We can't vectorize an extended conditional induction use without no-wrap flags on the step.
+define void @test_compress_store_with_extended_index(ptr writeonly noalias %dst, ptr readonly %src, i32 %c, i64 %n) {
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
+  %idx = phi i8 [ 0, %entry ], [ %idx.1, %for.inc ]
+  %src.ptr = getelementptr inbounds i32, ptr %src, i64 %iv
+  %load.src = load i32, ptr %src.ptr, align 4
+  %cmp = icmp slt i32 %load.src, %c
+  br i1 %cmp, label %if.then, label %for.inc
+
+if.then:
+  %dst.ptr = getelementptr i8, ptr %dst, i8 %idx
+  store i32 %load.src, ptr %dst.ptr, align 4
+  %idx.next = add i8 %idx, 1
+  br label %for.inc
+
+for.inc:
+  %idx.1 = phi i8 [ %idx.next, %if.then ], [ %idx, %for.body ]
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, %n
+  br i1 %exitcond.not, label %exit, label %for.body
+
+exit:
+  ret void
+}
diff --git a/llvm/test/Transforms/LoopVectorize/compress-idioms.ll b/llvm/test/Transforms/LoopVectorize/compress-idioms.ll
new file mode 100644
index 0000000000000..460471cffa1c9
--- /dev/null
+++ b/llvm/test/Transforms/LoopVectorize/compress-idioms.ll
@@ -0,0 +1,679 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 5
+; RUN: opt < %s -force-target-supports-masked-memory-ops -force-vector-width=4 -passes=loop-vectorize -S 2>&1 | FileCheck %s -check-prefix=CHECK-IC1
+; RUN: opt < %s -force-target-supports-masked-memory-ops -force-vector-width=4 -tail-folding-policy=must-fold-tail -passes=loop-vectorize -S 2>&1 | FileCheck %s -check-prefix=CHECK-TF
+
+define void @test_compress_store_with_index(ptr writeonly noalias %dst, ptr readonly %src, i32 %c) {
+; CHECK-IC1-LABEL: define void @test_compress_store_with_index(
+; CHECK-IC1-SAME: ptr noalias writeonly [[DST:%.*]], ptr readonly [[SRC:%.*]], i32 [[C:%.*]]) {
+; CHECK-IC1-NEXT:  [[VECTOR_PH:.*]]:
+; CHECK-IC1-NEXT:    br label %[[VECTOR_BODY:.*]]
+; CHECK-IC1:       [[VECTOR_BODY]]:
+; CHECK-IC1-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[IV_NEXT:%.*]], %[[EXIT:.*]] ]
+; CHECK-IC1-NEXT:    [[IDX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[IDX_1:%.*]], %[[EXIT]] ]
+; CHECK-IC1-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[INDEX]]
+; CHECK-IC1-NEXT:    [[LOAD_SRC:%.*]] = load i32, ptr [[TMP0]], align 4
+; CHECK-IC1-NEXT:    [[CMP:%.*]] = icmp slt i32 [[LOAD_SRC]], [[C]]
+; CHECK-IC1-NEXT:    br i1 [[CMP]], label %[[MIDDLE_BLOCK:.*]], label %[[EXIT]]
+; CHECK-IC1:       [[MIDDLE_BLOCK]]:
+; CHECK-IC1-NEXT:    [[DST_PTR:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IDX]]
+; CHECK-IC1-NEXT:    store i32 [[LOAD_SRC]], ptr [[DST_PTR]], align 4
+; CHECK-IC1-NEXT:    [[IDX_NEXT:%.*]] = add nsw i64 [[IDX]], 1
+; CHECK-IC1-NEXT:    br label %[[EXIT]]
+; CHECK-IC1:       [[EXIT]]:
+; CHECK-IC1-NEXT:    [[IDX_1]] = phi i64 [ [[IDX_NEXT]], %[[MIDDLE_BLOCK]] ], [ [[IDX]], %[[VECTOR_BODY]] ]
+; CHECK-IC1-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[INDEX]], 1
+; CHECK-IC1-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 4096
+; CHECK-IC1-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT1:.*]], label %[[VECTOR_BODY]]
+; CHECK-IC1:       [[EXIT1]]:
+; CHECK-IC1-NEXT:    ret void
+;
+; CHECK-TF-LABEL: define void @test_compress_store_with_index(
+; CHECK-TF-SAME: ptr noalias writeonly [[DST:%.*]], ptr readonly [[SRC:%.*]], i32 [[C:%.*]]) {
+; CHECK-TF-NEXT:  [[VECTOR_PH:.*]]:
+; CHECK-TF-NEXT:    br label %[[VECTOR_BODY:.*]]
+; CHECK-TF:       [[VECTOR_BODY]]:
+; CHECK-TF-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[IV_NEXT:%.*]], %[[EXIT:.*]] ]
+; CHECK-TF-NEXT:    [[IDX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[IDX_1:%.*]], %[[EXIT]] ]
+; CHECK-TF-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[INDEX]]
+; CHECK-TF-NEXT:    [[LOAD_SRC:%.*]] = load i32, ptr [[TMP0]], align 4
+; CHECK-TF-NEXT:    [[CMP:%.*]] = icmp slt i32 [[LOAD_SRC]], [[C]]
+; CHECK-TF-NEXT:    br i1 [[CMP]], label %[[MIDDLE_BLOCK:.*]], label %[[EXIT]]
+; CHECK-TF:       [[MIDDLE_BLOCK]]:
+; CHECK-TF-NEXT:    [[DST_PTR:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IDX]]
+; CHECK-TF-NEXT:    store i32 [[LOAD_SRC]], ptr [[DST_PTR]], align 4
+; CHECK-TF-NEXT:    [[IDX_NEXT:%.*]] = add nsw i64 [[IDX]], 1
+; CHECK-TF-NEXT:    br label %[[EXIT]]
+; CHECK-TF:       [[EXIT]]:
+; CHECK-TF-NEXT:    [[IDX_1]] = phi i64 [ [[IDX_NEXT]], %[[MIDDLE_BLOCK]] ], [ [[IDX]], %[[VECTOR_BODY]] ]
+; CHECK-TF-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[INDEX]], 1
+; CHECK-TF-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 4096
+; CHECK-TF-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT1:.*]], label %[[VECTOR_BODY]]
+; CHECK-TF:       [[EXIT1]]:
+; CHECK-TF-NEXT:    ret void
+;
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
+  %idx = phi i64 [ 0, %entry ], [ %idx.1, %for.inc ]
+  %src.ptr = getelementptr inbounds i32, ptr %src, i64 %iv
+  %load.src = load i32, ptr %src.ptr, align 4
+  %cmp = icmp slt i32 %load.src, %c
+  br i1 %cmp, label %if.then, label %for.inc
+
+if.then:
+  %dst.ptr = getelementptr inbounds i32, ptr %dst, i64 %idx
+  store i32 %load.src, ptr %dst.ptr, align 4
+  %idx.next = add nsw i64 %idx, 1
+  br label %for.inc
+
+for.inc:
+  %idx.1 = phi i64 [ %idx.next, %if.then ], [ %idx, %for.body ]
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, 4096
+  br i1 %exitcond.not, label %exit, label %for.body
+
+exit:
+  ret void
+}
+
+define void @test_expand_load_with_index(ptr noalias %dst, ptr readonly %src, i32 %c) {
+; CHECK-IC1-LABEL: define void @test_expand_load_with_index(
+; CHECK-IC1-SAME: ptr noalias [[DST:%.*]], ptr readonly [[SRC:%.*]], i32 [[C:%.*]]) {
+; CHECK-IC1-NEXT:  [[ENTRY:.*]]:
+; CHECK-IC1-NEXT:    br label %[[VECTOR_PH:.*]]
+; CHECK-IC1:       [[VECTOR_PH]]:
+; CHECK-IC1-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[EXIT:.*]] ]
+; CHECK-IC1-NEXT:    [[CONDITIONAL_IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IDX_1:%.*]], %[[EXIT]] ]
+; CHECK-IC1-NEXT:    [[DST_PTR:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]]
+; CHECK-IC1-NEXT:    [[LOAD_DST:%.*]] = load i32, ptr [[DST_PTR]], align 4
+; CHECK-IC1-NEXT:    [[CMP:%.*]] = icmp slt i32 [[LOAD_DST]], [[C]]
+; CHECK-IC1-NEXT:    br i1 [[CMP]], label %[[VECTOR_BODY:.*]], label %[[EXIT]]
+; CHECK-IC1:       [[VECTOR_BODY]]:
+; CHECK-IC1-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[CONDITIONAL_IV]]
+; CHECK-IC1-NEXT:    [[LOAD_SRC:%.*]] = load i32, ptr [[TMP2]], align 4
+; CHECK-IC1-NEXT:    store i32 [[LOAD_SRC]], ptr [[DST_PTR]], align 4
+; CHECK-IC1-NEXT:    [[IDX_NEXT:%.*]] = add nsw i64 [[CONDITIONAL_IV]], 1
+; CHECK-IC1-NEXT:    br label %[[EXIT]]
+; CHECK-IC1:       [[EXIT]]:
+; CHECK-IC1-NEXT:    [[IDX_1]] = phi i64 [ [[IDX_NEXT]], %[[VECTOR_BODY]] ], [ [[CONDITIONAL_IV]], %[[VECTOR_PH]] ]
+; CHECK-IC1-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
+; CHECK-IC1-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 4096
+; CHECK-IC1-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT1:.*]], label %[[VECTOR_PH]]
+; CHECK-IC1:       [[EXIT1]]:
+; CHECK-IC1-NEXT:    ret void
+;
+; CHECK-TF-LABEL: define void @test_expand_load_with_index(
+; CHECK-TF-SAME: ptr noalias [[DST:%.*]], ptr readonly [[SRC:%.*]], i32 [[C:%.*]]) {
+; CHECK-TF-NEXT:  [[ENTRY:.*]]:
+; CHECK-TF-NEXT:    br label %[[VECTOR_PH:.*]]
+; CHECK-TF:       [[VECTOR_PH]]:
+; CHECK-TF-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[EXIT:.*]] ]
+; CHECK-TF-NEXT:    [[CONDITIONAL_IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IDX_1:%.*]], %[[EXIT]] ]
+; CHECK-TF-NEXT:    [[DST_PTR:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]]
+; CHECK-TF-NEXT:    [[LOAD_DST:%.*]] = load i32, ptr [[DST_PTR]], align 4
+; CHECK-TF-NEXT:    [[CMP:%.*]] = icmp slt i32 [[LOAD_DST]], [[C]]
+; CHECK-TF-NEXT:    br i1 [[CMP]], label %[[VECTOR_BODY:.*]], label %[[EXIT]]
+; CHECK-TF:       [[VECTOR_BODY]]:
+; CHECK-TF-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[CONDITIONAL_IV]]
+; CHECK-TF-NEXT:    [[LOAD_SRC:%.*]] = load i32, ptr [[TMP2]], align 4
+; CHECK-TF-NEXT:    store i32 [[LOAD_SRC]], ptr [[DST_PTR]], align 4
+; CHECK-TF-NEXT:    [[IDX_NEXT:%.*]] = add nsw i64 [[CONDITIONAL_IV]], 1
+; CHECK-TF-NEXT:    br label %[[EXIT]]
+; CHECK-TF:       [[EXIT]]:
+; CHECK-TF-NEXT:    [[IDX_1]] = phi i64 [ [[IDX_NEXT]], %[[VECTOR_BODY]] ], [ [[CONDITIONAL_IV]], %[[VECTOR_PH]] ]
+; CHECK-TF-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
+; CHECK-TF-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 4096
+; CHECK-TF-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT1:.*]], label %[[VECTOR_PH]]
+; CHECK-TF:       [[EXIT1]]:
+; CHECK-TF-NEXT:    ret void
+;
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
+  %idx = phi i64 [ 0, %entry ], [ %idx.1, %for.inc ]
+  %dst.ptr = getelementptr inbounds i32, ptr %dst, i64 %iv
+  %load.dst = load i32, ptr %dst.ptr, align 4
+  %cmp = icmp slt i32 %load.dst, %c
+  br i1 %cmp, label %if.then, label %for.inc
+
+if.then:
+  %src.ptr = getelementptr inbounds i32, ptr %src, i64 %idx
+  %load.src = load i32, ptr %src.ptr, align 4
+  store i32 %load.src, ptr %dst.ptr, align 4
+  %idx.next = add nsw i64 %idx, 1
+  br label %for.inc
+
+for.inc:
+  %idx.1 = phi i64 [ %idx.next, %if.then ], [ %idx, %for.body ]
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, 4096
+  br i1 %exitcond.not, label %exit, label %for.body
+
+exit:
+  ret void
+}
+
+define i64 @test_conditionally_incremented_phi_liveout(ptr writeonly noalias %dst, ptr readonly %src, i32 %c) {
+; CHECK-IC1-LABEL: define i64 @test_conditionally_incremented_phi_liveout(
+; CHECK-IC1-SAME: ptr noalias writeonly [[DST:%.*]], ptr readonly [[SRC:%.*]], i32 [[C:%.*]]) {
+; CHECK-IC1-NEXT:  [[VECTOR_PH:.*]]:
+; CHECK-IC1-NEXT:    br label %[[VECTOR_BODY:.*]]
+; CHECK-IC1:       [[VECTOR_BODY]]:
+; CHECK-IC1-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[IV_NEXT:%.*]], %[[EXIT:.*]] ]
+; CHECK-IC1-NEXT:    [[IDX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[IDX_1:%.*]], %[[EXIT]] ]
+; CHECK-IC1-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[INDEX]]
+; CHECK-IC1-NEXT:    [[LOAD_SRC:%.*]] = load i32, ptr [[TMP0]], align 4
+; CHECK-IC1-NEXT:    [[CMP:%.*]] = icmp slt i32 [[LOAD_SRC]], [[C]]
+; CHECK-IC1-NEXT:    br i1 [[CMP]], label %[[MIDDLE_BLOCK:.*]], label %[[EXIT]]
+; CHECK-IC1:       [[MIDDLE_BLOCK]]:
+; CHECK-IC1-NEXT:    [[DST_PTR:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IDX]]
+; CHECK-IC1-NEXT:    store i32 [[LOAD_SRC]], ptr [[DST_PTR]], align 4
+; CHECK-IC1-NEXT:    [[IDX_NEXT:%.*]] = add nsw i64 [[IDX]], 1
+; CHECK-IC1-NEXT:    br label %[[EXIT]]
+; CHECK-IC1:       [[EXIT]]:
+; CHECK-IC1-NEXT:    [[IDX_1]] = phi i64 [ [[IDX_NEXT]], %[[MIDDLE_BLOCK]] ], [ [[IDX]], %[[VECTOR_BODY]] ]
+; CHECK-IC1-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[INDEX]], 1
+; CHECK-IC1-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 4096
+; CHECK-IC1-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT1:.*]], label %[[VECTOR_BODY]]
+; CHECK-IC1:       [[EXIT1]]:
+; CHECK-IC1-NEXT:    [[CONDITIONAL_STEP:%.*]] = phi i64 [ [[IDX_1]], %[[EXIT]] ]
+; CHECK-IC1-NEXT:    ret i64 [[CONDITIONAL_STEP]]
+;
+; CHECK-TF-LABEL: define i64 @test_conditionally_incremented_phi_liveout(
+; CHECK-TF-SAME: ptr noalias writeonly [[DST:%.*]], ptr readonly [[SRC:%.*]], i32 [[C:%.*]]) {
+; CHECK-TF-NEXT:  [[VECTOR_PH:.*]]:
+; CHECK-TF-NEXT:    br label %[[VECTOR_BODY:.*]]
+; CHECK-TF:       [[VECTOR_BODY]]:
+; CHECK-TF-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[IV_NEXT:%.*]], %[[EXIT:.*]] ]
+; CHECK-TF-NEXT:    [[IDX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[IDX_1:%.*]], %[[EXIT]] ]
+; CHECK-TF-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[INDEX]]
+; CHECK-TF-NEXT:    [[LOAD_SRC:%.*]] = load i32, ptr [[TMP0]], align 4
+; CHECK-TF-NEXT:    [[CMP:%.*]] = icmp slt i32 [[LOAD_SRC]], [[C]]
+; CHECK-TF-NEXT:    br i1 [[CMP]], label %[[MIDDLE_BLOCK:.*]], label %[[EXIT]]
+; CHECK-TF:       [[MIDDLE_BLOCK]]:
+; CHECK-TF-NEXT:    [[DST_PTR:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IDX]]
+; CHECK-TF-NEXT:    store i32 [[LOAD_SRC]], ptr [[DST_PTR]], align 4
+; CHECK-TF-NEXT:    [[IDX_NEXT:%.*]] = add nsw i64 [[IDX]], 1
+; CHECK-TF-NEXT:    br label %[[EXIT]]
+; CHECK-TF:       [[EXIT]]:
+; CHECK-TF-NEXT:    [[IDX_1]] = phi i64 [ [[IDX_NEXT]], %[[MIDDLE_BLOCK]] ], [ [[IDX]], %[[VECTOR_BODY]] ]
+; CHECK-TF-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[INDEX]], 1
+; CHECK-TF-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 4096
+; CHECK-TF-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT1:.*]], label %[[VECTOR_BODY]]
+; CHECK-TF:       [[EXIT1]]:
+; CHECK-TF-NEXT:    [[CONDITIONAL_STEP:%.*]] = phi i64 [ [[IDX_1]], %[[EXIT]] ]
+; CHECK-TF-NEXT:    ret i64 [[CONDITIONAL_STEP]]
+;
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
+  %idx = phi i64 [ 0, %entry ], [ %idx.1, %for.inc ]
+  %src.ptr = getelementptr inbounds i32, ptr %src, i64 %iv
+  %load.src = load i32, ptr %src.ptr, align 4
+  %cmp = icmp slt i32 %load.src, %c
+  br i1 %cmp, label %if.then, label %for.inc
+
+if.then:
+  %dst.ptr = getelementptr inbounds i32, ptr %dst, i64 %idx
+  store i32 %load.src, ptr %dst.ptr, align 4
+  %idx.next = add nsw i64 %idx, 1
+  br label %for.inc
+
+for.inc:
+  %idx.1 = phi i64 [ %idx.next, %if.then ], [ %idx, %for.body ]
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, 4096
+  br i1 %exitcond.not, label %exit, label %for.body
+
+exit:
+  ret i64 %idx.1
+}
+
+define void @test_compress_store_with_scaled_pointer(ptr writeonly noalias %dst.bytes, ptr readonly %src, i32 %c) {
+; CHECK-IC1-LABEL: define void @test_compress_store_with_scaled_pointer(
+; CHECK-IC1-SAME: ptr noalias writeonly [[DST_BYTES:%.*]], ptr readonly [[SRC:%.*]], i32 [[C:%.*]]) {
+; CHECK-IC1-NEXT:  [[VECTOR_PH:.*]]:
+; CHECK-IC1-NEXT:    br label %[[VECTOR_BODY:.*]]
+; CHECK-IC1:       [[VECTOR_BODY]]:
+; CHECK-IC1-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[IV_NEXT:%.*]], %[[EXIT:.*]] ]
+; CHECK-IC1-NEXT:    [[CONDITIONAL_IV:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[IDX_1:%.*]], %[[EXIT]] ]
+; CHECK-IC1-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[INDEX]]
+; CHECK-IC1-NEXT:    [[LOAD_SRC:%.*]] = load i32, ptr [[TMP0]], align 4
+; CHECK-IC1-NEXT:    [[CMP:%.*]] = icmp slt i32 [[LOAD_SRC]], [[C]]
+; CHECK-IC1-NEXT:    br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[EXIT]]
+; CHECK-IC1:       [[IF_THEN]]:
+; CHECK-IC1-NEXT:    [[TMP2:%.*]] = shl nsw i64 [[CONDITIONAL_IV]], 2
+; CHECK-IC1-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[DST_BYTES]], i64 [[TMP2]]
+; CHECK-IC1-NEXT:    store i32 [[LOAD_SRC]], ptr [[TMP3]], align 4
+; CHECK-IC1-NEXT:    [[IDX_NEXT:%.*]] = add nsw i64 [[CONDITIONAL_IV]], 1
+; CHECK-IC1-NEXT:    br label %[[EXIT]]
+; CHECK-IC1:       [[EXIT]]:
+; CHECK-IC1-NEXT:    [[IDX_1]] = phi i64 [ [[IDX_NEXT]], %[[IF_THEN]] ], [ [[CONDITIONAL_IV]], %[[VECTOR_BODY]] ]
+; CHECK-IC1-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[INDEX]], 1
+; CHECK-IC1-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 4096
+; CHECK-IC1-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT1:.*]], label %[[VECTOR_BODY]]
+; CHECK-IC1:       [[EXIT1]]:
+; CHECK-IC1-NEXT:    ret void
+;
+; CHECK-TF-LABEL: define void @test_compress_store_with_scaled_pointer(
+; CHECK-TF-SAME: ptr noalias writeonly [[DST_BYTES:%.*]], ptr readonly [[SRC:%.*]], i32 [[C:%.*]]) {
+; CHECK-TF-NEXT:  [[VECTOR_PH:.*]]:
+; CHECK-TF-NEXT:    br label %[[VECTOR_BODY:.*]]
+; CHECK-TF:       [[VECTOR_BODY]]:
+; CHECK-TF-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[IV_NEXT:%.*]], %[[EXIT:.*]] ]
+; CHECK-TF-NEXT:    [[CONDITIONAL_IV:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[IDX_1:%.*]], %[[EXIT]] ]
+; CHECK-TF-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[INDEX]]
+; CHECK-TF-NEXT:    [[LOAD_SRC:%.*]] = load i32, ptr [[TMP0]], align 4
+; CHECK-TF-NEXT:    [[CMP:%.*]] = icmp slt i32 [[LOAD_SRC]], [[C]]
+; CHECK-TF-NEXT:    br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[EXIT]]
+; CHECK-TF:       [[IF_THEN]]:
+; CHECK-TF-NEXT:    [[TMP2:%.*]] = shl nsw i64 [[CONDITIONAL_IV]], 2
+; CHECK-TF-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[DST_BYTES]], i64 [[TMP2]]
+; CHECK-TF-NEXT:    store i32 [[LOAD_SRC]], ptr [[TMP3]], align 4
+; CHECK-TF-NEXT:    [[IDX_NEXT:%.*]] = add nsw i64 [[CONDITIONAL_IV]], 1
+; CHECK-TF-NEXT:    br label %[[EXIT]]
+; CHECK-TF:       [[EXIT]]:
+; CHECK-TF-NEXT:    [[IDX_1]] = phi i64 [ [[IDX_NEXT]], %[[IF_THEN]] ], [ [[CONDITIONAL_IV]], %[[VECTOR_BODY]] ]
+; CHECK-TF-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[INDEX]], 1
+; CHECK-TF-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 4096
+; CHECK-TF-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT1:.*]], label %[[VECTOR_BODY]]
+; CHECK-TF:       [[EXIT1]]:
+; CHECK-TF-NEXT:    ret void
+;
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
+  %idx = phi i64 [ 0, %entry ], [ %idx.1, %for.inc ]
+  %src.ptr = getelementptr inbounds i32, ptr %src, i64 %iv
+  %load.src = load i32, ptr %src.ptr, align 4
+  %cmp = icmp slt i32 %load.src, %c
+  br i1 %cmp, label %if.then, label %for.inc
+
+if.then:
+  %idx.bytes = shl nsw i64 %idx, 2
+  %dst.ptr = getelementptr inbounds i8, ptr %dst.bytes, i64 %idx.bytes
+  store i32 %load.src, ptr %dst.ptr, align 4
+  %idx.next = add nsw i64 %idx, 1
+  br label %for.inc
+
+for.inc:
+  %idx.1 = phi i64 [ %idx.next, %if.then ], [ %idx, %for.body ]
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, 4096
+  br i1 %exitcond.not, label %exit, label %for.body
+
+exit:
+  ret void
+}
+
+; Test a nested conditional compress store, where the phi is only updated on iterations where the store takes place.
+define void @test_nested_conditional_compress_store(ptr writeonly noalias %dst, ptr readonly %src, i32 %c) {
+; CHECK-IC1-LABEL: define void @test_nested_conditional_compress_store(
+; CHECK-IC1-SAME: ptr noalias writeonly [[DST:%.*]], ptr readonly [[SRC:%.*]], i32 [[C:%.*]]) {
+; CHECK-IC1-NEXT:  [[VECTOR_PH:.*]]:
+; CHECK-IC1-NEXT:    br label %[[VECTOR_BODY:.*]]
+; CHECK-IC1:       [[VECTOR_BODY]]:
+; CHECK-IC1-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[IV_NEXT:%.*]], %[[EXIT:.*]] ]
+; CHECK-IC1-NEXT:    [[CONDITIONAL_IV:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[PHI:%.*]], %[[EXIT]] ]
+; CHECK-IC1-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[INDEX]]
+; CHECK-IC1-NEXT:    [[LOAD_SRC:%.*]] = load i32, ptr [[TMP0]], align 4
+; CHECK-IC1-NEXT:    [[CMP:%.*]] = icmp slt i32 [[LOAD_SRC]], [[C]]
+; CHECK-IC1-NEXT:    br i1 [[CMP]], label %[[UPDATE_BLOCK:.*]], label %[[EXIT]]
+; CHECK-IC1:       [[UPDATE_BLOCK]]:
+; CHECK-IC1-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[CONDITIONAL_IV]]
+; CHECK-IC1-NEXT:    [[UPDATE:%.*]] = add nsw i64 [[CONDITIONAL_IV]], 1
+; CHECK-IC1-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[LOAD_SRC]], 0
+; CHECK-IC1-NEXT:    br i1 [[CMP2]], label %[[MIDDLE_BLOCK:.*]], label %[[EXIT]]
+; CHECK-IC1:       [[MIDDLE_BLOCK]]:
+; CHECK-IC1-NEXT:    store i32 [[LOAD_SRC]], ptr [[TMP2]], align 4
+; CHECK-IC1-NEXT:    br label %[[EXIT]]
+; CHECK-IC1:       [[EXIT]]:
+; CHECK-IC1-NEXT:    [[PHI]] = phi i64 [ [[CONDITIONAL_IV]], %[[VECTOR_BODY]] ], [ [[CONDITIONAL_IV]], %[[UPDATE_BLOCK]] ], [ [[UPDATE]], %[[MIDDLE_BLOCK]] ]
+; CHECK-IC1-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[INDEX]], 1
+; CHECK-IC1-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 4096
+; CHECK-IC1-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT1:.*]], label %[[VECTOR_BODY]]
+; CHECK-IC1:       [[EXIT1]]:
+; CHECK-IC1-NEXT:    ret void
+;
+; CHECK-TF-LABEL: define void @test_nested_conditional_compress_store(
+; CHECK-TF-SAME: ptr noalias writeonly [[DST:%.*]], ptr readonly [[SRC:%.*]], i32 [[C:%.*]]) {
+; CHECK-TF-NEXT:  [[VECTOR_PH:.*]]:
+; CHECK-TF-NEXT:    br label %[[VECTOR_BODY:.*]]
+; CHECK-TF:       [[VECTOR_BODY]]:
+; CHECK-TF-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[IV_NEXT:%.*]], %[[EXIT:.*]] ]
+; CHECK-TF-NEXT:    [[CONDITIONAL_IV:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[PHI:%.*]], %[[EXIT]] ]
+; CHECK-TF-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[INDEX]]
+; CHECK-TF-NEXT:    [[LOAD_SRC:%.*]] = load i32, ptr [[TMP0]], align 4
+; CHECK-TF-NEXT:    [[CMP:%.*]] = icmp slt i32 [[LOAD_SRC]], [[C]]
+; CHECK-TF-NEXT:    br i1 [[CMP]], label %[[UPDATE_BLOCK:.*]], label %[[EXIT]]
+; CHECK-TF:       [[UPDATE_BLOCK]]:
+; CHECK-TF-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[CONDITIONAL_IV]]
+; CHECK-TF-NEXT:    [[UPDATE:%.*]] = add nsw i64 [[CONDITIONAL_IV]], 1
+; CHECK-TF-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[LOAD_SRC]], 0
+; CHECK-TF-NEXT:    br i1 [[CMP2]], label %[[MIDDLE_BLOCK:.*]], label %[[EXIT]]
+; CHECK-TF:       [[MIDDLE_BLOCK]]:
+; CHECK-TF-NEXT:    store i32 [[LOAD_SRC]], ptr [[TMP2]], align 4
+; CHECK-TF-NEXT:    br label %[[EXIT]]
+; CHECK-TF:       [[EXIT]]:
+; CHECK-TF-NEXT:    [[PHI]] = phi i64 [ [[CONDITIONAL_IV]], %[[VECTOR_BODY]] ], [ [[CONDITIONAL_IV]], %[[UPDATE_BLOCK]] ], [ [[UPDATE]], %[[MIDDLE_BLOCK]] ]
+; CHECK-TF-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[INDEX]], 1
+; CHECK-TF-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 4096
+; CHECK-TF-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT1:.*]], label %[[VECTOR_BODY]]
+; CHECK-TF:       [[EXIT1]]:
+; CHECK-TF-NEXT:    ret void
+;
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
+  %idx = phi i64 [ 0, %entry ], [ %phi, %latch ]
+  %src.ptr = getelementptr inbounds i32, ptr %src, i64 %iv
+  %load.src = load i32, ptr %src.ptr, align 4
+  %cmp = icmp slt i32 %load.src, %c
+  br i1 %cmp, label %update.block, label %latch
+
+update.block:
+  %dst.ptr = getelementptr inbounds i32, ptr %dst, i64 %idx
+  %update = add nsw i64 %idx, 1
+  %cmp2 = icmp sgt i32 %load.src, 0
+  br i1 %cmp2, label %store.block, label %latch
+
+store.block:
+  store i32 %load.src, ptr %dst.ptr, align 4
+  br label %latch
+
+latch:
+  %phi = phi i64 [ %idx, %for.body ], [ %idx, %update.block ], [ %update, %store.block ]
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, 4096
+  br i1 %exitcond.not, label %exit, label %for.body
+
+exit:
+  ret void
+}
+
+; An unconditional increment should lower as a simple induction (not a conditional induction).
+define void @test_unconditional_increment(ptr writeonly noalias %dst, ptr readonly %src, i32 %c) {
+; CHECK-IC1-LABEL: define void @test_unconditional_increment(
+; CHECK-IC1-SAME: ptr noalias writeonly [[DST:%.*]], ptr readonly [[SRC:%.*]], i32 [[C:%.*]]) {
+; CHECK-IC1-NEXT:  [[ENTRY:.*:]]
+; CHECK-IC1-NEXT:    br label %[[VECTOR_PH:.*]]
+; CHECK-IC1:       [[VECTOR_PH]]:
+; CHECK-IC1-NEXT:    br label %[[VECTOR_BODY:.*]]
+; CHECK-IC1:       [[VECTOR_BODY]]:
+; CHECK-IC1-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
+; CHECK-IC1-NEXT:    [[TMP0:%.*]] = add i64 15, [[INDEX]]
+; CHECK-IC1-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[INDEX]]
+; CHECK-IC1-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP1]], align 4
+; CHECK-IC1-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[TMP0]]
+; CHECK-IC1-NEXT:    store <4 x i32> [[WIDE_LOAD]], ptr [[TMP2]], align 4
+; CHECK-IC1-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
+; CHECK-IC1-NEXT:    [[TMP3:%.*]] = icmp eq i64 [[INDEX_NEXT]], 4096
+; CHECK-IC1-NEXT:    br i1 [[TMP3]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
+; CHECK-IC1:       [[MIDDLE_BLOCK]]:
+; CHECK-IC1-NEXT:    br label %[[EXIT:.*]]
+; CHECK-IC1:       [[EXIT]]:
+; CHECK-IC1-NEXT:    ret void
+;
+; CHECK-TF-LABEL: define void @test_unconditional_increment(
+; CHECK-TF-SAME: ptr noalias writeonly [[DST:%.*]], ptr readonly [[SRC:%.*]], i32 [[C:%.*]]) {
+; CHECK-TF-NEXT:  [[ENTRY:.*:]]
+; CHECK-TF-NEXT:    br label %[[VECTOR_PH:.*]]
+; CHECK-TF:       [[VECTOR_PH]]:
+; CHECK-TF-NEXT:    br label %[[VECTOR_BODY:.*]]
+; CHECK-TF:       [[VECTOR_BODY]]:
+; CHECK-TF-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
+; CHECK-TF-NEXT:    [[TMP0:%.*]] = add i64 15, [[INDEX]]
+; CHECK-TF-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[INDEX]]
+; CHECK-TF-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP1]], align 4
+; CHECK-TF-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[TMP0]]
+; CHECK-TF-NEXT:    store <4 x i32> [[WIDE_LOAD]], ptr [[TMP2]], align 4
+; CHECK-TF-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
+; CHECK-TF-NEXT:    [[TMP3:%.*]] = icmp eq i64 [[INDEX_NEXT]], 4096
+; CHECK-TF-NEXT:    br i1 [[TMP3]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
+; CHECK-TF:       [[MIDDLE_BLOCK]]:
+; CHECK-TF-NEXT:    br label %[[EXIT:.*]]
+; CHECK-TF:       [[EXIT]]:
+; CHECK-TF-NEXT:    ret void
+;
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
+  %idx = phi i64 [ 15, %entry ], [ %idx.1, %for.inc ]
+  %src.ptr = getelementptr inbounds i32, ptr %src, i64 %iv
+  %load.src = load i32, ptr %src.ptr, align 4
+  %cmp = icmp slt i32 %load.src, %c
+  br label %inc.step
+
+inc.step:
+  %dst.ptr = getelementptr inbounds i32, ptr %dst, i64 %idx
+  store i32 %load.src, ptr %dst.ptr, align 4
+  %idx.next = add nsw i64 %idx, 1
+  br label %for.inc
+
+for.inc:
+  %idx.1 = phi i64 [ %idx.next, %inc.step ]
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, 4096
+  br i1 %exitcond.not, label %exit, label %for.body
+
+exit:
+  ret void
+}
+
+define void @test_multiple_conditional_inductions(ptr %dst, ptr noalias %dst2, ptr noalias %src, ptr noalias %cond, ptr noalias %cond2) {
+; CHECK-IC1-LABEL: define void @test_multiple_conditional_inductions(
+; CHECK-IC1-SAME: ptr [[DST:%.*]], ptr noalias [[DST2:%.*]], ptr noalias [[SRC:%.*]], ptr noalias [[COND:%.*]], ptr noalias [[COND2:%.*]]) {
+; CHECK-IC1-NEXT:  [[VECTOR_PH:.*]]:
+; CHECK-IC1-NEXT:    br label %[[VECTOR_BODY:.*]]
+; CHECK-IC1:       [[VECTOR_BODY]]:
+; CHECK-IC1-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[IV_NEXT:%.*]], %[[EXIT:.*]] ]
+; CHECK-IC1-NEXT:    [[CONDITIONAL_IV:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[DST_INC:%.*]], %[[EXIT]] ]
+; CHECK-IC1-NEXT:    [[DST2_IDX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[DST2_INC:%.*]], %[[EXIT]] ]
+; CHECK-IC1-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[COND]], i64 [[INDEX]]
+; CHECK-IC1-NEXT:    [[COND_VAL:%.*]] = load i32, ptr [[TMP0]], align 4
+; CHECK-IC1-NEXT:    [[COND_IS_ZERO:%.*]] = icmp eq i32 [[COND_VAL]], 0
+; CHECK-IC1-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[INDEX]]
+; CHECK-IC1-NEXT:    [[SRC_VAL:%.*]] = load i32, ptr [[TMP2]], align 4
+; CHECK-IC1-NEXT:    br i1 [[COND_IS_ZERO]], label %[[IF_END:.*]], label %[[IF_THEN0:.*]]
+; CHECK-IC1:       [[IF_THEN0]]:
+; CHECK-IC1-NEXT:    [[DST_IDX_NEXT:%.*]] = add nsw i64 [[CONDITIONAL_IV]], 1
+; CHECK-IC1-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 [[CONDITIONAL_IV]]
+; CHECK-IC1-NEXT:    [[DST_VAL_TRUNC:%.*]] = trunc i32 [[SRC_VAL]] to i8
+; CHECK-IC1-NEXT:    store i8 [[DST_VAL_TRUNC]], ptr [[TMP3]], align 1
+; CHECK-IC1-NEXT:    br label %[[IF_END]]
+; CHECK-IC1:       [[IF_END]]:
+; CHECK-IC1-NEXT:    [[DST_INC]] = phi i64 [ [[DST_IDX_NEXT]], %[[IF_THEN0]] ], [ [[CONDITIONAL_IV]], %[[VECTOR_BODY]] ]
+; CHECK-IC1-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i32, ptr [[COND2]], i64 [[INDEX]]
+; CHECK-IC1-NEXT:    [[COND2_VAL:%.*]] = load i32, ptr [[TMP7]], align 4
+; CHECK-IC1-NEXT:    [[COND2_IS_ZERO:%.*]] = icmp eq i32 [[COND2_VAL]], 0
+; CHECK-IC1-NEXT:    br i1 [[COND2_IS_ZERO]], label %[[EXIT]], label %[[MIDDLE_BLOCK:.*]]
+; CHECK-IC1:       [[MIDDLE_BLOCK]]:
+; CHECK-IC1-NEXT:    [[DST2_VAL_TRUNC:%.*]] = trunc i32 [[SRC_VAL]] to i16
+; CHECK-IC1-NEXT:    [[DST2_IDX_NEXT:%.*]] = add nsw i64 [[DST2_IDX]], 1
+; CHECK-IC1-NEXT:    [[DST2_GEP:%.*]] = getelementptr inbounds i16, ptr [[DST2]], i64 [[DST2_IDX]]
+; CHECK-IC1-NEXT:    store i16 [[DST2_VAL_TRUNC]], ptr [[DST2_GEP]], align 2
+; CHECK-IC1-NEXT:    br label %[[EXIT]]
+; CHECK-IC1:       [[EXIT]]:
+; CHECK-IC1-NEXT:    [[DST2_INC]] = phi i64 [ [[DST2_IDX_NEXT]], %[[MIDDLE_BLOCK]] ], [ [[DST2_IDX]], %[[IF_END]] ]
+; CHECK-IC1-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[INDEX]], 1
+; CHECK-IC1-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 4096
+; CHECK-IC1-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT1:.*]], label %[[VECTOR_BODY]]
+; CHECK-IC1:       [[EXIT1]]:
+; CHECK-IC1-NEXT:    ret void
+;
+; CHECK-TF-LABEL: define void @test_multiple_conditional_inductions(
+; CHECK-TF-SAME: ptr [[DST:%.*]], ptr noalias [[DST2:%.*]], ptr noalias [[SRC:%.*]], ptr noalias [[COND:%.*]], ptr noalias [[COND2:%.*]]) {
+; CHECK-TF-NEXT:  [[VECTOR_PH:.*]]:
+; CHECK-TF-NEXT:    br label %[[VECTOR_BODY:.*]]
+; CHECK-TF:       [[VECTOR_BODY]]:
+; CHECK-TF-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[IV_NEXT:%.*]], %[[EXIT:.*]] ]
+; CHECK-TF-NEXT:    [[CONDITIONAL_IV:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[DST_INC:%.*]], %[[EXIT]] ]
+; CHECK-TF-NEXT:    [[DST2_IDX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[DST2_INC:%.*]], %[[EXIT]] ]
+; CHECK-TF-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[COND]], i64 [[INDEX]]
+; CHECK-TF-NEXT:    [[COND_VAL:%.*]] = load i32, ptr [[TMP0]], align 4
+; CHECK-TF-NEXT:    [[COND_IS_ZERO:%.*]] = icmp eq i32 [[COND_VAL]], 0
+; CHECK-TF-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[INDEX]]
+; CHECK-TF-NEXT:    [[SRC_VAL:%.*]] = load i32, ptr [[TMP2]], align 4
+; CHECK-TF-NEXT:    br i1 [[COND_IS_ZERO]], label %[[IF_END:.*]], label %[[IF_THEN0:.*]]
+; CHECK-TF:       [[IF_THEN0]]:
+; CHECK-TF-NEXT:    [[DST_IDX_NEXT:%.*]] = add nsw i64 [[CONDITIONAL_IV]], 1
+; CHECK-TF-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 [[CONDITIONAL_IV]]
+; CHECK-TF-NEXT:    [[DST_VAL_TRUNC:%.*]] = trunc i32 [[SRC_VAL]] to i8
+; CHECK-TF-NEXT:    store i8 [[DST_VAL_TRUNC]], ptr [[TMP3]], align 1
+; CHECK-TF-NEXT:    br label %[[IF_END]]
+; CHECK-TF:       [[IF_END]]:
+; CHECK-TF-NEXT:    [[DST_INC]] = phi i64 [ [[DST_IDX_NEXT]], %[[IF_THEN0]] ], [ [[CONDITIONAL_IV]], %[[VECTOR_BODY]] ]
+; CHECK-TF-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i32, ptr [[COND2]], i64 [[INDEX]]
+; CHECK-TF-NEXT:    [[COND2_VAL:%.*]] = load i32, ptr [[TMP7]], align 4
+; CHECK-TF-NEXT:    [[COND2_IS_ZERO:%.*]] = icmp eq i32 [[COND2_VAL]], 0
+; CHECK-TF-NEXT:    br i1 [[COND2_IS_ZERO]], label %[[EXIT]], label %[[MIDDLE_BLOCK:.*]]
+; CHECK-TF:       [[MIDDLE_BLOCK]]:
+; CHECK-TF-NEXT:    [[DST2_VAL_TRUNC:%.*]] = trunc i32 [[SRC_VAL]] to i16
+; CHECK-TF-NEXT:    [[DST2_IDX_NEXT:%.*]] = add nsw i64 [[DST2_IDX]], 1
+; CHECK-TF-NEXT:    [[DST2_GEP:%.*]] = getelementptr inbounds i16, ptr [[DST2]], i64 [[DST2_IDX]]
+; CHECK-TF-NEXT:    store i16 [[DST2_VAL_TRUNC]], ptr [[DST2_GEP]], align 2
+; CHECK-TF-NEXT:    br label %[[EXIT]]
+; CHECK-TF:       [[EXIT]]:
+; CHECK-TF-NEXT:    [[DST2_INC]] = phi i64 [ [[DST2_IDX_NEXT]], %[[MIDDLE_BLOCK]] ], [ [[DST2_IDX]], %[[IF_END]] ]
+; CHECK-TF-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[INDEX]], 1
+; CHECK-TF-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 4096
+; CHECK-TF-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT1:.*]], label %[[VECTOR_BODY]]
+; CHECK-TF:       [[EXIT1]]:
+; CHECK-TF-NEXT:    ret void
+;
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
+  %dst.idx = phi i64 [ 0, %entry ], [ %dst.inc, %for.inc ]
+  %dst2.idx = phi i64 [ 0, %entry ], [ %dst2.inc, %for.inc ]
+  %cond.gep = getelementptr inbounds i32, ptr %cond, i64 %iv
+  %cond.val = load i32, ptr %cond.gep, align 4
+  %cond.is.zero = icmp eq i32 %cond.val, 0
+  %src.gep = getelementptr inbounds i32, ptr %src, i64 %iv
+  %src.val = load i32, ptr %src.gep, align 4
+  br i1 %cond.is.zero, label %if.end, label %if.then0
+
+if.then0:
+  %dst.idx.next = add nsw i64 %dst.idx, 1
+  %dst.gep = getelementptr inbounds i8, ptr %dst, i64 %dst.idx
+  %dst.val.trunc = trunc i32 %src.val to i8
+  store i8 %dst.val.trunc, ptr %dst.gep, align 1
+  br label %if.end
+
+if.end:
+  %dst.inc = phi i64 [ %dst.idx.next, %if.then0 ], [ %dst.idx, %for.body ]
+  %cond2.gep = getelementptr inbounds i32, ptr %cond2, i64 %iv
+  %cond2.val = load i32, ptr %cond2.gep, align 4
+  %cond2.is.zero = icmp eq i32 %cond2.val, 0
+  br i1 %cond2.is.zero, label %for.inc, label %if.then1
+
+if.then1:
+  %dst2.val.trunc = trunc i32 %src.val to i16
+  %dst2.idx.next = add nsw i64 %dst2.idx, 1
+  %dst2.gep = getelementptr inbounds i16, ptr %dst2, i64 %dst2.idx
+  store i16 %dst2.val.trunc, ptr %dst2.gep, align 2
+  br label %for.inc
+
+for.inc:
+  %dst2.inc = phi i64 [ %dst2.idx.next, %if.then1 ], [ %dst2.idx, %if.end ]
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, 4096
+  br i1 %exitcond.not, label %exit, label %for.body
+
+exit:
+  ret void
+}
+
+; Test expand load with always false update (this probably can be simplified).
+define void @test_expand_load_always_false_cond(ptr noalias %dst, ptr readonly %src, i32 %c) {
+; CHECK-IC1-LABEL: define void @test_expand_load_always_false_cond(
+; CHECK-IC1-SAME: ptr noalias [[DST:%.*]], ptr readonly [[SRC:%.*]], i32 [[C:%.*]]) {
+; CHECK-IC1-NEXT:  [[ENTRY:.*]]:
+; CHECK-IC1-NEXT:    br label %[[VECTOR_PH:.*]]
+; CHECK-IC1:       [[VECTOR_PH]]:
+; CHECK-IC1-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[EXIT:.*]] ]
+; CHECK-IC1-NEXT:    [[CONDITIONAL_IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IDX_1:%.*]], %[[EXIT]] ]
+; CHECK-IC1-NEXT:    [[DST_PTR:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]]
+; CHECK-IC1-NEXT:    [[LOAD_DST:%.*]] = load i32, ptr [[DST_PTR]], align 4
+; CHECK-IC1-NEXT:    br i1 false, label %[[VECTOR_BODY:.*]], label %[[EXIT]]
+; CHECK-IC1:       [[VECTOR_BODY]]:
+; CHECK-IC1-NEXT:    [[TMP1:%.*]] = sext i32 [[CONDITIONAL_IV]] to i64
+; CHECK-IC1-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[TMP1]]
+; CHECK-IC1-NEXT:    [[LOAD_SRC:%.*]] = load i32, ptr [[TMP2]], align 4
+; CHECK-IC1-NEXT:    store i32 [[LOAD_SRC]], ptr [[DST_PTR]], align 4
+; CHECK-IC1-NEXT:    [[IDX_NEXT:%.*]] = add nsw i32 [[CONDITIONAL_IV]], 1
+; CHECK-IC1-NEXT:    br label %[[EXIT]]
+; CHECK-IC1:       [[EXIT]]:
+; CHECK-IC1-NEXT:    [[IDX_1]] = phi i32 [ [[IDX_NEXT]], %[[VECTOR_BODY]] ], [ [[CONDITIONAL_IV]], %[[VECTOR_PH]] ]
+; CHECK-IC1-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
+; CHECK-IC1-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 4096
+; CHECK-IC1-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT1:.*]], label %[[VECTOR_PH]]
+; CHECK-IC1:       [[EXIT1]]:
+; CHECK-IC1-NEXT:    ret void
+;
+; CHECK-TF-LABEL: define void @test_expand_load_always_false_cond(
+; CHECK-TF-SAME: ptr noalias [[DST:%.*]], ptr readonly [[SRC:%.*]], i32 [[C:%.*]]) {
+; CHECK-TF-NEXT:  [[ENTRY:.*]]:
+; CHECK-TF-NEXT:    br label %[[VECTOR_PH:.*]]
+; CHECK-TF:       [[VECTOR_PH]]:
+; CHECK-TF-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[EXIT:.*]] ]
+; CHECK-TF-NEXT:    [[CONDITIONAL_IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IDX_1:%.*]], %[[EXIT]] ]
+; CHECK-TF-NEXT:    [[DST_PTR:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]]
+; CHECK-TF-NEXT:    [[LOAD_DST:%.*]] = load i32, ptr [[DST_PTR]], align 4
+; CHECK-TF-NEXT:    br i1 false, label %[[VECTOR_BODY:.*]], label %[[EXIT]]
+; CHECK-TF:       [[VECTOR_BODY]]:
+; CHECK-TF-NEXT:    [[TMP1:%.*]] = sext i32 [[CONDITIONAL_IV]] to i64
+; CHECK-TF-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[TMP1]]
+; CHECK-TF-NEXT:    [[LOAD_SRC:%.*]] = load i32, ptr [[TMP2]], align 4
+; CHECK-TF-NEXT:    store i32 [[LOAD_SRC]], ptr [[DST_PTR]], align 4
+; CHECK-TF-NEXT:    [[IDX_NEXT:%.*]] = add nsw i32 [[CONDITIONAL_IV]], 1
+; CHECK-TF-NEXT:    br label %[[EXIT]]
+; CHECK-TF:       [[EXIT]]:
+; CHECK-TF-NEXT:    [[IDX_1]] = phi i32 [ [[IDX_NEXT]], %[[VECTOR_BODY]] ], [ [[CONDITIONAL_IV]], %[[VECTOR_PH]] ]
+; CHECK-TF-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
+; CHECK-TF-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 4096
+; CHECK-TF-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT1:.*]], label %[[VECTOR_PH]]
+; CHECK-TF:       [[EXIT1]]:
+; CHECK-TF-NEXT:    ret void
+;
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
+  %idx = phi i32 [ 0, %entry ], [ %idx.1, %for.inc ]
+  %dst.ptr = getelementptr inbounds i32, ptr %dst, i64 %iv
+  %load.dst = load i32, ptr %dst.ptr, align 4
+  br i1 0, label %if.then, label %for.inc
+
+if.then:
+  %src.idx = sext i32 %idx to i64
+  %src.ptr = getelementptr inbounds i32, ptr %src, i64 %src.idx
+  %load.src = load i32, ptr %src.ptr, align 4
+  store i32 %load.src, ptr %dst.ptr, align 4
+  %idx.next = add nsw i32 %idx, 1
+  br label %for.inc
+
+for.inc:
+  %idx.1 = phi i32 [ %idx.next, %if.then ], [ %idx, %for.body ]
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, 4096
+  br i1 %exitcond.not, label %exit, label %for.body
+
+exit:
+  ret void
+}
diff --git a/llvm/test/Transforms/LoopVectorize/compress-store-vec-epilogue.ll b/llvm/test/Transforms/LoopVectorize/compress-store-vec-epilogue.ll
new file mode 100644
index 0000000000000..a41fadcba5168
--- /dev/null
+++ b/llvm/test/Transforms/LoopVectorize/compress-store-vec-epilogue.ll
@@ -0,0 +1,54 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 5
+; RUN: opt < %s -force-target-supports-masked-memory-ops -force-vector-width=16 -epilogue-vectorization-force-VF=4  -passes=loop-vectorize -S 2>&1 | FileCheck %s -check-prefixes=CHECK
+
+define void @compress_store(ptr writeonly noalias %dst, ptr readonly %src, i32 %c) {
+; CHECK-LABEL: define void @compress_store(
+; CHECK-SAME: ptr noalias writeonly [[DST:%.*]], ptr readonly [[SRC:%.*]], i32 [[C:%.*]]) {
+; CHECK-NEXT:  [[VEC_EPILOG_SCALAR_PH:.*]]:
+; CHECK-NEXT:    br label %[[FOR_BODY:.*]]
+; CHECK:       [[FOR_BODY]]:
+; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[VEC_EPILOG_SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[FOR_INC:.*]] ]
+; CHECK-NEXT:    [[IDX:%.*]] = phi i64 [ 42, %[[VEC_EPILOG_SCALAR_PH]] ], [ [[IDX_1:%.*]], %[[FOR_INC]] ]
+; CHECK-NEXT:    [[SRC_PTR:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[IV]]
+; CHECK-NEXT:    [[LOAD_SRC:%.*]] = load i32, ptr [[SRC_PTR]], align 4
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[LOAD_SRC]], [[C]]
+; CHECK-NEXT:    br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[FOR_INC]]
+; CHECK:       [[IF_THEN]]:
+; CHECK-NEXT:    [[DST_PTR:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IDX]]
+; CHECK-NEXT:    store i32 [[LOAD_SRC]], ptr [[DST_PTR]], align 4
+; CHECK-NEXT:    [[IDX_NEXT:%.*]] = add nsw i64 [[IDX]], 1
+; CHECK-NEXT:    br label %[[FOR_INC]]
+; CHECK:       [[FOR_INC]]:
+; CHECK-NEXT:    [[IDX_1]] = phi i64 [ [[IDX_NEXT]], %[[IF_THEN]] ], [ [[IDX]], %[[FOR_BODY]] ]
+; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
+; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 4110
+; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[FOR_BODY]]
+; CHECK:       [[EXIT]]:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
+  %idx = phi i64 [ 42, %entry ], [ %idx.1, %for.inc ]
+  %src.ptr = getelementptr inbounds i32, ptr %src, i64 %iv
+  %load.src = load i32, ptr %src.ptr, align 4
+  %cmp = icmp slt i32 %load.src, %c
+  br i1 %cmp, label %if.then, label %for.inc
+
+if.then:
+  %dst.ptr = getelementptr inbounds i32, ptr %dst, i64 %idx
+  store i32 %load.src, ptr %dst.ptr, align 4
+  %idx.next = add nsw i64 %idx, 1
+  br label %for.inc
+
+for.inc:
+  %idx.1 = phi i64 [ %idx.next, %if.then ], [ %idx, %for.body ]
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, 4110
+  br i1 %exitcond.not, label %exit, label %for.body
+
+exit:
+  ret void
+}

>From 546ac6312b95cfacd37574db964046ff167a7aef Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Mon, 21 Sep 2026 16:50:46 +0000
Subject: [PATCH 2/2] Fixups

---
 .../Transforms/LoopVectorize/AArch64/compress-idioms.ll   | 4 ++--
 .../Transforms/LoopVectorize/RISCV/compress-idioms.ll     | 4 ++--
 llvm/test/Transforms/LoopVectorize/X86/compress-idioms.ll | 8 ++++----
 .../LoopVectorize/compress-idioms-negative-tests.ll       | 1 +
 llvm/test/Transforms/LoopVectorize/compress-idioms.ll     | 6 +++---
 .../LoopVectorize/compress-store-vec-epilogue.ll          | 4 ++--
 6 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/compress-idioms.ll b/llvm/test/Transforms/LoopVectorize/AArch64/compress-idioms.ll
index 2a0b26b991dcc..ad8878ca635eb 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/compress-idioms.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/compress-idioms.ll
@@ -1,5 +1,5 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --filter-out-after "^scalar.ph:" --version 5
-; RUN: opt < %s -mtriple=aarch64 -mattr=+sve2p2 -passes=loop-vectorize -S 2>&1 | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --filter-out-after "^scalar.ph:" --version 6
+; RUN: opt < %s -mtriple=aarch64 -mattr=+sve2p2 -passes=loop-vectorize -S | FileCheck %s
 
 ; SVE compresstore/expandload vectorization (requires +sve2p2 for expandload and +sve for compresstore).
 
diff --git a/llvm/test/Transforms/LoopVectorize/RISCV/compress-idioms.ll b/llvm/test/Transforms/LoopVectorize/RISCV/compress-idioms.ll
index 1b4f36d8e4e11..3bc2fe5804c74 100644
--- a/llvm/test/Transforms/LoopVectorize/RISCV/compress-idioms.ll
+++ b/llvm/test/Transforms/LoopVectorize/RISCV/compress-idioms.ll
@@ -1,5 +1,5 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --filter-out-after "^scalar.ph:" --version 5
-; RUN: opt < %s -mtriple=riscv64 -mattr=+v -passes=loop-vectorize -S 2>&1 | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --filter-out-after "^scalar.ph:" --version 6
+; RUN: opt < %s -mtriple=riscv64 -mattr=+v -passes=loop-vectorize -S | FileCheck %s
 
 define void @compress_store(ptr writeonly noalias %dst, ptr readonly %src, i32 %c, i64 %n) {
 ; CHECK-LABEL: define void @compress_store(
diff --git a/llvm/test/Transforms/LoopVectorize/X86/compress-idioms.ll b/llvm/test/Transforms/LoopVectorize/X86/compress-idioms.ll
index 360392a834c2b..99b5c4736dad6 100644
--- a/llvm/test/Transforms/LoopVectorize/X86/compress-idioms.ll
+++ b/llvm/test/Transforms/LoopVectorize/X86/compress-idioms.ll
@@ -1,7 +1,7 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --filter-out-after "^scalar.ph:" --version 5
-; RUN: opt < %s -mtriple=x86_64-- -mcpu=x86-64-v4 -passes=loop-vectorize -S 2>&1 | FileCheck %s --check-prefix=CHECK-V4
-; RUN: opt < %s -mtriple=x86_64-- -mcpu=icelake-server -passes=loop-vectorize -S 2>&1 | FileCheck %s --check-prefix=CHECK-ICELAKE
-; RUN: opt < %s -mtriple=x86_64-- -mcpu=znver4 -passes=loop-vectorize -S 2>&1 | FileCheck %s --check-prefix=CHECK-ZNVER4
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --filter-out-after "^scalar.ph:" --version 6
+; RUN: opt < %s -mtriple=x86_64-- -mcpu=x86-64-v4 -passes=loop-vectorize -S | FileCheck %s --check-prefix=CHECK-V4
+; RUN: opt < %s -mtriple=x86_64-- -mcpu=icelake-server -passes=loop-vectorize -S | FileCheck %s --check-prefix=CHECK-ICELAKE
+; RUN: opt < %s -mtriple=x86_64-- -mcpu=znver4 -passes=loop-vectorize -S | FileCheck %s --check-prefix=CHECK-ZNVER4
 
 define void @compress_store(ptr writeonly noalias %dst, ptr readonly %src, i32 %c, i64 %n) {
 ; CHECK-V4-LABEL: define void @compress_store(
diff --git a/llvm/test/Transforms/LoopVectorize/compress-idioms-negative-tests.ll b/llvm/test/Transforms/LoopVectorize/compress-idioms-negative-tests.ll
index 375e77b2de482..da3d76cdadb1a 100644
--- a/llvm/test/Transforms/LoopVectorize/compress-idioms-negative-tests.ll
+++ b/llvm/test/Transforms/LoopVectorize/compress-idioms-negative-tests.ll
@@ -1,3 +1,4 @@
+; REQUIRES: asserts
 ; RUN: opt < %s -enable-early-exit-vectorization-with-side-effects -force-target-supports-masked-memory-ops -force-vector-width=4 -passes=loop-vectorize -disable-output -pass-remarks-missed=".*" 2>&1 | FileCheck %s
 
 ; CHECK: loop not vectorized
diff --git a/llvm/test/Transforms/LoopVectorize/compress-idioms.ll b/llvm/test/Transforms/LoopVectorize/compress-idioms.ll
index 460471cffa1c9..c0dbd746fc997 100644
--- a/llvm/test/Transforms/LoopVectorize/compress-idioms.ll
+++ b/llvm/test/Transforms/LoopVectorize/compress-idioms.ll
@@ -1,6 +1,6 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 5
-; RUN: opt < %s -force-target-supports-masked-memory-ops -force-vector-width=4 -passes=loop-vectorize -S 2>&1 | FileCheck %s -check-prefix=CHECK-IC1
-; RUN: opt < %s -force-target-supports-masked-memory-ops -force-vector-width=4 -tail-folding-policy=must-fold-tail -passes=loop-vectorize -S 2>&1 | FileCheck %s -check-prefix=CHECK-TF
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 6
+; RUN: opt < %s -force-target-supports-masked-memory-ops -force-vector-width=4 -passes=loop-vectorize -S | FileCheck %s -check-prefix=CHECK-IC1
+; RUN: opt < %s -force-target-supports-masked-memory-ops -force-vector-width=4 -tail-folding-policy=must-fold-tail -passes=loop-vectorize -S | FileCheck %s -check-prefix=CHECK-TF
 
 define void @test_compress_store_with_index(ptr writeonly noalias %dst, ptr readonly %src, i32 %c) {
 ; CHECK-IC1-LABEL: define void @test_compress_store_with_index(
diff --git a/llvm/test/Transforms/LoopVectorize/compress-store-vec-epilogue.ll b/llvm/test/Transforms/LoopVectorize/compress-store-vec-epilogue.ll
index a41fadcba5168..3932acd2f2a3f 100644
--- a/llvm/test/Transforms/LoopVectorize/compress-store-vec-epilogue.ll
+++ b/llvm/test/Transforms/LoopVectorize/compress-store-vec-epilogue.ll
@@ -1,5 +1,5 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 5
-; RUN: opt < %s -force-target-supports-masked-memory-ops -force-vector-width=16 -epilogue-vectorization-force-VF=4  -passes=loop-vectorize -S 2>&1 | FileCheck %s -check-prefixes=CHECK
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 6
+; RUN: opt < %s -force-target-supports-masked-memory-ops -force-vector-width=16 -epilogue-vectorization-force-VF=4  -passes=loop-vectorize -S | FileCheck %s -check-prefixes=CHECK
 
 define void @compress_store(ptr writeonly noalias %dst, ptr readonly %src, i32 %c) {
 ; CHECK-LABEL: define void @compress_store(



More information about the llvm-commits mailing list