[llvm] [VectorCombine][TTI] Prevent extract/ins rewrite to GEP (PR #150216)

Nathan Gauër via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 31 04:19:35 PDT 2025


https://github.com/Keenuts updated https://github.com/llvm/llvm-project/pull/150216

>From 301305e4c4b16836c38927c85e14105d12bca069 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= <brioche at google.com>
Date: Wed, 23 Jul 2025 14:43:41 +0200
Subject: [PATCH 1/6] [VectorCombine] Prevent extract/ins rewrite to GEP

Using GEP to index into a vector is not disallowed, but not
recommended.
The SPIR-V backend needs to generate structured access into types,
which is impossible with an untyped GEP instruction unless we add
more info to the IR. Finding a solution is a work-in-progress, but
in the meantime, we'd like to reduce the amount of failures.

Preventing this optimizations from rewritting extract/insert
instructions into a GEP helps us lower more code to SPIR-V.
This change should be OK as it's only active when targeting SPIR-V and
disabling a non-recommended transformation.

Related to #145002
---
 .../Transforms/Vectorize/VectorCombine.cpp    |  11 +-
 .../VectorCombine/load-insert-store.ll        | 382 ++++++++++++++++++
 2 files changed, 389 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
index 6252f4f0507cb..3752d9d88129d 100644
--- a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
+++ b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
@@ -3866,8 +3866,9 @@ bool VectorCombine::run() {
 
   LLVM_DEBUG(dbgs() << "\n\nVECTORCOMBINE on " << F.getName() << "\n");
 
+  const bool isSPIRV = F.getParent()->getTargetTriple().isSPIRV();
   bool MadeChange = false;
-  auto FoldInst = [this, &MadeChange](Instruction &I) {
+  auto FoldInst = [this, &MadeChange, isSPIRV](Instruction &I) {
     Builder.SetInsertPoint(&I);
     bool IsVectorType = isa<VectorType>(I.getType());
     bool IsFixedVectorType = isa<FixedVectorType>(I.getType());
@@ -3896,13 +3897,15 @@ bool VectorCombine::run() {
     // TODO: Identify and allow other scalable transforms
     if (IsVectorType) {
       MadeChange |= scalarizeOpOrCmp(I);
-      MadeChange |= scalarizeLoadExtract(I);
-      MadeChange |= scalarizeExtExtract(I);
+      if (!isSPIRV) {
+        MadeChange |= scalarizeLoadExtract(I);
+        MadeChange |= scalarizeExtExtract(I);
+      }
       MadeChange |= scalarizeVPIntrinsic(I);
       MadeChange |= foldInterleaveIntrinsics(I);
     }
 
-    if (Opcode == Instruction::Store)
+    if (Opcode == Instruction::Store && !isSPIRV)
       MadeChange |= foldSingleElementStore(I);
 
     // If this is an early pipeline invocation of this pass, we are done.
diff --git a/llvm/test/Transforms/VectorCombine/load-insert-store.ll b/llvm/test/Transforms/VectorCombine/load-insert-store.ll
index 93565c1a708eb..0181ec76088bd 100644
--- a/llvm/test/Transforms/VectorCombine/load-insert-store.ll
+++ b/llvm/test/Transforms/VectorCombine/load-insert-store.ll
@@ -1,6 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt -S -passes=vector-combine -data-layout=e < %s | FileCheck %s
 ; RUN: opt -S -passes=vector-combine -data-layout=E < %s | FileCheck %s
+; RUN: opt -S -passes=vector-combine -data-layout=E -mtriple=spirv-unknown-vulkan1.3-library %s | FileCheck %s --check-prefix=SPIRV
 
 define void @insert_store(ptr %q, i8 zeroext %s) {
 ; CHECK-LABEL: @insert_store(
@@ -9,6 +10,13 @@ define void @insert_store(ptr %q, i8 zeroext %s) {
 ; CHECK-NEXT:    store i8 [[S:%.*]], ptr [[TMP0]], align 1
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 3
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <16 x i8>, ptr %q
   %vecins = insertelement <16 x i8> %0, i8 %s, i32 3
@@ -23,6 +31,13 @@ define void @insert_store_i16_align1(ptr %q, i16 zeroext %s) {
 ; CHECK-NEXT:    store i16 [[S:%.*]], ptr [[TMP0]], align 2
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_i16_align1(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <8 x i16>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <8 x i16> [[TMP0]], i16 [[S:%.*]], i32 3
+; SPIRV-NEXT:    store <8 x i16> [[VECINS]], ptr [[Q]], align 1
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <8 x i16>, ptr %q
   %vecins = insertelement <8 x i16> %0, i16 %s, i32 3
@@ -39,6 +54,13 @@ define void @insert_store_outofbounds(ptr %q, i16 zeroext %s) {
 ; CHECK-NEXT:    store <8 x i16> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_outofbounds(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <8 x i16>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <8 x i16> [[TMP0]], i16 [[S:%.*]], i32 9
+; SPIRV-NEXT:    store <8 x i16> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <8 x i16>, ptr %q
   %vecins = insertelement <8 x i16> %0, i16 %s, i32 9
@@ -53,6 +75,13 @@ define void @insert_store_vscale(ptr %q, i16 zeroext %s) {
 ; CHECK-NEXT:    store i16 [[S:%.*]], ptr [[TMP0]], align 2
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_vscale(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <vscale x 8 x i16>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <vscale x 8 x i16> [[TMP0]], i16 [[S:%.*]], i32 3
+; SPIRV-NEXT:    store <vscale x 8 x i16> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <vscale x 8 x i16>, ptr %q
   %vecins = insertelement <vscale x 8 x i16> %0, i16 %s, i32 3
@@ -70,6 +99,13 @@ define void @insert_store_vscale_exceeds(ptr %q, i16 zeroext %s) {
 ; CHECK-NEXT:    store <vscale x 8 x i16> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_vscale_exceeds(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <vscale x 8 x i16>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <vscale x 8 x i16> [[TMP0]], i16 [[S:%.*]], i32 9
+; SPIRV-NEXT:    store <vscale x 8 x i16> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <vscale x 8 x i16>, ptr %q
   %vecins = insertelement <vscale x 8 x i16> %0, i16 %s, i32 9
@@ -85,6 +121,13 @@ define void @insert_store_v9i4(ptr %q, i4 zeroext %s) {
 ; CHECK-NEXT:    store <9 x i4> [[VECINS]], ptr [[Q]], align 1
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_v9i4(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <9 x i4>, ptr [[Q:%.*]], align 8
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <9 x i4> [[TMP0]], i4 [[S:%.*]], i32 3
+; SPIRV-NEXT:    store <9 x i4> [[VECINS]], ptr [[Q]], align 1
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <9 x i4>, ptr %q
   %vecins = insertelement <9 x i4> %0, i4 %s, i32 3
@@ -100,6 +143,13 @@ define void @insert_store_v4i27(ptr %q, i27 zeroext %s) {
 ; CHECK-NEXT:    store <4 x i27> [[VECINS]], ptr [[Q]], align 1
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_v4i27(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <4 x i27>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <4 x i27> [[TMP0]], i27 [[S:%.*]], i32 3
+; SPIRV-NEXT:    store <4 x i27> [[VECINS]], ptr [[Q]], align 1
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <4 x i27>, ptr %q
   %vecins = insertelement <4 x i27> %0, i27 %s, i32 3
@@ -113,6 +163,12 @@ define void @insert_store_v32i1(ptr %p) {
 ; CHECK-NEXT:    [[INS:%.*]] = insertelement <32 x i1> [[VEC]], i1 true, i64 0
 ; CHECK-NEXT:    store <32 x i1> [[INS]], ptr [[P]], align 4
 ; CHECK-NEXT:    ret void
+;
+; SPIRV-LABEL: @insert_store_v32i1(
+; SPIRV-NEXT:    [[VEC:%.*]] = load <32 x i1>, ptr [[P:%.*]], align 4
+; SPIRV-NEXT:    [[INS:%.*]] = insertelement <32 x i1> [[VEC]], i1 true, i64 0
+; SPIRV-NEXT:    store <32 x i1> [[INS]], ptr [[P]], align 4
+; SPIRV-NEXT:    ret void
 ;
   %vec = load <32 x i1>, ptr %p
   %ins = insertelement <32 x i1> %vec, i1 true, i64 0
@@ -130,6 +186,15 @@ define void @insert_store_blk_differ(ptr %q, i16 zeroext %s) {
 ; CHECK-NEXT:    store <8 x i16> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_blk_differ(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <8 x i16>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    br label [[CONT:%.*]]
+; SPIRV:       cont:
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <8 x i16> [[TMP0]], i16 [[S:%.*]], i32 3
+; SPIRV-NEXT:    store <8 x i16> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <8 x i16>, ptr %q
   br label %cont
@@ -147,6 +212,13 @@ define void @insert_store_nonconst(ptr %q, i8 zeroext %s, i32 %idx) {
 ; CHECK-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_nonconst(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX:%.*]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <16 x i8>, ptr %q
   %vecins = insertelement <16 x i8> %0, i8 %s, i32 %idx
@@ -164,6 +236,13 @@ define void @insert_store_vscale_nonconst(ptr %q, i8 zeroext %s, i32 %idx) {
 ; CHECK-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_vscale_nonconst(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <vscale x 16 x i8>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <vscale x 16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX:%.*]]
+; SPIRV-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <vscale x 16 x i8>, ptr %q
   %vecins = insertelement <vscale x 16 x i8> %0, i8 %s, i32 %idx
@@ -181,6 +260,15 @@ define void @insert_store_nonconst_large_alignment(ptr %q, i32 zeroext %s, i32 %
 ; CHECK-NEXT:    store i32 [[S:%.*]], ptr [[TMP0]], align 4
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_nonconst_large_alignment(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX:%.*]], 4
+; SPIRV-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; SPIRV-NEXT:    [[I:%.*]] = load <4 x i32>, ptr [[Q:%.*]], align 128
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <4 x i32> [[I]], i32 [[S:%.*]], i32 [[IDX]]
+; SPIRV-NEXT:    store <4 x i32> [[VECINS]], ptr [[Q]], align 128
+; SPIRV-NEXT:    ret void
+;
 entry:
   %cmp = icmp ult i32 %idx, 4
   call void @llvm.assume(i1 %cmp)
@@ -197,6 +285,14 @@ define void @insert_store_nonconst_align_maximum_8(ptr %q, i64 %s, i32 %idx) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds <8 x i64>, ptr [[Q:%.*]], i32 0, i32 [[IDX]]
 ; CHECK-NEXT:    store i64 [[S:%.*]], ptr [[TMP1]], align 8
 ; CHECK-NEXT:    ret void
+;
+; SPIRV-LABEL: @insert_store_nonconst_align_maximum_8(
+; SPIRV-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX:%.*]], 2
+; SPIRV-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; SPIRV-NEXT:    [[I:%.*]] = load <8 x i64>, ptr [[Q:%.*]], align 8
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <8 x i64> [[I]], i64 [[S:%.*]], i32 [[IDX]]
+; SPIRV-NEXT:    store <8 x i64> [[VECINS]], ptr [[Q]], align 8
+; SPIRV-NEXT:    ret void
 ;
   %cmp = icmp ult i32 %idx, 2
   call void @llvm.assume(i1 %cmp)
@@ -213,6 +309,14 @@ define void @insert_store_nonconst_align_maximum_4(ptr %q, i64 %s, i32 %idx) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds <8 x i64>, ptr [[Q:%.*]], i32 0, i32 [[IDX]]
 ; CHECK-NEXT:    store i64 [[S:%.*]], ptr [[TMP1]], align 4
 ; CHECK-NEXT:    ret void
+;
+; SPIRV-LABEL: @insert_store_nonconst_align_maximum_4(
+; SPIRV-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX:%.*]], 2
+; SPIRV-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; SPIRV-NEXT:    [[I:%.*]] = load <8 x i64>, ptr [[Q:%.*]], align 4
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <8 x i64> [[I]], i64 [[S:%.*]], i32 [[IDX]]
+; SPIRV-NEXT:    store <8 x i64> [[VECINS]], ptr [[Q]], align 4
+; SPIRV-NEXT:    ret void
 ;
   %cmp = icmp ult i32 %idx, 2
   call void @llvm.assume(i1 %cmp)
@@ -229,6 +333,14 @@ define void @insert_store_nonconst_align_larger(ptr %q, i64 %s, i32 %idx) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds <8 x i64>, ptr [[Q:%.*]], i32 0, i32 [[IDX]]
 ; CHECK-NEXT:    store i64 [[S:%.*]], ptr [[TMP1]], align 4
 ; CHECK-NEXT:    ret void
+;
+; SPIRV-LABEL: @insert_store_nonconst_align_larger(
+; SPIRV-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX:%.*]], 2
+; SPIRV-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; SPIRV-NEXT:    [[I:%.*]] = load <8 x i64>, ptr [[Q:%.*]], align 4
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <8 x i64> [[I]], i64 [[S:%.*]], i32 [[IDX]]
+; SPIRV-NEXT:    store <8 x i64> [[VECINS]], ptr [[Q]], align 2
+; SPIRV-NEXT:    ret void
 ;
   %cmp = icmp ult i32 %idx, 2
   call void @llvm.assume(i1 %cmp)
@@ -247,6 +359,15 @@ define void @insert_store_nonconst_index_known_valid_by_assume(ptr %q, i8 zeroex
 ; CHECK-NEXT:    store i8 [[S:%.*]], ptr [[TMP0]], align 1
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_nonconst_index_known_valid_by_assume(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX:%.*]], 4
+; SPIRV-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %cmp = icmp ult i32 %idx, 4
   call void @llvm.assume(i1 %cmp)
@@ -267,6 +388,15 @@ define void @insert_store_vscale_nonconst_index_known_valid_by_assume(ptr %q, i8
 ; CHECK-NEXT:    store i8 [[S:%.*]], ptr [[TMP0]], align 1
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_vscale_nonconst_index_known_valid_by_assume(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX:%.*]], 4
+; SPIRV-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <vscale x 16 x i8>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <vscale x 16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX]]
+; SPIRV-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %cmp = icmp ult i32 %idx, 4
   call void @llvm.assume(i1 %cmp)
@@ -289,6 +419,16 @@ define void @insert_store_nonconst_index_not_known_valid_by_assume_after_load(pt
 ; CHECK-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_nonconst_index_not_known_valid_by_assume_after_load(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX:%.*]], 4
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    call void @maythrow()
+; SPIRV-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %cmp = icmp ult i32 %idx, 4
   %0 = load <16 x i8>, ptr %q
@@ -309,6 +449,15 @@ define void @insert_store_nonconst_index_not_known_valid_by_assume(ptr %q, i8 ze
 ; CHECK-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_nonconst_index_not_known_valid_by_assume(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX:%.*]], 17
+; SPIRV-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %cmp = icmp ult i32 %idx, 17
   call void @llvm.assume(i1 %cmp)
@@ -330,6 +479,15 @@ define void @insert_store_vscale_nonconst_index_not_known_valid_by_assume(ptr %q
 ; CHECK-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_vscale_nonconst_index_not_known_valid_by_assume(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX:%.*]], 17
+; SPIRV-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <vscale x 16 x i8>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <vscale x 16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX]]
+; SPIRV-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %cmp = icmp ult i32 %idx, 17
   call void @llvm.assume(i1 %cmp)
@@ -349,6 +507,14 @@ define void @insert_store_nonconst_index_known_noundef_and_valid_by_and(ptr %q,
 ; CHECK-NEXT:    store i8 [[S:%.*]], ptr [[TMP0]], align 1
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_nonconst_index_known_noundef_and_valid_by_and(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = and i32 [[IDX:%.*]], 7
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <16 x i8>, ptr %q
   %idx.clamped = and i32 %idx, 7
@@ -367,6 +533,14 @@ define void @insert_store_vscale_nonconst_index_known_noundef_and_valid_by_and(p
 ; CHECK-NEXT:    store i8 [[S:%.*]], ptr [[TMP0]], align 1
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_vscale_nonconst_index_known_noundef_and_valid_by_and(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <vscale x 16 x i8>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = and i32 [[IDX:%.*]], 7
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <vscale x 16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <vscale x 16 x i8>, ptr %q
   %idx.clamped = and i32 %idx, 7
@@ -384,6 +558,15 @@ define void @insert_store_nonconst_index_base_frozen_and_valid_by_and(ptr %q, i8
 ; CHECK-NEXT:    store i8 [[S:%.*]], ptr [[TMP0]], align 1
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_nonconst_index_base_frozen_and_valid_by_and(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[IDX_FROZEN:%.*]] = freeze i32 [[IDX:%.*]]
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = and i32 [[IDX_FROZEN]], 7
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <16 x i8>, ptr %q
   %idx.frozen = freeze i32 %idx
@@ -403,6 +586,15 @@ define void @insert_store_nonconst_index_frozen_and_valid_by_and(ptr %q, i8 zero
 ; CHECK-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_nonconst_index_frozen_and_valid_by_and(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = and i32 [[IDX:%.*]], 7
+; SPIRV-NEXT:    [[IDX_CLAMPED_FROZEN:%.*]] = freeze i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED_FROZEN]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <16 x i8>, ptr %q
   %idx.clamped = and i32 %idx, 7
@@ -421,6 +613,14 @@ define void @insert_store_nonconst_index_known_valid_by_and_but_may_be_poison(pt
 ; CHECK-NEXT:    store i8 [[S:%.*]], ptr [[TMP0]], align 1
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_nonconst_index_known_valid_by_and_but_may_be_poison(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = and i32 [[IDX:%.*]], 7
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <16 x i8>, ptr %q
   %idx.clamped = and i32 %idx, 7
@@ -438,6 +638,14 @@ define void @insert_store_nonconst_index_not_known_valid_by_and(ptr %q, i8 zeroe
 ; CHECK-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_nonconst_index_not_known_valid_by_and(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = and i32 [[IDX:%.*]], 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <16 x i8>, ptr %q
   %idx.clamped = and i32 %idx, 16
@@ -455,6 +663,14 @@ define void @insert_store_nonconst_index_known_noundef_not_known_valid_by_and(pt
 ; CHECK-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_nonconst_index_known_noundef_not_known_valid_by_and(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = and i32 [[IDX:%.*]], 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <16 x i8>, ptr %q
   %idx.clamped = and i32 %idx, 16
@@ -474,6 +690,14 @@ define void @insert_store_vscale_nonconst_index_not_known_valid_by_and(ptr %q, i
 ; CHECK-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_vscale_nonconst_index_not_known_valid_by_and(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <vscale x 16 x i8>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = and i32 [[IDX:%.*]], 31
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <vscale x 16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <vscale x 16 x i8>, ptr %q
   %idx.clamped = and i32 %idx, 31
@@ -490,6 +714,14 @@ define void @insert_store_nonconst_index_known_noundef_and_valid_by_urem(ptr %q,
 ; CHECK-NEXT:    store i8 [[S:%.*]], ptr [[TMP0]], align 1
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_nonconst_index_known_noundef_and_valid_by_urem(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = urem i32 [[IDX:%.*]], 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <16 x i8>, ptr %q
   %idx.clamped = urem i32 %idx, 16
@@ -508,6 +740,14 @@ define void @insert_store_vscale_nonconst_index_known_noundef_and_valid_by_urem(
 ; CHECK-NEXT:    store i8 [[S:%.*]], ptr [[TMP0]], align 1
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_vscale_nonconst_index_known_noundef_and_valid_by_urem(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <vscale x 16 x i8>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = urem i32 [[IDX:%.*]], 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <vscale x 16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <vscale x 16 x i8>, ptr %q
   %idx.clamped = urem i32 %idx, 16
@@ -525,6 +765,15 @@ define void @insert_store_nonconst_index_base_frozen_and_valid_by_urem(ptr %q, i
 ; CHECK-NEXT:    store i8 [[S:%.*]], ptr [[TMP0]], align 1
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_nonconst_index_base_frozen_and_valid_by_urem(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[IDX_FROZEN:%.*]] = freeze i32 [[IDX:%.*]]
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = urem i32 [[IDX_FROZEN]], 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <16 x i8>, ptr %q
   %idx.frozen = freeze i32 %idx
@@ -544,6 +793,15 @@ define void @insert_store_nonconst_index_frozen_and_valid_by_urem(ptr %q, i8 zer
 ; CHECK-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_nonconst_index_frozen_and_valid_by_urem(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = urem i32 [[IDX:%.*]], 16
+; SPIRV-NEXT:    [[IDX_CLAMPED_FROZEN:%.*]] = freeze i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED_FROZEN]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <16 x i8>, ptr %q
   %idx.clamped = urem i32 %idx, 16
@@ -562,6 +820,14 @@ define void @insert_store_nonconst_index_known_valid_by_urem_but_may_be_poison(p
 ; CHECK-NEXT:    store i8 [[S:%.*]], ptr [[TMP0]], align 1
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_nonconst_index_known_valid_by_urem_but_may_be_poison(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = urem i32 [[IDX:%.*]], 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <16 x i8>, ptr %q
   %idx.clamped = urem i32 %idx, 16
@@ -579,6 +845,14 @@ define void @insert_store_nonconst_index_not_known_valid_by_urem(ptr %q, i8 zero
 ; CHECK-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_nonconst_index_not_known_valid_by_urem(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = urem i32 [[IDX:%.*]], 17
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <16 x i8>, ptr %q
   %idx.clamped = urem i32 %idx, 17
@@ -598,6 +872,14 @@ define void @insert_store_vscale_nonconst_index_not_known_valid_by_urem(ptr %q,
 ; CHECK-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_vscale_nonconst_index_not_known_valid_by_urem(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <vscale x 16 x i8>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = urem i32 [[IDX:%.*]], 17
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <vscale x 16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <vscale x 16 x i8>, ptr %q
   %idx.clamped = urem i32 %idx, 17
@@ -615,6 +897,14 @@ define void @insert_store_nonconst_index_known_noundef_not_known_valid_by_urem(p
 ; CHECK-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_nonconst_index_known_noundef_not_known_valid_by_urem(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = urem i32 [[IDX:%.*]], 17
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <16 x i8>, ptr %q
   %idx.clamped = urem i32 %idx, 17
@@ -630,6 +920,13 @@ define void @insert_store_ptr_strip(ptr %q, i8 zeroext %s) {
 ; CHECK-NEXT:    store i8 [[S:%.*]], ptr [[TMP0]], align 1
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_ptr_strip(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 3
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <16 x i8>, ptr %q
   %vecins = insertelement <16 x i8> %0, i8 %s, i32 3
@@ -648,6 +945,16 @@ define void @volatile_update(ptr %q, ptr %p, i8 zeroext %s) {
 ; CHECK-NEXT:    store <16 x i8> [[VECINS1]], ptr [[P]], align 16
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @volatile_update(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[VECINS0:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 3
+; SPIRV-NEXT:    store volatile <16 x i8> [[VECINS0]], ptr [[Q]], align 16
+; SPIRV-NEXT:    [[TMP1:%.*]] = load volatile <16 x i8>, ptr [[P:%.*]], align 16
+; SPIRV-NEXT:    [[VECINS1:%.*]] = insertelement <16 x i8> [[TMP1]], i8 [[S]], i32 1
+; SPIRV-NEXT:    store <16 x i8> [[VECINS1]], ptr [[P]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %0 = load <16 x i8>, ptr %q
   %vecins0 = insertelement <16 x i8> %0, i8 %s, i32 3
@@ -667,6 +974,13 @@ define void @insert_store_addr_differ(ptr %p, ptr %q, i8 %s) {
 ; CHECK-NEXT:    store <16 x i8> [[INS]], ptr [[Q:%.*]], align 16
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_addr_differ(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[LD:%.*]] = load <16 x i8>, ptr [[P:%.*]], align 16
+; SPIRV-NEXT:    [[INS:%.*]] = insertelement <16 x i8> [[LD]], i8 [[S:%.*]], i32 3
+; SPIRV-NEXT:    store <16 x i8> [[INS]], ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %ld = load <16 x i8>, ptr %p
   %ins = insertelement <16 x i8> %ld, i8 %s, i32 3
@@ -691,6 +1005,22 @@ define void @insert_store_mem_modify(ptr %p, ptr %q, ptr noalias %r, i8 %s, i32
 ; CHECK-NEXT:    store <4 x i32> [[INS3]], ptr [[P]], align 16
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_mem_modify(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[LD:%.*]] = load <16 x i8>, ptr [[P:%.*]], align 16
+; SPIRV-NEXT:    store <16 x i8> zeroinitializer, ptr [[Q:%.*]], align 16
+; SPIRV-NEXT:    [[INS:%.*]] = insertelement <16 x i8> [[LD]], i8 [[S:%.*]], i32 3
+; SPIRV-NEXT:    store <16 x i8> [[INS]], ptr [[P]], align 16
+; SPIRV-NEXT:    [[LD2:%.*]] = load <16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    store <16 x i8> zeroinitializer, ptr [[R:%.*]], align 16
+; SPIRV-NEXT:    [[INS2:%.*]] = insertelement <16 x i8> [[LD2]], i8 [[S]], i32 7
+; SPIRV-NEXT:    store <16 x i8> [[INS2]], ptr [[Q]], align 16
+; SPIRV-NEXT:    [[LD3:%.*]] = load <4 x i32>, ptr [[P]], align 16
+; SPIRV-NEXT:    store <16 x i8> zeroinitializer, ptr [[P]], align 16
+; SPIRV-NEXT:    [[INS3:%.*]] = insertelement <4 x i32> [[LD3]], i32 [[M:%.*]], i32 0
+; SPIRV-NEXT:    store <4 x i32> [[INS3]], ptr [[P]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   ; p may alias q
   %ld = load <16 x i8>, ptr %p
@@ -727,6 +1057,19 @@ define void @insert_store_with_call(ptr %p, ptr %q, i8 %s) {
 ; CHECK-NEXT:    store i8 [[S]], ptr [[TMP0]], align 1
 ; CHECK-NEXT:    ret void
 ;
+; SPIRV-LABEL: @insert_store_with_call(
+; SPIRV-NEXT:  entry:
+; SPIRV-NEXT:    [[LD:%.*]] = load <16 x i8>, ptr [[P:%.*]], align 16
+; SPIRV-NEXT:    call void @maywrite(ptr [[P]])
+; SPIRV-NEXT:    [[INS:%.*]] = insertelement <16 x i8> [[LD]], i8 [[S:%.*]], i32 3
+; SPIRV-NEXT:    store <16 x i8> [[INS]], ptr [[P]], align 16
+; SPIRV-NEXT:    call void @foo()
+; SPIRV-NEXT:    [[LD2:%.*]] = load <16 x i8>, ptr [[P]], align 16
+; SPIRV-NEXT:    call void @nowrite(ptr [[P]])
+; SPIRV-NEXT:    [[INS2:%.*]] = insertelement <16 x i8> [[LD2]], i8 [[S]], i32 7
+; SPIRV-NEXT:    store <16 x i8> [[INS2]], ptr [[P]], align 16
+; SPIRV-NEXT:    ret void
+;
 entry:
   %ld = load <16 x i8>, ptr %p
   call void @maywrite(ptr %p)
@@ -786,6 +1129,45 @@ define i32 @insert_store_maximum_scan_instrs(i32 %arg, ptr %arg1, ptr %arg2, i8
 ; CHECK-NEXT:    store <16 x i8> [[I36]], ptr [[ARG2]], align 16
 ; CHECK-NEXT:    ret i32 [[I35]]
 ;
+; SPIRV-LABEL: @insert_store_maximum_scan_instrs(
+; SPIRV-NEXT:  bb:
+; SPIRV-NEXT:    [[I:%.*]] = or i32 [[ARG:%.*]], 1
+; SPIRV-NEXT:    [[I4:%.*]] = load <16 x i8>, ptr [[ARG2:%.*]], align 16
+; SPIRV-NEXT:    [[I5:%.*]] = tail call i32 @bar(i32 [[I]], i1 true)
+; SPIRV-NEXT:    [[I6:%.*]] = shl i32 [[ARG]], [[I5]]
+; SPIRV-NEXT:    [[I7:%.*]] = lshr i32 [[I6]], 26
+; SPIRV-NEXT:    [[I8:%.*]] = trunc i32 [[I7]] to i8
+; SPIRV-NEXT:    [[I9:%.*]] = and i8 [[I8]], 31
+; SPIRV-NEXT:    [[I10:%.*]] = lshr i32 [[I6]], 11
+; SPIRV-NEXT:    [[I11:%.*]] = and i32 [[I10]], 32767
+; SPIRV-NEXT:    [[I12:%.*]] = zext i8 [[I9]] to i64
+; SPIRV-NEXT:    [[I13:%.*]] = getelementptr inbounds i16, ptr [[ARG1:%.*]], i64 [[I12]]
+; SPIRV-NEXT:    [[I14:%.*]] = load i16, ptr [[I13]], align 2
+; SPIRV-NEXT:    [[I15:%.*]] = zext i16 [[I14]] to i32
+; SPIRV-NEXT:    [[I16:%.*]] = add nuw nsw i8 [[I9]], 1
+; SPIRV-NEXT:    [[I17:%.*]] = zext i8 [[I16]] to i64
+; SPIRV-NEXT:    [[I18:%.*]] = getelementptr inbounds i16, ptr [[ARG1]], i64 [[I17]]
+; SPIRV-NEXT:    [[I19:%.*]] = load i16, ptr [[I18]], align 2
+; SPIRV-NEXT:    [[I20:%.*]] = zext i16 [[I19]] to i32
+; SPIRV-NEXT:    [[I21:%.*]] = sub nsw i32 [[I20]], [[I15]]
+; SPIRV-NEXT:    [[I22:%.*]] = mul nsw i32 [[I11]], [[I21]]
+; SPIRV-NEXT:    [[I23:%.*]] = ashr i32 [[I22]], 15
+; SPIRV-NEXT:    [[I24:%.*]] = shl nuw nsw i32 [[I5]], 15
+; SPIRV-NEXT:    [[I25:%.*]] = xor i32 [[I24]], 1015808
+; SPIRV-NEXT:    [[I26:%.*]] = add nuw nsw i32 [[I25]], [[I15]]
+; SPIRV-NEXT:    [[I27:%.*]] = add nsw i32 [[I26]], [[I23]]
+; SPIRV-NEXT:    [[I28:%.*]] = sitofp i32 [[ARG]] to double
+; SPIRV-NEXT:    [[I29:%.*]] = tail call double @llvm.log2.f64(double [[I28]])
+; SPIRV-NEXT:    [[I30:%.*]] = fptosi double [[I29]] to i32
+; SPIRV-NEXT:    [[I31:%.*]] = shl nsw i32 [[I30]], 15
+; SPIRV-NEXT:    [[I32:%.*]] = or i32 [[I31]], 4
+; SPIRV-NEXT:    [[I33:%.*]] = icmp eq i32 [[I27]], [[I32]]
+; SPIRV-NEXT:    [[I34:%.*]] = select i1 [[I33]], i32 [[ARG]], i32 [[I31]]
+; SPIRV-NEXT:    [[I35:%.*]] = lshr i32 [[I34]], 1
+; SPIRV-NEXT:    [[I36:%.*]] = insertelement <16 x i8> [[I4]], i8 [[ARG3:%.*]], i32 3
+; SPIRV-NEXT:    store <16 x i8> [[I36]], ptr [[ARG2]], align 16
+; SPIRV-NEXT:    ret i32 [[I35]]
+;
 bb:
   %i = or i32 %arg, 1
   %i4 = load <16 x i8>, ptr %arg2, align 16

>From e581c35ea2652795284ca2baded170b800b30846 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= <brioche at google.com>
Date: Tue, 29 Jul 2025 15:56:25 +0200
Subject: [PATCH 2/6] add TTI hook

---
 .../llvm/Analysis/TargetTransformInfo.h        |  4 ++++
 .../llvm/Analysis/TargetTransformInfoImpl.h    |  2 ++
 llvm/lib/Analysis/TargetTransformInfo.cpp      |  4 ++++
 .../Target/SPIRV/SPIRVTargetTransformInfo.h    |  2 ++
 .../lib/Transforms/Vectorize/VectorCombine.cpp | 18 +++++++++++-------
 5 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/llvm/include/llvm/Analysis/TargetTransformInfo.h b/llvm/include/llvm/Analysis/TargetTransformInfo.h
index 7928835f7f84d..be0529754a116 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfo.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfo.h
@@ -1950,6 +1950,10 @@ class TargetTransformInfo {
       const Function &F,
       SmallVectorImpl<std::pair<StringRef, int64_t>> &LB) const;
 
+  /// Returns true if GEP should not be used to index into vectors for this
+  /// target.
+  LLVM_ABI bool isVectorElementIndexingUsingGEPAllowed() const;
+
 private:
   std::unique_ptr<const TargetTransformInfoImplBase> TTIImpl;
 };
diff --git a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
index 2ea87b3c62895..0e705cc8258f2 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -1145,6 +1145,8 @@ class TargetTransformInfoImplBase {
       const Function &F,
       SmallVectorImpl<std::pair<StringRef, int64_t>> &LB) const {}
 
+  virtual bool isVectorElementIndexingUsingGEPAllowed() const { return true; }
+
 protected:
   // Obtain the minimum required size to hold the value (without the sign)
   // In case of a vector it returns the min required size for one element.
diff --git a/llvm/lib/Analysis/TargetTransformInfo.cpp b/llvm/lib/Analysis/TargetTransformInfo.cpp
index 55ba52a1079ce..50c1993eb35a2 100644
--- a/llvm/lib/Analysis/TargetTransformInfo.cpp
+++ b/llvm/lib/Analysis/TargetTransformInfo.cpp
@@ -1486,6 +1486,10 @@ void TargetTransformInfo::collectKernelLaunchBounds(
   return TTIImpl->collectKernelLaunchBounds(F, LB);
 }
 
+bool TargetTransformInfo::isVectorElementIndexingUsingGEPAllowed() const {
+  return TTIImpl->isVectorElementIndexingUsingGEPAllowed();
+}
+
 TargetTransformInfoImplBase::~TargetTransformInfoImplBase() = default;
 
 TargetIRAnalysis::TargetIRAnalysis() : TTICallback(&getDefaultTTI) {}
diff --git a/llvm/lib/Target/SPIRV/SPIRVTargetTransformInfo.h b/llvm/lib/Target/SPIRV/SPIRVTargetTransformInfo.h
index 43bf6e9dd2a6e..bd066873a28af 100644
--- a/llvm/lib/Target/SPIRV/SPIRVTargetTransformInfo.h
+++ b/llvm/lib/Target/SPIRV/SPIRVTargetTransformInfo.h
@@ -59,6 +59,8 @@ class SPIRVTTIImpl final : public BasicTTIImplBase<SPIRVTTIImpl> {
                                   Intrinsic::ID IID) const override;
   Value *rewriteIntrinsicWithAddressSpace(IntrinsicInst *II, Value *OldV,
                                           Value *NewV) const override;
+
+  bool isVectorElementIndexingUsingGEPAllowed() const override { return false; }
 };
 
 } // namespace llvm
diff --git a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
index 3752d9d88129d..0d9a93fd5f99b 100644
--- a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
+++ b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
@@ -1664,6 +1664,8 @@ static Align computeAlignmentAfterScalarization(Align VectorAlignment,
 //   %1 = getelementptr inbounds i32, i32* %0, i64 0, i64 1
 //   store i32 %b, i32* %1
 bool VectorCombine::foldSingleElementStore(Instruction &I) {
+  if (!TTI.isVectorElementIndexingUsingGEPAllowed())
+    return false;
   auto *SI = cast<StoreInst>(&I);
   if (!SI->isSimple() || !isa<VectorType>(SI->getValueOperand()->getType()))
     return false;
@@ -1719,6 +1721,9 @@ bool VectorCombine::foldSingleElementStore(Instruction &I) {
 
 /// Try to scalarize vector loads feeding extractelement instructions.
 bool VectorCombine::scalarizeLoadExtract(Instruction &I) {
+  if (!TTI.isVectorElementIndexingUsingGEPAllowed())
+    return false;
+
   Value *Ptr;
   if (!match(&I, m_Load(m_Value(Ptr))))
     return false;
@@ -1827,6 +1832,8 @@ bool VectorCombine::scalarizeLoadExtract(Instruction &I) {
 }
 
 bool VectorCombine::scalarizeExtExtract(Instruction &I) {
+  if (!TTI.isVectorElementIndexingUsingGEPAllowed())
+    return false;
   auto *Ext = dyn_cast<ZExtInst>(&I);
   if (!Ext)
     return false;
@@ -3866,9 +3873,8 @@ bool VectorCombine::run() {
 
   LLVM_DEBUG(dbgs() << "\n\nVECTORCOMBINE on " << F.getName() << "\n");
 
-  const bool isSPIRV = F.getParent()->getTargetTriple().isSPIRV();
   bool MadeChange = false;
-  auto FoldInst = [this, &MadeChange, isSPIRV](Instruction &I) {
+  auto FoldInst = [this, &MadeChange](Instruction &I) {
     Builder.SetInsertPoint(&I);
     bool IsVectorType = isa<VectorType>(I.getType());
     bool IsFixedVectorType = isa<FixedVectorType>(I.getType());
@@ -3897,15 +3903,13 @@ bool VectorCombine::run() {
     // TODO: Identify and allow other scalable transforms
     if (IsVectorType) {
       MadeChange |= scalarizeOpOrCmp(I);
-      if (!isSPIRV) {
-        MadeChange |= scalarizeLoadExtract(I);
-        MadeChange |= scalarizeExtExtract(I);
-      }
+      MadeChange |= scalarizeLoadExtract(I);
+      MadeChange |= scalarizeExtExtract(I);
       MadeChange |= scalarizeVPIntrinsic(I);
       MadeChange |= foldInterleaveIntrinsics(I);
     }
 
-    if (Opcode == Instruction::Store && !isSPIRV)
+    if (Opcode == Instruction::Store)
       MadeChange |= foldSingleElementStore(I);
 
     // If this is an early pipeline invocation of this pass, we are done.

>From 5c3e2add5fb85fccd7dfb38ec6503b8390a417d3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= <brioche at google.com>
Date: Tue, 29 Jul 2025 17:38:21 +0200
Subject: [PATCH 3/6] move test to SPIRV subfolder

---
 .../VectorCombine/SPIRV/lit.local.cfg         |   2 +
 .../VectorCombine/SPIRV/load-insert-store.ll  | 889 ++++++++++++++++++
 .../VectorCombine/load-insert-store.ll        |   1 -
 3 files changed, 891 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/Transforms/VectorCombine/SPIRV/lit.local.cfg
 create mode 100644 llvm/test/Transforms/VectorCombine/SPIRV/load-insert-store.ll

diff --git a/llvm/test/Transforms/VectorCombine/SPIRV/lit.local.cfg b/llvm/test/Transforms/VectorCombine/SPIRV/lit.local.cfg
new file mode 100644
index 0000000000000..78dd74cd6dc63
--- /dev/null
+++ b/llvm/test/Transforms/VectorCombine/SPIRV/lit.local.cfg
@@ -0,0 +1,2 @@
+if not "SPIRV" in config.root.targets:
+    config.unsupported = True
diff --git a/llvm/test/Transforms/VectorCombine/SPIRV/load-insert-store.ll b/llvm/test/Transforms/VectorCombine/SPIRV/load-insert-store.ll
new file mode 100644
index 0000000000000..6f4c80d5d89a6
--- /dev/null
+++ b/llvm/test/Transforms/VectorCombine/SPIRV/load-insert-store.ll
@@ -0,0 +1,889 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S -passes=vector-combine -data-layout=E -mtriple=spirv-unknown-vulkan1.3-library %s | FileCheck %s --check-prefix=SPIRV
+
+define void @insert_store(ptr %q, i8 zeroext %s) {
+; SPIRV-LABEL: define void @insert_store(
+; SPIRV-SAME: ptr [[Q:%.*]], i8 zeroext [[S:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S]], i32 3
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <16 x i8>, ptr %q
+  %vecins = insertelement <16 x i8> %0, i8 %s, i32 3
+  store <16 x i8> %vecins, ptr %q, align 16
+  ret void
+}
+
+define void @insert_store_i16_align1(ptr %q, i16 zeroext %s) {
+; SPIRV-LABEL: define void @insert_store_i16_align1(
+; SPIRV-SAME: ptr [[Q:%.*]], i16 zeroext [[S:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <8 x i16>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <8 x i16> [[TMP0]], i16 [[S]], i32 3
+; SPIRV-NEXT:    store <8 x i16> [[VECINS]], ptr [[Q]], align 1
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <8 x i16>, ptr %q
+  %vecins = insertelement <8 x i16> %0, i16 %s, i32 3
+  store <8 x i16> %vecins, ptr %q, align 1
+  ret void
+}
+
+; To verify case when index is out of bounds
+define void @insert_store_outofbounds(ptr %q, i16 zeroext %s) {
+; SPIRV-LABEL: define void @insert_store_outofbounds(
+; SPIRV-SAME: ptr [[Q:%.*]], i16 zeroext [[S:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <8 x i16>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <8 x i16> [[TMP0]], i16 [[S]], i32 9
+; SPIRV-NEXT:    store <8 x i16> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <8 x i16>, ptr %q
+  %vecins = insertelement <8 x i16> %0, i16 %s, i32 9
+  store <8 x i16> %vecins, ptr %q
+  ret void
+}
+
+define void @insert_store_vscale(ptr %q, i16 zeroext %s) {
+; SPIRV-LABEL: define void @insert_store_vscale(
+; SPIRV-SAME: ptr [[Q:%.*]], i16 zeroext [[S:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <vscale x 8 x i16>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <vscale x 8 x i16> [[TMP0]], i16 [[S]], i32 3
+; SPIRV-NEXT:    store <vscale x 8 x i16> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <vscale x 8 x i16>, ptr %q
+  %vecins = insertelement <vscale x 8 x i16> %0, i16 %s, i32 3
+  store <vscale x 8 x i16> %vecins, ptr %q
+  ret void
+}
+
+; To verify the case that index exceeds the minimum number
+; of elements of a scalable vector type.
+define void @insert_store_vscale_exceeds(ptr %q, i16 zeroext %s) {
+; SPIRV-LABEL: define void @insert_store_vscale_exceeds(
+; SPIRV-SAME: ptr [[Q:%.*]], i16 zeroext [[S:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <vscale x 8 x i16>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <vscale x 8 x i16> [[TMP0]], i16 [[S]], i32 9
+; SPIRV-NEXT:    store <vscale x 8 x i16> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <vscale x 8 x i16>, ptr %q
+  %vecins = insertelement <vscale x 8 x i16> %0, i16 %s, i32 9
+  store <vscale x 8 x i16> %vecins, ptr %q
+  ret void
+}
+
+define void @insert_store_v9i4(ptr %q, i4 zeroext %s) {
+; SPIRV-LABEL: define void @insert_store_v9i4(
+; SPIRV-SAME: ptr [[Q:%.*]], i4 zeroext [[S:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <9 x i4>, ptr [[Q]], align 8
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <9 x i4> [[TMP0]], i4 [[S]], i32 3
+; SPIRV-NEXT:    store <9 x i4> [[VECINS]], ptr [[Q]], align 1
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <9 x i4>, ptr %q
+  %vecins = insertelement <9 x i4> %0, i4 %s, i32 3
+  store <9 x i4> %vecins, ptr %q, align 1
+  ret void
+}
+
+define void @insert_store_v4i27(ptr %q, i27 zeroext %s) {
+; SPIRV-LABEL: define void @insert_store_v4i27(
+; SPIRV-SAME: ptr [[Q:%.*]], i27 zeroext [[S:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <4 x i27>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <4 x i27> [[TMP0]], i27 [[S]], i32 3
+; SPIRV-NEXT:    store <4 x i27> [[VECINS]], ptr [[Q]], align 1
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <4 x i27>, ptr %q
+  %vecins = insertelement <4 x i27> %0, i27 %s, i32 3
+  store <4 x i27> %vecins, ptr %q, align 1
+  ret void
+}
+
+define void @insert_store_v32i1(ptr %p) {
+; SPIRV-LABEL: define void @insert_store_v32i1(
+; SPIRV-SAME: ptr [[P:%.*]]) {
+; SPIRV-NEXT:    [[VEC:%.*]] = load <32 x i1>, ptr [[P]], align 4
+; SPIRV-NEXT:    [[INS:%.*]] = insertelement <32 x i1> [[VEC]], i1 true, i64 0
+; SPIRV-NEXT:    store <32 x i1> [[INS]], ptr [[P]], align 4
+; SPIRV-NEXT:    ret void
+;
+  %vec = load <32 x i1>, ptr %p
+  %ins = insertelement <32 x i1> %vec, i1 true, i64 0
+  store <32 x i1> %ins, ptr %p
+  ret void
+}
+
+define void @insert_store_blk_differ(ptr %q, i16 zeroext %s) {
+; SPIRV-LABEL: define void @insert_store_blk_differ(
+; SPIRV-SAME: ptr [[Q:%.*]], i16 zeroext [[S:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <8 x i16>, ptr [[Q]], align 16
+; SPIRV-NEXT:    br label %[[CONT:.*]]
+; SPIRV:       [[CONT]]:
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <8 x i16> [[TMP0]], i16 [[S]], i32 3
+; SPIRV-NEXT:    store <8 x i16> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <8 x i16>, ptr %q
+  br label %cont
+cont:
+  %vecins = insertelement <8 x i16> %0, i16 %s, i32 3
+  store <8 x i16> %vecins, ptr %q
+  ret void
+}
+
+define void @insert_store_nonconst(ptr %q, i8 zeroext %s, i32 %idx) {
+; SPIRV-LABEL: define void @insert_store_nonconst(
+; SPIRV-SAME: ptr [[Q:%.*]], i8 zeroext [[S:%.*]], i32 [[IDX:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S]], i32 [[IDX]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <16 x i8>, ptr %q
+  %vecins = insertelement <16 x i8> %0, i8 %s, i32 %idx
+  store <16 x i8> %vecins, ptr %q
+  ret void
+}
+
+; To verify the case that the index is not a constant, and
+; the vector type is scalable.
+define void @insert_store_vscale_nonconst(ptr %q, i8 zeroext %s, i32 %idx) {
+; SPIRV-LABEL: define void @insert_store_vscale_nonconst(
+; SPIRV-SAME: ptr [[Q:%.*]], i8 zeroext [[S:%.*]], i32 [[IDX:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <vscale x 16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <vscale x 16 x i8> [[TMP0]], i8 [[S]], i32 [[IDX]]
+; SPIRV-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <vscale x 16 x i8>, ptr %q
+  %vecins = insertelement <vscale x 16 x i8> %0, i8 %s, i32 %idx
+  store <vscale x 16 x i8> %vecins, ptr %q
+  ret void
+}
+
+; To verify align here is narrowed to scalar store size
+define void @insert_store_nonconst_large_alignment(ptr %q, i32 zeroext %s, i32 %idx) {
+; SPIRV-LABEL: define void @insert_store_nonconst_large_alignment(
+; SPIRV-SAME: ptr [[Q:%.*]], i32 zeroext [[S:%.*]], i32 [[IDX:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX]], 4
+; SPIRV-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; SPIRV-NEXT:    [[I:%.*]] = load <4 x i32>, ptr [[Q]], align 128
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <4 x i32> [[I]], i32 [[S]], i32 [[IDX]]
+; SPIRV-NEXT:    store <4 x i32> [[VECINS]], ptr [[Q]], align 128
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %cmp = icmp ult i32 %idx, 4
+  call void @llvm.assume(i1 %cmp)
+  %i = load <4 x i32>, ptr %q, align 128
+  %vecins = insertelement <4 x i32> %i, i32 %s, i32 %idx
+  store <4 x i32> %vecins, ptr %q, align 128
+  ret void
+}
+
+define void @insert_store_nonconst_align_maximum_8(ptr %q, i64 %s, i32 %idx) {
+; SPIRV-LABEL: define void @insert_store_nonconst_align_maximum_8(
+; SPIRV-SAME: ptr [[Q:%.*]], i64 [[S:%.*]], i32 [[IDX:%.*]]) {
+; SPIRV-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX]], 2
+; SPIRV-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; SPIRV-NEXT:    [[I:%.*]] = load <8 x i64>, ptr [[Q]], align 8
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <8 x i64> [[I]], i64 [[S]], i32 [[IDX]]
+; SPIRV-NEXT:    store <8 x i64> [[VECINS]], ptr [[Q]], align 8
+; SPIRV-NEXT:    ret void
+;
+  %cmp = icmp ult i32 %idx, 2
+  call void @llvm.assume(i1 %cmp)
+  %i = load <8 x i64>, ptr %q, align 8
+  %vecins = insertelement <8 x i64> %i, i64 %s, i32 %idx
+  store <8 x i64> %vecins, ptr %q, align 8
+  ret void
+}
+
+define void @insert_store_nonconst_align_maximum_4(ptr %q, i64 %s, i32 %idx) {
+; SPIRV-LABEL: define void @insert_store_nonconst_align_maximum_4(
+; SPIRV-SAME: ptr [[Q:%.*]], i64 [[S:%.*]], i32 [[IDX:%.*]]) {
+; SPIRV-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX]], 2
+; SPIRV-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; SPIRV-NEXT:    [[I:%.*]] = load <8 x i64>, ptr [[Q]], align 4
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <8 x i64> [[I]], i64 [[S]], i32 [[IDX]]
+; SPIRV-NEXT:    store <8 x i64> [[VECINS]], ptr [[Q]], align 4
+; SPIRV-NEXT:    ret void
+;
+  %cmp = icmp ult i32 %idx, 2
+  call void @llvm.assume(i1 %cmp)
+  %i = load <8 x i64>, ptr %q, align 4
+  %vecins = insertelement <8 x i64> %i, i64 %s, i32 %idx
+  store <8 x i64> %vecins, ptr %q, align 4
+  ret void
+}
+
+define void @insert_store_nonconst_align_larger(ptr %q, i64 %s, i32 %idx) {
+; SPIRV-LABEL: define void @insert_store_nonconst_align_larger(
+; SPIRV-SAME: ptr [[Q:%.*]], i64 [[S:%.*]], i32 [[IDX:%.*]]) {
+; SPIRV-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX]], 2
+; SPIRV-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; SPIRV-NEXT:    [[I:%.*]] = load <8 x i64>, ptr [[Q]], align 4
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <8 x i64> [[I]], i64 [[S]], i32 [[IDX]]
+; SPIRV-NEXT:    store <8 x i64> [[VECINS]], ptr [[Q]], align 2
+; SPIRV-NEXT:    ret void
+;
+  %cmp = icmp ult i32 %idx, 2
+  call void @llvm.assume(i1 %cmp)
+  %i = load <8 x i64>, ptr %q, align 4
+  %vecins = insertelement <8 x i64> %i, i64 %s, i32 %idx
+  store <8 x i64> %vecins, ptr %q, align 2
+  ret void
+}
+
+define void @insert_store_nonconst_index_known_valid_by_assume(ptr %q, i8 zeroext %s, i32 %idx) {
+; SPIRV-LABEL: define void @insert_store_nonconst_index_known_valid_by_assume(
+; SPIRV-SAME: ptr [[Q:%.*]], i8 zeroext [[S:%.*]], i32 [[IDX:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX]], 4
+; SPIRV-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S]], i32 [[IDX]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %cmp = icmp ult i32 %idx, 4
+  call void @llvm.assume(i1 %cmp)
+  %0 = load <16 x i8>, ptr %q
+  %vecins = insertelement <16 x i8> %0, i8 %s, i32 %idx
+  store <16 x i8> %vecins, ptr %q
+  ret void
+}
+
+; To verify the index is not a constant but valid by assume,
+; for scalable vector types.
+define void @insert_store_vscale_nonconst_index_known_valid_by_assume(ptr %q, i8 zeroext %s, i32 %idx) {
+; SPIRV-LABEL: define void @insert_store_vscale_nonconst_index_known_valid_by_assume(
+; SPIRV-SAME: ptr [[Q:%.*]], i8 zeroext [[S:%.*]], i32 [[IDX:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX]], 4
+; SPIRV-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <vscale x 16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <vscale x 16 x i8> [[TMP0]], i8 [[S]], i32 [[IDX]]
+; SPIRV-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %cmp = icmp ult i32 %idx, 4
+  call void @llvm.assume(i1 %cmp)
+  %0 = load <vscale x 16 x i8>, ptr %q
+  %vecins = insertelement <vscale x 16 x i8> %0, i8 %s, i32 %idx
+  store <vscale x 16 x i8> %vecins, ptr %q
+  ret void
+}
+
+declare void @maythrow() readnone
+
+define void @insert_store_nonconst_index_not_known_valid_by_assume_after_load(ptr %q, i8 zeroext %s, i32 %idx) {
+; SPIRV-LABEL: define void @insert_store_nonconst_index_not_known_valid_by_assume_after_load(
+; SPIRV-SAME: ptr [[Q:%.*]], i8 zeroext [[S:%.*]], i32 [[IDX:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX]], 4
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    call void @maythrow()
+; SPIRV-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S]], i32 [[IDX]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %cmp = icmp ult i32 %idx, 4
+  %0 = load <16 x i8>, ptr %q
+  call void @maythrow()
+  call void @llvm.assume(i1 %cmp)
+  %vecins = insertelement <16 x i8> %0, i8 %s, i32 %idx
+  store <16 x i8> %vecins, ptr %q
+  ret void
+}
+
+define void @insert_store_nonconst_index_not_known_valid_by_assume(ptr %q, i8 zeroext %s, i32 %idx) {
+; SPIRV-LABEL: define void @insert_store_nonconst_index_not_known_valid_by_assume(
+; SPIRV-SAME: ptr [[Q:%.*]], i8 zeroext [[S:%.*]], i32 [[IDX:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX]], 17
+; SPIRV-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S]], i32 [[IDX]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %cmp = icmp ult i32 %idx, 17
+  call void @llvm.assume(i1 %cmp)
+  %0 = load <16 x i8>, ptr %q
+  %vecins = insertelement <16 x i8> %0, i8 %s, i32 %idx
+  store <16 x i8> %vecins, ptr %q
+  ret void
+}
+
+; To verify the index is not a constant and may not be valid by assume,
+; for scalable vector types.
+define void @insert_store_vscale_nonconst_index_not_known_valid_by_assume(ptr %q, i8 zeroext %s, i32 %idx) {
+; SPIRV-LABEL: define void @insert_store_vscale_nonconst_index_not_known_valid_by_assume(
+; SPIRV-SAME: ptr [[Q:%.*]], i8 zeroext [[S:%.*]], i32 [[IDX:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX]], 17
+; SPIRV-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <vscale x 16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <vscale x 16 x i8> [[TMP0]], i8 [[S]], i32 [[IDX]]
+; SPIRV-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %cmp = icmp ult i32 %idx, 17
+  call void @llvm.assume(i1 %cmp)
+  %0 = load <vscale x 16 x i8>, ptr %q
+  %vecins = insertelement <vscale x 16 x i8> %0, i8 %s, i32 %idx
+  store <vscale x 16 x i8> %vecins, ptr %q
+  ret void
+}
+
+declare void @llvm.assume(i1)
+
+define void @insert_store_nonconst_index_known_noundef_and_valid_by_and(ptr %q, i8 zeroext %s, i32 noundef %idx) {
+; SPIRV-LABEL: define void @insert_store_nonconst_index_known_noundef_and_valid_by_and(
+; SPIRV-SAME: ptr [[Q:%.*]], i8 zeroext [[S:%.*]], i32 noundef [[IDX:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = and i32 [[IDX]], 7
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <16 x i8>, ptr %q
+  %idx.clamped = and i32 %idx, 7
+  %vecins = insertelement <16 x i8> %0, i8 %s, i32 %idx.clamped
+  store <16 x i8> %vecins, ptr %q
+  ret void
+}
+
+; To verify the index is not a constant but valid by and,
+; for scalable vector types.
+define void @insert_store_vscale_nonconst_index_known_noundef_and_valid_by_and(ptr %q, i8 zeroext %s, i32 noundef %idx) {
+; SPIRV-LABEL: define void @insert_store_vscale_nonconst_index_known_noundef_and_valid_by_and(
+; SPIRV-SAME: ptr [[Q:%.*]], i8 zeroext [[S:%.*]], i32 noundef [[IDX:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <vscale x 16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = and i32 [[IDX]], 7
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <vscale x 16 x i8> [[TMP0]], i8 [[S]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <vscale x 16 x i8>, ptr %q
+  %idx.clamped = and i32 %idx, 7
+  %vecins = insertelement <vscale x 16 x i8> %0, i8 %s, i32 %idx.clamped
+  store <vscale x 16 x i8> %vecins, ptr %q
+  ret void
+}
+
+define void @insert_store_nonconst_index_base_frozen_and_valid_by_and(ptr %q, i8 zeroext %s, i32 %idx) {
+; SPIRV-LABEL: define void @insert_store_nonconst_index_base_frozen_and_valid_by_and(
+; SPIRV-SAME: ptr [[Q:%.*]], i8 zeroext [[S:%.*]], i32 [[IDX:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[IDX_FROZEN:%.*]] = freeze i32 [[IDX]]
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = and i32 [[IDX_FROZEN]], 7
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <16 x i8>, ptr %q
+  %idx.frozen = freeze i32 %idx
+  %idx.clamped = and i32 %idx.frozen, 7
+  %vecins = insertelement <16 x i8> %0, i8 %s, i32 %idx.clamped
+  store <16 x i8> %vecins, ptr %q
+  ret void
+}
+
+define void @insert_store_nonconst_index_frozen_and_valid_by_and(ptr %q, i8 zeroext %s, i32 %idx) {
+; SPIRV-LABEL: define void @insert_store_nonconst_index_frozen_and_valid_by_and(
+; SPIRV-SAME: ptr [[Q:%.*]], i8 zeroext [[S:%.*]], i32 [[IDX:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = and i32 [[IDX]], 7
+; SPIRV-NEXT:    [[IDX_CLAMPED_FROZEN:%.*]] = freeze i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S]], i32 [[IDX_CLAMPED_FROZEN]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <16 x i8>, ptr %q
+  %idx.clamped = and i32 %idx, 7
+  %idx.clamped.frozen = freeze i32 %idx.clamped
+  %vecins = insertelement <16 x i8> %0, i8 %s, i32 %idx.clamped.frozen
+  store <16 x i8> %vecins, ptr %q
+  ret void
+}
+
+define void @insert_store_nonconst_index_known_valid_by_and_but_may_be_poison(ptr %q, i8 zeroext %s, i32 %idx) {
+; SPIRV-LABEL: define void @insert_store_nonconst_index_known_valid_by_and_but_may_be_poison(
+; SPIRV-SAME: ptr [[Q:%.*]], i8 zeroext [[S:%.*]], i32 [[IDX:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = and i32 [[IDX]], 7
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <16 x i8>, ptr %q
+  %idx.clamped = and i32 %idx, 7
+  %vecins = insertelement <16 x i8> %0, i8 %s, i32 %idx.clamped
+  store <16 x i8> %vecins, ptr %q
+  ret void
+}
+
+define void @insert_store_nonconst_index_not_known_valid_by_and(ptr %q, i8 zeroext %s, i32 %idx) {
+; SPIRV-LABEL: define void @insert_store_nonconst_index_not_known_valid_by_and(
+; SPIRV-SAME: ptr [[Q:%.*]], i8 zeroext [[S:%.*]], i32 [[IDX:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = and i32 [[IDX]], 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <16 x i8>, ptr %q
+  %idx.clamped = and i32 %idx, 16
+  %vecins = insertelement <16 x i8> %0, i8 %s, i32 %idx.clamped
+  store <16 x i8> %vecins, ptr %q
+  ret void
+}
+
+define void @insert_store_nonconst_index_known_noundef_not_known_valid_by_and(ptr %q, i8 zeroext %s, i32 noundef %idx) {
+; SPIRV-LABEL: define void @insert_store_nonconst_index_known_noundef_not_known_valid_by_and(
+; SPIRV-SAME: ptr [[Q:%.*]], i8 zeroext [[S:%.*]], i32 noundef [[IDX:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = and i32 [[IDX]], 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <16 x i8>, ptr %q
+  %idx.clamped = and i32 %idx, 16
+  %vecins = insertelement <16 x i8> %0, i8 %s, i32 %idx.clamped
+  store <16 x i8> %vecins, ptr %q
+  ret void
+}
+
+; To verify the index is not a constant and may not be valid by and,
+; for scalable vector types.
+define void @insert_store_vscale_nonconst_index_not_known_valid_by_and(ptr %q, i8 zeroext %s, i32 %idx) {
+; SPIRV-LABEL: define void @insert_store_vscale_nonconst_index_not_known_valid_by_and(
+; SPIRV-SAME: ptr [[Q:%.*]], i8 zeroext [[S:%.*]], i32 [[IDX:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <vscale x 16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = and i32 [[IDX]], 31
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <vscale x 16 x i8> [[TMP0]], i8 [[S]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <vscale x 16 x i8>, ptr %q
+  %idx.clamped = and i32 %idx, 31
+  %vecins = insertelement <vscale x 16 x i8> %0, i8 %s, i32 %idx.clamped
+  store <vscale x 16 x i8> %vecins, ptr %q
+  ret void
+}
+
+define void @insert_store_nonconst_index_known_noundef_and_valid_by_urem(ptr %q, i8 zeroext %s, i32 noundef %idx) {
+; SPIRV-LABEL: define void @insert_store_nonconst_index_known_noundef_and_valid_by_urem(
+; SPIRV-SAME: ptr [[Q:%.*]], i8 zeroext [[S:%.*]], i32 noundef [[IDX:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = urem i32 [[IDX]], 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <16 x i8>, ptr %q
+  %idx.clamped = urem i32 %idx, 16
+  %vecins = insertelement <16 x i8> %0, i8 %s, i32 %idx.clamped
+  store <16 x i8> %vecins, ptr %q
+  ret void
+}
+
+; To verify the index is not a constant but valid by urem,
+; for scalable vector types.
+define void @insert_store_vscale_nonconst_index_known_noundef_and_valid_by_urem(ptr %q, i8 zeroext %s, i32 noundef %idx) {
+; SPIRV-LABEL: define void @insert_store_vscale_nonconst_index_known_noundef_and_valid_by_urem(
+; SPIRV-SAME: ptr [[Q:%.*]], i8 zeroext [[S:%.*]], i32 noundef [[IDX:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <vscale x 16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = urem i32 [[IDX]], 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <vscale x 16 x i8> [[TMP0]], i8 [[S]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <vscale x 16 x i8>, ptr %q
+  %idx.clamped = urem i32 %idx, 16
+  %vecins = insertelement <vscale x 16 x i8> %0, i8 %s, i32 %idx.clamped
+  store <vscale x 16 x i8> %vecins, ptr %q
+  ret void
+}
+
+define void @insert_store_nonconst_index_base_frozen_and_valid_by_urem(ptr %q, i8 zeroext %s, i32 %idx) {
+; SPIRV-LABEL: define void @insert_store_nonconst_index_base_frozen_and_valid_by_urem(
+; SPIRV-SAME: ptr [[Q:%.*]], i8 zeroext [[S:%.*]], i32 [[IDX:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[IDX_FROZEN:%.*]] = freeze i32 [[IDX]]
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = urem i32 [[IDX_FROZEN]], 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <16 x i8>, ptr %q
+  %idx.frozen = freeze i32 %idx
+  %idx.clamped = urem i32 %idx.frozen, 16
+  %vecins = insertelement <16 x i8> %0, i8 %s, i32 %idx.clamped
+  store <16 x i8> %vecins, ptr %q
+  ret void
+}
+
+define void @insert_store_nonconst_index_frozen_and_valid_by_urem(ptr %q, i8 zeroext %s, i32 %idx) {
+; SPIRV-LABEL: define void @insert_store_nonconst_index_frozen_and_valid_by_urem(
+; SPIRV-SAME: ptr [[Q:%.*]], i8 zeroext [[S:%.*]], i32 [[IDX:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = urem i32 [[IDX]], 16
+; SPIRV-NEXT:    [[IDX_CLAMPED_FROZEN:%.*]] = freeze i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S]], i32 [[IDX_CLAMPED_FROZEN]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <16 x i8>, ptr %q
+  %idx.clamped = urem i32 %idx, 16
+  %idx.clamped.frozen = freeze i32 %idx.clamped
+  %vecins = insertelement <16 x i8> %0, i8 %s, i32 %idx.clamped.frozen
+  store <16 x i8> %vecins, ptr %q
+  ret void
+}
+
+define void @insert_store_nonconst_index_known_valid_by_urem_but_may_be_poison(ptr %q, i8 zeroext %s, i32 %idx) {
+; SPIRV-LABEL: define void @insert_store_nonconst_index_known_valid_by_urem_but_may_be_poison(
+; SPIRV-SAME: ptr [[Q:%.*]], i8 zeroext [[S:%.*]], i32 [[IDX:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = urem i32 [[IDX]], 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <16 x i8>, ptr %q
+  %idx.clamped = urem i32 %idx, 16
+  %vecins = insertelement <16 x i8> %0, i8 %s, i32 %idx.clamped
+  store <16 x i8> %vecins, ptr %q
+  ret void
+}
+
+define void @insert_store_nonconst_index_not_known_valid_by_urem(ptr %q, i8 zeroext %s, i32 %idx) {
+; SPIRV-LABEL: define void @insert_store_nonconst_index_not_known_valid_by_urem(
+; SPIRV-SAME: ptr [[Q:%.*]], i8 zeroext [[S:%.*]], i32 [[IDX:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = urem i32 [[IDX]], 17
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <16 x i8>, ptr %q
+  %idx.clamped = urem i32 %idx, 17
+  %vecins = insertelement <16 x i8> %0, i8 %s, i32 %idx.clamped
+  store <16 x i8> %vecins, ptr %q
+  ret void
+}
+
+; To verify the index is not a constant and may not be vaild by urem,
+; for scalable vector types.
+define void @insert_store_vscale_nonconst_index_not_known_valid_by_urem(ptr %q, i8 zeroext %s, i32 %idx) {
+; SPIRV-LABEL: define void @insert_store_vscale_nonconst_index_not_known_valid_by_urem(
+; SPIRV-SAME: ptr [[Q:%.*]], i8 zeroext [[S:%.*]], i32 [[IDX:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <vscale x 16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = urem i32 [[IDX]], 17
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <vscale x 16 x i8> [[TMP0]], i8 [[S]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <vscale x 16 x i8>, ptr %q
+  %idx.clamped = urem i32 %idx, 17
+  %vecins = insertelement <vscale x 16 x i8> %0, i8 %s, i32 %idx.clamped
+  store <vscale x 16 x i8> %vecins, ptr %q
+  ret void
+}
+
+define void @insert_store_nonconst_index_known_noundef_not_known_valid_by_urem(ptr %q, i8 zeroext %s, i32 noundef %idx) {
+; SPIRV-LABEL: define void @insert_store_nonconst_index_known_noundef_not_known_valid_by_urem(
+; SPIRV-SAME: ptr [[Q:%.*]], i8 zeroext [[S:%.*]], i32 noundef [[IDX:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = urem i32 [[IDX]], 17
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S]], i32 [[IDX_CLAMPED]]
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <16 x i8>, ptr %q
+  %idx.clamped = urem i32 %idx, 17
+  %vecins = insertelement <16 x i8> %0, i8 %s, i32 %idx.clamped
+  store <16 x i8> %vecins, ptr %q
+  ret void
+}
+
+define void @insert_store_ptr_strip(ptr %q, i8 zeroext %s) {
+; SPIRV-LABEL: define void @insert_store_ptr_strip(
+; SPIRV-SAME: ptr [[Q:%.*]], i8 zeroext [[S:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S]], i32 3
+; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <16 x i8>, ptr %q
+  %vecins = insertelement <16 x i8> %0, i8 %s, i32 3
+  store <16 x i8> %vecins, ptr %q
+  ret void
+}
+
+define void @volatile_update(ptr %q, ptr %p, i8 zeroext %s) {
+; SPIRV-LABEL: define void @volatile_update(
+; SPIRV-SAME: ptr [[Q:%.*]], ptr [[P:%.*]], i8 zeroext [[S:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[VECINS0:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S]], i32 3
+; SPIRV-NEXT:    store volatile <16 x i8> [[VECINS0]], ptr [[Q]], align 16
+; SPIRV-NEXT:    [[TMP1:%.*]] = load volatile <16 x i8>, ptr [[P]], align 16
+; SPIRV-NEXT:    [[VECINS1:%.*]] = insertelement <16 x i8> [[TMP1]], i8 [[S]], i32 1
+; SPIRV-NEXT:    store <16 x i8> [[VECINS1]], ptr [[P]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %0 = load <16 x i8>, ptr %q
+  %vecins0 = insertelement <16 x i8> %0, i8 %s, i32 3
+  store volatile <16 x i8> %vecins0, ptr %q
+
+  %1 = load volatile <16 x i8>, ptr %p
+  %vecins1 = insertelement <16 x i8> %1, i8 %s, i32 1
+  store <16 x i8> %vecins1, ptr %p
+  ret void
+}
+
+define void @insert_store_addr_differ(ptr %p, ptr %q, i8 %s) {
+; SPIRV-LABEL: define void @insert_store_addr_differ(
+; SPIRV-SAME: ptr [[P:%.*]], ptr [[Q:%.*]], i8 [[S:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[LD:%.*]] = load <16 x i8>, ptr [[P]], align 16
+; SPIRV-NEXT:    [[INS:%.*]] = insertelement <16 x i8> [[LD]], i8 [[S]], i32 3
+; SPIRV-NEXT:    store <16 x i8> [[INS]], ptr [[Q]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %ld = load <16 x i8>, ptr %p
+  %ins = insertelement <16 x i8> %ld, i8 %s, i32 3
+  store <16 x i8> %ins, ptr %q
+  ret void
+}
+
+; We can't transform if any instr could modify memory in between.
+define void @insert_store_mem_modify(ptr %p, ptr %q, ptr noalias %r, i8 %s, i32 %m) {
+; SPIRV-LABEL: define void @insert_store_mem_modify(
+; SPIRV-SAME: ptr [[P:%.*]], ptr [[Q:%.*]], ptr noalias [[R:%.*]], i8 [[S:%.*]], i32 [[M:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[LD:%.*]] = load <16 x i8>, ptr [[P]], align 16
+; SPIRV-NEXT:    store <16 x i8> zeroinitializer, ptr [[Q]], align 16
+; SPIRV-NEXT:    [[INS:%.*]] = insertelement <16 x i8> [[LD]], i8 [[S]], i32 3
+; SPIRV-NEXT:    store <16 x i8> [[INS]], ptr [[P]], align 16
+; SPIRV-NEXT:    [[LD2:%.*]] = load <16 x i8>, ptr [[Q]], align 16
+; SPIRV-NEXT:    store <16 x i8> zeroinitializer, ptr [[R]], align 16
+; SPIRV-NEXT:    [[INS2:%.*]] = insertelement <16 x i8> [[LD2]], i8 [[S]], i32 7
+; SPIRV-NEXT:    store <16 x i8> [[INS2]], ptr [[Q]], align 16
+; SPIRV-NEXT:    [[LD3:%.*]] = load <4 x i32>, ptr [[P]], align 16
+; SPIRV-NEXT:    store <16 x i8> zeroinitializer, ptr [[P]], align 16
+; SPIRV-NEXT:    [[INS3:%.*]] = insertelement <4 x i32> [[LD3]], i32 [[M]], i32 0
+; SPIRV-NEXT:    store <4 x i32> [[INS3]], ptr [[P]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  ; p may alias q
+  %ld = load <16 x i8>, ptr %p
+  store <16 x i8> zeroinitializer, ptr %q
+  %ins = insertelement <16 x i8> %ld, i8 %s, i32 3
+  store <16 x i8> %ins, ptr %p
+
+  ; p never aliases r
+  %ld2 = load <16 x i8>, ptr %q
+  store <16 x i8> zeroinitializer, ptr %r
+  %ins2 = insertelement <16 x i8> %ld2, i8 %s, i32 7
+  store <16 x i8> %ins2, ptr %q
+
+  ; p must alias ptr0
+  %ld3 = load <4 x i32>, ptr %p
+  store <16 x i8> zeroinitializer, ptr %p
+  %ins3 = insertelement <4 x i32> %ld3, i32 %m, i32 0
+  store <4 x i32> %ins3, ptr %p
+
+  ret void
+}
+
+; Check cases when calls may modify memory
+define void @insert_store_with_call(ptr %p, ptr %q, i8 %s) {
+; SPIRV-LABEL: define void @insert_store_with_call(
+; SPIRV-SAME: ptr [[P:%.*]], ptr [[Q:%.*]], i8 [[S:%.*]]) {
+; SPIRV-NEXT:  [[ENTRY:.*:]]
+; SPIRV-NEXT:    [[LD:%.*]] = load <16 x i8>, ptr [[P]], align 16
+; SPIRV-NEXT:    call void @maywrite(ptr [[P]])
+; SPIRV-NEXT:    [[INS:%.*]] = insertelement <16 x i8> [[LD]], i8 [[S]], i32 3
+; SPIRV-NEXT:    store <16 x i8> [[INS]], ptr [[P]], align 16
+; SPIRV-NEXT:    call void @foo()
+; SPIRV-NEXT:    [[LD2:%.*]] = load <16 x i8>, ptr [[P]], align 16
+; SPIRV-NEXT:    call void @nowrite(ptr [[P]])
+; SPIRV-NEXT:    [[INS2:%.*]] = insertelement <16 x i8> [[LD2]], i8 [[S]], i32 7
+; SPIRV-NEXT:    store <16 x i8> [[INS2]], ptr [[P]], align 16
+; SPIRV-NEXT:    ret void
+;
+entry:
+  %ld = load <16 x i8>, ptr %p
+  call void @maywrite(ptr %p)
+  %ins = insertelement <16 x i8> %ld, i8 %s, i32 3
+  store <16 x i8> %ins, ptr %p
+  call void @foo()  ; Barrier
+  %ld2 = load <16 x i8>, ptr %p
+  call void @nowrite(ptr %p)
+  %ins2 = insertelement <16 x i8> %ld2, i8 %s, i32 7
+  store <16 x i8> %ins2, ptr %p
+  ret void
+}
+
+declare void @foo()
+declare void @maywrite(ptr)
+declare void @nowrite(ptr) readonly
+
+; To test if number of instructions in-between exceeds the limit (default 30),
+; the combine will quit.
+define i32 @insert_store_maximum_scan_instrs(i32 %arg, ptr %arg1, ptr %arg2, i8 zeroext %arg3) {
+; SPIRV-LABEL: define i32 @insert_store_maximum_scan_instrs(
+; SPIRV-SAME: i32 [[ARG:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]], i8 zeroext [[ARG3:%.*]]) {
+; SPIRV-NEXT:  [[BB:.*:]]
+; SPIRV-NEXT:    [[I:%.*]] = or i32 [[ARG]], 1
+; SPIRV-NEXT:    [[I4:%.*]] = load <16 x i8>, ptr [[ARG2]], align 16
+; SPIRV-NEXT:    [[I5:%.*]] = tail call i32 @bar(i32 [[I]], i1 true)
+; SPIRV-NEXT:    [[I6:%.*]] = shl i32 [[ARG]], [[I5]]
+; SPIRV-NEXT:    [[I7:%.*]] = lshr i32 [[I6]], 26
+; SPIRV-NEXT:    [[I8:%.*]] = trunc i32 [[I7]] to i8
+; SPIRV-NEXT:    [[I9:%.*]] = and i8 [[I8]], 31
+; SPIRV-NEXT:    [[I10:%.*]] = lshr i32 [[I6]], 11
+; SPIRV-NEXT:    [[I11:%.*]] = and i32 [[I10]], 32767
+; SPIRV-NEXT:    [[I12:%.*]] = zext i8 [[I9]] to i64
+; SPIRV-NEXT:    [[I13:%.*]] = getelementptr inbounds i16, ptr [[ARG1]], i64 [[I12]]
+; SPIRV-NEXT:    [[I14:%.*]] = load i16, ptr [[I13]], align 2
+; SPIRV-NEXT:    [[I15:%.*]] = zext i16 [[I14]] to i32
+; SPIRV-NEXT:    [[I16:%.*]] = add nuw nsw i8 [[I9]], 1
+; SPIRV-NEXT:    [[I17:%.*]] = zext i8 [[I16]] to i64
+; SPIRV-NEXT:    [[I18:%.*]] = getelementptr inbounds i16, ptr [[ARG1]], i64 [[I17]]
+; SPIRV-NEXT:    [[I19:%.*]] = load i16, ptr [[I18]], align 2
+; SPIRV-NEXT:    [[I20:%.*]] = zext i16 [[I19]] to i32
+; SPIRV-NEXT:    [[I21:%.*]] = sub nsw i32 [[I20]], [[I15]]
+; SPIRV-NEXT:    [[I22:%.*]] = mul nsw i32 [[I11]], [[I21]]
+; SPIRV-NEXT:    [[I23:%.*]] = ashr i32 [[I22]], 15
+; SPIRV-NEXT:    [[I24:%.*]] = shl nuw nsw i32 [[I5]], 15
+; SPIRV-NEXT:    [[I25:%.*]] = xor i32 [[I24]], 1015808
+; SPIRV-NEXT:    [[I26:%.*]] = add nuw nsw i32 [[I25]], [[I15]]
+; SPIRV-NEXT:    [[I27:%.*]] = add nsw i32 [[I26]], [[I23]]
+; SPIRV-NEXT:    [[I28:%.*]] = sitofp i32 [[ARG]] to double
+; SPIRV-NEXT:    [[I29:%.*]] = tail call double @llvm.log2.f64(double [[I28]])
+; SPIRV-NEXT:    [[I30:%.*]] = fptosi double [[I29]] to i32
+; SPIRV-NEXT:    [[I31:%.*]] = shl nsw i32 [[I30]], 15
+; SPIRV-NEXT:    [[I32:%.*]] = or i32 [[I31]], 4
+; SPIRV-NEXT:    [[I33:%.*]] = icmp eq i32 [[I27]], [[I32]]
+; SPIRV-NEXT:    [[I34:%.*]] = select i1 [[I33]], i32 [[ARG]], i32 [[I31]]
+; SPIRV-NEXT:    [[I35:%.*]] = lshr i32 [[I34]], 1
+; SPIRV-NEXT:    [[I36:%.*]] = insertelement <16 x i8> [[I4]], i8 [[ARG3]], i32 3
+; SPIRV-NEXT:    store <16 x i8> [[I36]], ptr [[ARG2]], align 16
+; SPIRV-NEXT:    ret i32 [[I35]]
+;
+bb:
+  %i = or i32 %arg, 1
+  %i4 = load <16 x i8>, ptr %arg2, align 16
+  %i5 = tail call i32 @bar(i32 %i, i1 true)
+  %i6 = shl i32 %arg, %i5
+  %i7 = lshr i32 %i6, 26
+  %i8 = trunc i32 %i7 to i8
+  %i9 = and i8 %i8, 31
+  %i10 = lshr i32 %i6, 11
+  %i11 = and i32 %i10, 32767
+  %i12 = zext i8 %i9 to i64
+  %i13 = getelementptr inbounds i16, ptr %arg1, i64 %i12
+  %i14 = load i16, ptr %i13, align 2
+  %i15 = zext i16 %i14 to i32
+  %i16 = add nuw nsw i8 %i9, 1
+  %i17 = zext i8 %i16 to i64
+  %i18 = getelementptr inbounds i16, ptr %arg1, i64 %i17
+  %i19 = load i16, ptr %i18, align 2
+  %i20 = zext i16 %i19 to i32
+  %i21 = sub nsw i32 %i20, %i15
+  %i22 = mul nsw i32 %i11, %i21
+  %i23 = ashr i32 %i22, 15
+  %i24 = shl nuw nsw i32 %i5, 15
+  %i25 = xor i32 %i24, 1015808
+  %i26 = add nuw nsw i32 %i25, %i15
+  %i27 = add nsw i32 %i26, %i23
+  %i28 = sitofp i32 %arg to double
+  %i29 = tail call double @llvm.log2.f64(double %i28)
+  %i30 = fptosi double %i29 to i32
+  %i31 = shl nsw i32 %i30, 15
+  %i32 = or i32 %i31, 4
+  %i33 = icmp eq i32 %i27, %i32
+  %i34 = select i1 %i33, i32 %arg, i32 %i31
+  %i35 = lshr i32 %i34, 1
+  %i36 = insertelement <16 x i8> %i4, i8 %arg3, i32 3
+  store <16 x i8> %i36, ptr %arg2, align 16
+  ret i32 %i35
+}
+
+declare i32 @bar(i32, i1) readonly
+declare double @llvm.log2.f64(double)
+
diff --git a/llvm/test/Transforms/VectorCombine/load-insert-store.ll b/llvm/test/Transforms/VectorCombine/load-insert-store.ll
index 0181ec76088bd..9864bb8964e75 100644
--- a/llvm/test/Transforms/VectorCombine/load-insert-store.ll
+++ b/llvm/test/Transforms/VectorCombine/load-insert-store.ll
@@ -1,7 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt -S -passes=vector-combine -data-layout=e < %s | FileCheck %s
 ; RUN: opt -S -passes=vector-combine -data-layout=E < %s | FileCheck %s
-; RUN: opt -S -passes=vector-combine -data-layout=E -mtriple=spirv-unknown-vulkan1.3-library %s | FileCheck %s --check-prefix=SPIRV
 
 define void @insert_store(ptr %q, i8 zeroext %s) {
 ; CHECK-LABEL: @insert_store(

>From 8f49a51b7ec99ae50151abc77fd7c77e990fabbb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= <brioche at google.com>
Date: Tue, 29 Jul 2025 17:39:45 +0200
Subject: [PATCH 4/6] rename to allowVectorElementIndexingUsingGEP

---
 llvm/include/llvm/Analysis/TargetTransformInfo.h | 2 +-
 llvm/lib/Analysis/TargetTransformInfo.cpp        | 4 ++--
 llvm/lib/Target/SPIRV/SPIRVTargetTransformInfo.h | 2 +-
 llvm/lib/Transforms/Vectorize/VectorCombine.cpp  | 6 +++---
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/llvm/include/llvm/Analysis/TargetTransformInfo.h b/llvm/include/llvm/Analysis/TargetTransformInfo.h
index be0529754a116..aa4550de455e0 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfo.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfo.h
@@ -1952,7 +1952,7 @@ class TargetTransformInfo {
 
   /// Returns true if GEP should not be used to index into vectors for this
   /// target.
-  LLVM_ABI bool isVectorElementIndexingUsingGEPAllowed() const;
+  LLVM_ABI bool allowVectorElementIndexingUsingGEP() const;
 
 private:
   std::unique_ptr<const TargetTransformInfoImplBase> TTIImpl;
diff --git a/llvm/lib/Analysis/TargetTransformInfo.cpp b/llvm/lib/Analysis/TargetTransformInfo.cpp
index 50c1993eb35a2..c7eb2ec18c679 100644
--- a/llvm/lib/Analysis/TargetTransformInfo.cpp
+++ b/llvm/lib/Analysis/TargetTransformInfo.cpp
@@ -1486,8 +1486,8 @@ void TargetTransformInfo::collectKernelLaunchBounds(
   return TTIImpl->collectKernelLaunchBounds(F, LB);
 }
 
-bool TargetTransformInfo::isVectorElementIndexingUsingGEPAllowed() const {
-  return TTIImpl->isVectorElementIndexingUsingGEPAllowed();
+bool TargetTransformInfo::allowVectorElementIndexingUsingGEP() const {
+  return TTIImpl->allowVectorElementIndexingUsingGEP();
 }
 
 TargetTransformInfoImplBase::~TargetTransformInfoImplBase() = default;
diff --git a/llvm/lib/Target/SPIRV/SPIRVTargetTransformInfo.h b/llvm/lib/Target/SPIRV/SPIRVTargetTransformInfo.h
index bd066873a28af..60c4e2de2fb23 100644
--- a/llvm/lib/Target/SPIRV/SPIRVTargetTransformInfo.h
+++ b/llvm/lib/Target/SPIRV/SPIRVTargetTransformInfo.h
@@ -60,7 +60,7 @@ class SPIRVTTIImpl final : public BasicTTIImplBase<SPIRVTTIImpl> {
   Value *rewriteIntrinsicWithAddressSpace(IntrinsicInst *II, Value *OldV,
                                           Value *NewV) const override;
 
-  bool isVectorElementIndexingUsingGEPAllowed() const override { return false; }
+  bool allowVectorElementIndexingUsingGEP() const override { return false; }
 };
 
 } // namespace llvm
diff --git a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
index 0d9a93fd5f99b..6345b18b809a6 100644
--- a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
+++ b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
@@ -1664,7 +1664,7 @@ static Align computeAlignmentAfterScalarization(Align VectorAlignment,
 //   %1 = getelementptr inbounds i32, i32* %0, i64 0, i64 1
 //   store i32 %b, i32* %1
 bool VectorCombine::foldSingleElementStore(Instruction &I) {
-  if (!TTI.isVectorElementIndexingUsingGEPAllowed())
+  if (!TTI.allowVectorElementIndexingUsingGEP())
     return false;
   auto *SI = cast<StoreInst>(&I);
   if (!SI->isSimple() || !isa<VectorType>(SI->getValueOperand()->getType()))
@@ -1721,7 +1721,7 @@ bool VectorCombine::foldSingleElementStore(Instruction &I) {
 
 /// Try to scalarize vector loads feeding extractelement instructions.
 bool VectorCombine::scalarizeLoadExtract(Instruction &I) {
-  if (!TTI.isVectorElementIndexingUsingGEPAllowed())
+  if (!TTI.allowVectorElementIndexingUsingGEP())
     return false;
 
   Value *Ptr;
@@ -1832,7 +1832,7 @@ bool VectorCombine::scalarizeLoadExtract(Instruction &I) {
 }
 
 bool VectorCombine::scalarizeExtExtract(Instruction &I) {
-  if (!TTI.isVectorElementIndexingUsingGEPAllowed())
+  if (!TTI.allowVectorElementIndexingUsingGEP())
     return false;
   auto *Ext = dyn_cast<ZExtInst>(&I);
   if (!Ext)

>From 37d4fb110d93604a258b26c0c122084ab85eab1f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= <brioche at google.com>
Date: Tue, 29 Jul 2025 17:41:12 +0200
Subject: [PATCH 5/6] fix one missing rename

---
 llvm/include/llvm/Analysis/TargetTransformInfoImpl.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
index 0e705cc8258f2..abdbca04488db 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -1145,7 +1145,7 @@ class TargetTransformInfoImplBase {
       const Function &F,
       SmallVectorImpl<std::pair<StringRef, int64_t>> &LB) const {}
 
-  virtual bool isVectorElementIndexingUsingGEPAllowed() const { return true; }
+  virtual bool allowVectorElementIndexingUsingGEP() const { return true; }
 
 protected:
   // Obtain the minimum required size to hold the value (without the sign)

>From 775680905e7d38f359d60d26c32e800ba658f021 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= <brioche at google.com>
Date: Wed, 30 Jul 2025 19:33:59 +0200
Subject: [PATCH 6/6] remove obsolete test lines

---
 .../VectorCombine/load-insert-store.ll        | 381 ------------------
 1 file changed, 381 deletions(-)

diff --git a/llvm/test/Transforms/VectorCombine/load-insert-store.ll b/llvm/test/Transforms/VectorCombine/load-insert-store.ll
index 9864bb8964e75..93565c1a708eb 100644
--- a/llvm/test/Transforms/VectorCombine/load-insert-store.ll
+++ b/llvm/test/Transforms/VectorCombine/load-insert-store.ll
@@ -9,13 +9,6 @@ define void @insert_store(ptr %q, i8 zeroext %s) {
 ; CHECK-NEXT:    store i8 [[S:%.*]], ptr [[TMP0]], align 1
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 3
-; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <16 x i8>, ptr %q
   %vecins = insertelement <16 x i8> %0, i8 %s, i32 3
@@ -30,13 +23,6 @@ define void @insert_store_i16_align1(ptr %q, i16 zeroext %s) {
 ; CHECK-NEXT:    store i16 [[S:%.*]], ptr [[TMP0]], align 2
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_i16_align1(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <8 x i16>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <8 x i16> [[TMP0]], i16 [[S:%.*]], i32 3
-; SPIRV-NEXT:    store <8 x i16> [[VECINS]], ptr [[Q]], align 1
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <8 x i16>, ptr %q
   %vecins = insertelement <8 x i16> %0, i16 %s, i32 3
@@ -53,13 +39,6 @@ define void @insert_store_outofbounds(ptr %q, i16 zeroext %s) {
 ; CHECK-NEXT:    store <8 x i16> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_outofbounds(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <8 x i16>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <8 x i16> [[TMP0]], i16 [[S:%.*]], i32 9
-; SPIRV-NEXT:    store <8 x i16> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <8 x i16>, ptr %q
   %vecins = insertelement <8 x i16> %0, i16 %s, i32 9
@@ -74,13 +53,6 @@ define void @insert_store_vscale(ptr %q, i16 zeroext %s) {
 ; CHECK-NEXT:    store i16 [[S:%.*]], ptr [[TMP0]], align 2
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_vscale(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <vscale x 8 x i16>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <vscale x 8 x i16> [[TMP0]], i16 [[S:%.*]], i32 3
-; SPIRV-NEXT:    store <vscale x 8 x i16> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <vscale x 8 x i16>, ptr %q
   %vecins = insertelement <vscale x 8 x i16> %0, i16 %s, i32 3
@@ -98,13 +70,6 @@ define void @insert_store_vscale_exceeds(ptr %q, i16 zeroext %s) {
 ; CHECK-NEXT:    store <vscale x 8 x i16> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_vscale_exceeds(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <vscale x 8 x i16>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <vscale x 8 x i16> [[TMP0]], i16 [[S:%.*]], i32 9
-; SPIRV-NEXT:    store <vscale x 8 x i16> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <vscale x 8 x i16>, ptr %q
   %vecins = insertelement <vscale x 8 x i16> %0, i16 %s, i32 9
@@ -120,13 +85,6 @@ define void @insert_store_v9i4(ptr %q, i4 zeroext %s) {
 ; CHECK-NEXT:    store <9 x i4> [[VECINS]], ptr [[Q]], align 1
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_v9i4(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <9 x i4>, ptr [[Q:%.*]], align 8
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <9 x i4> [[TMP0]], i4 [[S:%.*]], i32 3
-; SPIRV-NEXT:    store <9 x i4> [[VECINS]], ptr [[Q]], align 1
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <9 x i4>, ptr %q
   %vecins = insertelement <9 x i4> %0, i4 %s, i32 3
@@ -142,13 +100,6 @@ define void @insert_store_v4i27(ptr %q, i27 zeroext %s) {
 ; CHECK-NEXT:    store <4 x i27> [[VECINS]], ptr [[Q]], align 1
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_v4i27(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <4 x i27>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <4 x i27> [[TMP0]], i27 [[S:%.*]], i32 3
-; SPIRV-NEXT:    store <4 x i27> [[VECINS]], ptr [[Q]], align 1
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <4 x i27>, ptr %q
   %vecins = insertelement <4 x i27> %0, i27 %s, i32 3
@@ -162,12 +113,6 @@ define void @insert_store_v32i1(ptr %p) {
 ; CHECK-NEXT:    [[INS:%.*]] = insertelement <32 x i1> [[VEC]], i1 true, i64 0
 ; CHECK-NEXT:    store <32 x i1> [[INS]], ptr [[P]], align 4
 ; CHECK-NEXT:    ret void
-;
-; SPIRV-LABEL: @insert_store_v32i1(
-; SPIRV-NEXT:    [[VEC:%.*]] = load <32 x i1>, ptr [[P:%.*]], align 4
-; SPIRV-NEXT:    [[INS:%.*]] = insertelement <32 x i1> [[VEC]], i1 true, i64 0
-; SPIRV-NEXT:    store <32 x i1> [[INS]], ptr [[P]], align 4
-; SPIRV-NEXT:    ret void
 ;
   %vec = load <32 x i1>, ptr %p
   %ins = insertelement <32 x i1> %vec, i1 true, i64 0
@@ -185,15 +130,6 @@ define void @insert_store_blk_differ(ptr %q, i16 zeroext %s) {
 ; CHECK-NEXT:    store <8 x i16> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_blk_differ(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <8 x i16>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    br label [[CONT:%.*]]
-; SPIRV:       cont:
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <8 x i16> [[TMP0]], i16 [[S:%.*]], i32 3
-; SPIRV-NEXT:    store <8 x i16> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <8 x i16>, ptr %q
   br label %cont
@@ -211,13 +147,6 @@ define void @insert_store_nonconst(ptr %q, i8 zeroext %s, i32 %idx) {
 ; CHECK-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_nonconst(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX:%.*]]
-; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <16 x i8>, ptr %q
   %vecins = insertelement <16 x i8> %0, i8 %s, i32 %idx
@@ -235,13 +164,6 @@ define void @insert_store_vscale_nonconst(ptr %q, i8 zeroext %s, i32 %idx) {
 ; CHECK-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_vscale_nonconst(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <vscale x 16 x i8>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <vscale x 16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX:%.*]]
-; SPIRV-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <vscale x 16 x i8>, ptr %q
   %vecins = insertelement <vscale x 16 x i8> %0, i8 %s, i32 %idx
@@ -259,15 +181,6 @@ define void @insert_store_nonconst_large_alignment(ptr %q, i32 zeroext %s, i32 %
 ; CHECK-NEXT:    store i32 [[S:%.*]], ptr [[TMP0]], align 4
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_nonconst_large_alignment(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX:%.*]], 4
-; SPIRV-NEXT:    call void @llvm.assume(i1 [[CMP]])
-; SPIRV-NEXT:    [[I:%.*]] = load <4 x i32>, ptr [[Q:%.*]], align 128
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <4 x i32> [[I]], i32 [[S:%.*]], i32 [[IDX]]
-; SPIRV-NEXT:    store <4 x i32> [[VECINS]], ptr [[Q]], align 128
-; SPIRV-NEXT:    ret void
-;
 entry:
   %cmp = icmp ult i32 %idx, 4
   call void @llvm.assume(i1 %cmp)
@@ -284,14 +197,6 @@ define void @insert_store_nonconst_align_maximum_8(ptr %q, i64 %s, i32 %idx) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds <8 x i64>, ptr [[Q:%.*]], i32 0, i32 [[IDX]]
 ; CHECK-NEXT:    store i64 [[S:%.*]], ptr [[TMP1]], align 8
 ; CHECK-NEXT:    ret void
-;
-; SPIRV-LABEL: @insert_store_nonconst_align_maximum_8(
-; SPIRV-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX:%.*]], 2
-; SPIRV-NEXT:    call void @llvm.assume(i1 [[CMP]])
-; SPIRV-NEXT:    [[I:%.*]] = load <8 x i64>, ptr [[Q:%.*]], align 8
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <8 x i64> [[I]], i64 [[S:%.*]], i32 [[IDX]]
-; SPIRV-NEXT:    store <8 x i64> [[VECINS]], ptr [[Q]], align 8
-; SPIRV-NEXT:    ret void
 ;
   %cmp = icmp ult i32 %idx, 2
   call void @llvm.assume(i1 %cmp)
@@ -308,14 +213,6 @@ define void @insert_store_nonconst_align_maximum_4(ptr %q, i64 %s, i32 %idx) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds <8 x i64>, ptr [[Q:%.*]], i32 0, i32 [[IDX]]
 ; CHECK-NEXT:    store i64 [[S:%.*]], ptr [[TMP1]], align 4
 ; CHECK-NEXT:    ret void
-;
-; SPIRV-LABEL: @insert_store_nonconst_align_maximum_4(
-; SPIRV-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX:%.*]], 2
-; SPIRV-NEXT:    call void @llvm.assume(i1 [[CMP]])
-; SPIRV-NEXT:    [[I:%.*]] = load <8 x i64>, ptr [[Q:%.*]], align 4
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <8 x i64> [[I]], i64 [[S:%.*]], i32 [[IDX]]
-; SPIRV-NEXT:    store <8 x i64> [[VECINS]], ptr [[Q]], align 4
-; SPIRV-NEXT:    ret void
 ;
   %cmp = icmp ult i32 %idx, 2
   call void @llvm.assume(i1 %cmp)
@@ -332,14 +229,6 @@ define void @insert_store_nonconst_align_larger(ptr %q, i64 %s, i32 %idx) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds <8 x i64>, ptr [[Q:%.*]], i32 0, i32 [[IDX]]
 ; CHECK-NEXT:    store i64 [[S:%.*]], ptr [[TMP1]], align 4
 ; CHECK-NEXT:    ret void
-;
-; SPIRV-LABEL: @insert_store_nonconst_align_larger(
-; SPIRV-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX:%.*]], 2
-; SPIRV-NEXT:    call void @llvm.assume(i1 [[CMP]])
-; SPIRV-NEXT:    [[I:%.*]] = load <8 x i64>, ptr [[Q:%.*]], align 4
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <8 x i64> [[I]], i64 [[S:%.*]], i32 [[IDX]]
-; SPIRV-NEXT:    store <8 x i64> [[VECINS]], ptr [[Q]], align 2
-; SPIRV-NEXT:    ret void
 ;
   %cmp = icmp ult i32 %idx, 2
   call void @llvm.assume(i1 %cmp)
@@ -358,15 +247,6 @@ define void @insert_store_nonconst_index_known_valid_by_assume(ptr %q, i8 zeroex
 ; CHECK-NEXT:    store i8 [[S:%.*]], ptr [[TMP0]], align 1
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_nonconst_index_known_valid_by_assume(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX:%.*]], 4
-; SPIRV-NEXT:    call void @llvm.assume(i1 [[CMP]])
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX]]
-; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %cmp = icmp ult i32 %idx, 4
   call void @llvm.assume(i1 %cmp)
@@ -387,15 +267,6 @@ define void @insert_store_vscale_nonconst_index_known_valid_by_assume(ptr %q, i8
 ; CHECK-NEXT:    store i8 [[S:%.*]], ptr [[TMP0]], align 1
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_vscale_nonconst_index_known_valid_by_assume(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX:%.*]], 4
-; SPIRV-NEXT:    call void @llvm.assume(i1 [[CMP]])
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <vscale x 16 x i8>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <vscale x 16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX]]
-; SPIRV-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %cmp = icmp ult i32 %idx, 4
   call void @llvm.assume(i1 %cmp)
@@ -418,16 +289,6 @@ define void @insert_store_nonconst_index_not_known_valid_by_assume_after_load(pt
 ; CHECK-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_nonconst_index_not_known_valid_by_assume_after_load(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX:%.*]], 4
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    call void @maythrow()
-; SPIRV-NEXT:    call void @llvm.assume(i1 [[CMP]])
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX]]
-; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %cmp = icmp ult i32 %idx, 4
   %0 = load <16 x i8>, ptr %q
@@ -448,15 +309,6 @@ define void @insert_store_nonconst_index_not_known_valid_by_assume(ptr %q, i8 ze
 ; CHECK-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_nonconst_index_not_known_valid_by_assume(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX:%.*]], 17
-; SPIRV-NEXT:    call void @llvm.assume(i1 [[CMP]])
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX]]
-; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %cmp = icmp ult i32 %idx, 17
   call void @llvm.assume(i1 %cmp)
@@ -478,15 +330,6 @@ define void @insert_store_vscale_nonconst_index_not_known_valid_by_assume(ptr %q
 ; CHECK-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_vscale_nonconst_index_not_known_valid_by_assume(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX:%.*]], 17
-; SPIRV-NEXT:    call void @llvm.assume(i1 [[CMP]])
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <vscale x 16 x i8>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <vscale x 16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX]]
-; SPIRV-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %cmp = icmp ult i32 %idx, 17
   call void @llvm.assume(i1 %cmp)
@@ -506,14 +349,6 @@ define void @insert_store_nonconst_index_known_noundef_and_valid_by_and(ptr %q,
 ; CHECK-NEXT:    store i8 [[S:%.*]], ptr [[TMP0]], align 1
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_nonconst_index_known_noundef_and_valid_by_and(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = and i32 [[IDX:%.*]], 7
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
-; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <16 x i8>, ptr %q
   %idx.clamped = and i32 %idx, 7
@@ -532,14 +367,6 @@ define void @insert_store_vscale_nonconst_index_known_noundef_and_valid_by_and(p
 ; CHECK-NEXT:    store i8 [[S:%.*]], ptr [[TMP0]], align 1
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_vscale_nonconst_index_known_noundef_and_valid_by_and(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <vscale x 16 x i8>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = and i32 [[IDX:%.*]], 7
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <vscale x 16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
-; SPIRV-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <vscale x 16 x i8>, ptr %q
   %idx.clamped = and i32 %idx, 7
@@ -557,15 +384,6 @@ define void @insert_store_nonconst_index_base_frozen_and_valid_by_and(ptr %q, i8
 ; CHECK-NEXT:    store i8 [[S:%.*]], ptr [[TMP0]], align 1
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_nonconst_index_base_frozen_and_valid_by_and(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[IDX_FROZEN:%.*]] = freeze i32 [[IDX:%.*]]
-; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = and i32 [[IDX_FROZEN]], 7
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
-; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <16 x i8>, ptr %q
   %idx.frozen = freeze i32 %idx
@@ -585,15 +403,6 @@ define void @insert_store_nonconst_index_frozen_and_valid_by_and(ptr %q, i8 zero
 ; CHECK-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_nonconst_index_frozen_and_valid_by_and(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = and i32 [[IDX:%.*]], 7
-; SPIRV-NEXT:    [[IDX_CLAMPED_FROZEN:%.*]] = freeze i32 [[IDX_CLAMPED]]
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED_FROZEN]]
-; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <16 x i8>, ptr %q
   %idx.clamped = and i32 %idx, 7
@@ -612,14 +421,6 @@ define void @insert_store_nonconst_index_known_valid_by_and_but_may_be_poison(pt
 ; CHECK-NEXT:    store i8 [[S:%.*]], ptr [[TMP0]], align 1
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_nonconst_index_known_valid_by_and_but_may_be_poison(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = and i32 [[IDX:%.*]], 7
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
-; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <16 x i8>, ptr %q
   %idx.clamped = and i32 %idx, 7
@@ -637,14 +438,6 @@ define void @insert_store_nonconst_index_not_known_valid_by_and(ptr %q, i8 zeroe
 ; CHECK-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_nonconst_index_not_known_valid_by_and(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = and i32 [[IDX:%.*]], 16
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
-; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <16 x i8>, ptr %q
   %idx.clamped = and i32 %idx, 16
@@ -662,14 +455,6 @@ define void @insert_store_nonconst_index_known_noundef_not_known_valid_by_and(pt
 ; CHECK-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_nonconst_index_known_noundef_not_known_valid_by_and(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = and i32 [[IDX:%.*]], 16
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
-; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <16 x i8>, ptr %q
   %idx.clamped = and i32 %idx, 16
@@ -689,14 +474,6 @@ define void @insert_store_vscale_nonconst_index_not_known_valid_by_and(ptr %q, i
 ; CHECK-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_vscale_nonconst_index_not_known_valid_by_and(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <vscale x 16 x i8>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = and i32 [[IDX:%.*]], 31
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <vscale x 16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
-; SPIRV-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <vscale x 16 x i8>, ptr %q
   %idx.clamped = and i32 %idx, 31
@@ -713,14 +490,6 @@ define void @insert_store_nonconst_index_known_noundef_and_valid_by_urem(ptr %q,
 ; CHECK-NEXT:    store i8 [[S:%.*]], ptr [[TMP0]], align 1
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_nonconst_index_known_noundef_and_valid_by_urem(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = urem i32 [[IDX:%.*]], 16
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
-; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <16 x i8>, ptr %q
   %idx.clamped = urem i32 %idx, 16
@@ -739,14 +508,6 @@ define void @insert_store_vscale_nonconst_index_known_noundef_and_valid_by_urem(
 ; CHECK-NEXT:    store i8 [[S:%.*]], ptr [[TMP0]], align 1
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_vscale_nonconst_index_known_noundef_and_valid_by_urem(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <vscale x 16 x i8>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = urem i32 [[IDX:%.*]], 16
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <vscale x 16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
-; SPIRV-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <vscale x 16 x i8>, ptr %q
   %idx.clamped = urem i32 %idx, 16
@@ -764,15 +525,6 @@ define void @insert_store_nonconst_index_base_frozen_and_valid_by_urem(ptr %q, i
 ; CHECK-NEXT:    store i8 [[S:%.*]], ptr [[TMP0]], align 1
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_nonconst_index_base_frozen_and_valid_by_urem(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[IDX_FROZEN:%.*]] = freeze i32 [[IDX:%.*]]
-; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = urem i32 [[IDX_FROZEN]], 16
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
-; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <16 x i8>, ptr %q
   %idx.frozen = freeze i32 %idx
@@ -792,15 +544,6 @@ define void @insert_store_nonconst_index_frozen_and_valid_by_urem(ptr %q, i8 zer
 ; CHECK-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_nonconst_index_frozen_and_valid_by_urem(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = urem i32 [[IDX:%.*]], 16
-; SPIRV-NEXT:    [[IDX_CLAMPED_FROZEN:%.*]] = freeze i32 [[IDX_CLAMPED]]
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED_FROZEN]]
-; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <16 x i8>, ptr %q
   %idx.clamped = urem i32 %idx, 16
@@ -819,14 +562,6 @@ define void @insert_store_nonconst_index_known_valid_by_urem_but_may_be_poison(p
 ; CHECK-NEXT:    store i8 [[S:%.*]], ptr [[TMP0]], align 1
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_nonconst_index_known_valid_by_urem_but_may_be_poison(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = urem i32 [[IDX:%.*]], 16
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
-; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <16 x i8>, ptr %q
   %idx.clamped = urem i32 %idx, 16
@@ -844,14 +579,6 @@ define void @insert_store_nonconst_index_not_known_valid_by_urem(ptr %q, i8 zero
 ; CHECK-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_nonconst_index_not_known_valid_by_urem(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = urem i32 [[IDX:%.*]], 17
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
-; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <16 x i8>, ptr %q
   %idx.clamped = urem i32 %idx, 17
@@ -871,14 +598,6 @@ define void @insert_store_vscale_nonconst_index_not_known_valid_by_urem(ptr %q,
 ; CHECK-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_vscale_nonconst_index_not_known_valid_by_urem(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <vscale x 16 x i8>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = urem i32 [[IDX:%.*]], 17
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <vscale x 16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
-; SPIRV-NEXT:    store <vscale x 16 x i8> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <vscale x 16 x i8>, ptr %q
   %idx.clamped = urem i32 %idx, 17
@@ -896,14 +615,6 @@ define void @insert_store_nonconst_index_known_noundef_not_known_valid_by_urem(p
 ; CHECK-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_nonconst_index_known_noundef_not_known_valid_by_urem(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[IDX_CLAMPED:%.*]] = urem i32 [[IDX:%.*]], 17
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 [[IDX_CLAMPED]]
-; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <16 x i8>, ptr %q
   %idx.clamped = urem i32 %idx, 17
@@ -919,13 +630,6 @@ define void @insert_store_ptr_strip(ptr %q, i8 zeroext %s) {
 ; CHECK-NEXT:    store i8 [[S:%.*]], ptr [[TMP0]], align 1
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_ptr_strip(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[VECINS:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 3
-; SPIRV-NEXT:    store <16 x i8> [[VECINS]], ptr [[Q]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <16 x i8>, ptr %q
   %vecins = insertelement <16 x i8> %0, i8 %s, i32 3
@@ -944,16 +648,6 @@ define void @volatile_update(ptr %q, ptr %p, i8 zeroext %s) {
 ; CHECK-NEXT:    store <16 x i8> [[VECINS1]], ptr [[P]], align 16
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @volatile_update(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[VECINS0:%.*]] = insertelement <16 x i8> [[TMP0]], i8 [[S:%.*]], i32 3
-; SPIRV-NEXT:    store volatile <16 x i8> [[VECINS0]], ptr [[Q]], align 16
-; SPIRV-NEXT:    [[TMP1:%.*]] = load volatile <16 x i8>, ptr [[P:%.*]], align 16
-; SPIRV-NEXT:    [[VECINS1:%.*]] = insertelement <16 x i8> [[TMP1]], i8 [[S]], i32 1
-; SPIRV-NEXT:    store <16 x i8> [[VECINS1]], ptr [[P]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %0 = load <16 x i8>, ptr %q
   %vecins0 = insertelement <16 x i8> %0, i8 %s, i32 3
@@ -973,13 +667,6 @@ define void @insert_store_addr_differ(ptr %p, ptr %q, i8 %s) {
 ; CHECK-NEXT:    store <16 x i8> [[INS]], ptr [[Q:%.*]], align 16
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_addr_differ(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[LD:%.*]] = load <16 x i8>, ptr [[P:%.*]], align 16
-; SPIRV-NEXT:    [[INS:%.*]] = insertelement <16 x i8> [[LD]], i8 [[S:%.*]], i32 3
-; SPIRV-NEXT:    store <16 x i8> [[INS]], ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %ld = load <16 x i8>, ptr %p
   %ins = insertelement <16 x i8> %ld, i8 %s, i32 3
@@ -1004,22 +691,6 @@ define void @insert_store_mem_modify(ptr %p, ptr %q, ptr noalias %r, i8 %s, i32
 ; CHECK-NEXT:    store <4 x i32> [[INS3]], ptr [[P]], align 16
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_mem_modify(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[LD:%.*]] = load <16 x i8>, ptr [[P:%.*]], align 16
-; SPIRV-NEXT:    store <16 x i8> zeroinitializer, ptr [[Q:%.*]], align 16
-; SPIRV-NEXT:    [[INS:%.*]] = insertelement <16 x i8> [[LD]], i8 [[S:%.*]], i32 3
-; SPIRV-NEXT:    store <16 x i8> [[INS]], ptr [[P]], align 16
-; SPIRV-NEXT:    [[LD2:%.*]] = load <16 x i8>, ptr [[Q]], align 16
-; SPIRV-NEXT:    store <16 x i8> zeroinitializer, ptr [[R:%.*]], align 16
-; SPIRV-NEXT:    [[INS2:%.*]] = insertelement <16 x i8> [[LD2]], i8 [[S]], i32 7
-; SPIRV-NEXT:    store <16 x i8> [[INS2]], ptr [[Q]], align 16
-; SPIRV-NEXT:    [[LD3:%.*]] = load <4 x i32>, ptr [[P]], align 16
-; SPIRV-NEXT:    store <16 x i8> zeroinitializer, ptr [[P]], align 16
-; SPIRV-NEXT:    [[INS3:%.*]] = insertelement <4 x i32> [[LD3]], i32 [[M:%.*]], i32 0
-; SPIRV-NEXT:    store <4 x i32> [[INS3]], ptr [[P]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   ; p may alias q
   %ld = load <16 x i8>, ptr %p
@@ -1056,19 +727,6 @@ define void @insert_store_with_call(ptr %p, ptr %q, i8 %s) {
 ; CHECK-NEXT:    store i8 [[S]], ptr [[TMP0]], align 1
 ; CHECK-NEXT:    ret void
 ;
-; SPIRV-LABEL: @insert_store_with_call(
-; SPIRV-NEXT:  entry:
-; SPIRV-NEXT:    [[LD:%.*]] = load <16 x i8>, ptr [[P:%.*]], align 16
-; SPIRV-NEXT:    call void @maywrite(ptr [[P]])
-; SPIRV-NEXT:    [[INS:%.*]] = insertelement <16 x i8> [[LD]], i8 [[S:%.*]], i32 3
-; SPIRV-NEXT:    store <16 x i8> [[INS]], ptr [[P]], align 16
-; SPIRV-NEXT:    call void @foo()
-; SPIRV-NEXT:    [[LD2:%.*]] = load <16 x i8>, ptr [[P]], align 16
-; SPIRV-NEXT:    call void @nowrite(ptr [[P]])
-; SPIRV-NEXT:    [[INS2:%.*]] = insertelement <16 x i8> [[LD2]], i8 [[S]], i32 7
-; SPIRV-NEXT:    store <16 x i8> [[INS2]], ptr [[P]], align 16
-; SPIRV-NEXT:    ret void
-;
 entry:
   %ld = load <16 x i8>, ptr %p
   call void @maywrite(ptr %p)
@@ -1128,45 +786,6 @@ define i32 @insert_store_maximum_scan_instrs(i32 %arg, ptr %arg1, ptr %arg2, i8
 ; CHECK-NEXT:    store <16 x i8> [[I36]], ptr [[ARG2]], align 16
 ; CHECK-NEXT:    ret i32 [[I35]]
 ;
-; SPIRV-LABEL: @insert_store_maximum_scan_instrs(
-; SPIRV-NEXT:  bb:
-; SPIRV-NEXT:    [[I:%.*]] = or i32 [[ARG:%.*]], 1
-; SPIRV-NEXT:    [[I4:%.*]] = load <16 x i8>, ptr [[ARG2:%.*]], align 16
-; SPIRV-NEXT:    [[I5:%.*]] = tail call i32 @bar(i32 [[I]], i1 true)
-; SPIRV-NEXT:    [[I6:%.*]] = shl i32 [[ARG]], [[I5]]
-; SPIRV-NEXT:    [[I7:%.*]] = lshr i32 [[I6]], 26
-; SPIRV-NEXT:    [[I8:%.*]] = trunc i32 [[I7]] to i8
-; SPIRV-NEXT:    [[I9:%.*]] = and i8 [[I8]], 31
-; SPIRV-NEXT:    [[I10:%.*]] = lshr i32 [[I6]], 11
-; SPIRV-NEXT:    [[I11:%.*]] = and i32 [[I10]], 32767
-; SPIRV-NEXT:    [[I12:%.*]] = zext i8 [[I9]] to i64
-; SPIRV-NEXT:    [[I13:%.*]] = getelementptr inbounds i16, ptr [[ARG1:%.*]], i64 [[I12]]
-; SPIRV-NEXT:    [[I14:%.*]] = load i16, ptr [[I13]], align 2
-; SPIRV-NEXT:    [[I15:%.*]] = zext i16 [[I14]] to i32
-; SPIRV-NEXT:    [[I16:%.*]] = add nuw nsw i8 [[I9]], 1
-; SPIRV-NEXT:    [[I17:%.*]] = zext i8 [[I16]] to i64
-; SPIRV-NEXT:    [[I18:%.*]] = getelementptr inbounds i16, ptr [[ARG1]], i64 [[I17]]
-; SPIRV-NEXT:    [[I19:%.*]] = load i16, ptr [[I18]], align 2
-; SPIRV-NEXT:    [[I20:%.*]] = zext i16 [[I19]] to i32
-; SPIRV-NEXT:    [[I21:%.*]] = sub nsw i32 [[I20]], [[I15]]
-; SPIRV-NEXT:    [[I22:%.*]] = mul nsw i32 [[I11]], [[I21]]
-; SPIRV-NEXT:    [[I23:%.*]] = ashr i32 [[I22]], 15
-; SPIRV-NEXT:    [[I24:%.*]] = shl nuw nsw i32 [[I5]], 15
-; SPIRV-NEXT:    [[I25:%.*]] = xor i32 [[I24]], 1015808
-; SPIRV-NEXT:    [[I26:%.*]] = add nuw nsw i32 [[I25]], [[I15]]
-; SPIRV-NEXT:    [[I27:%.*]] = add nsw i32 [[I26]], [[I23]]
-; SPIRV-NEXT:    [[I28:%.*]] = sitofp i32 [[ARG]] to double
-; SPIRV-NEXT:    [[I29:%.*]] = tail call double @llvm.log2.f64(double [[I28]])
-; SPIRV-NEXT:    [[I30:%.*]] = fptosi double [[I29]] to i32
-; SPIRV-NEXT:    [[I31:%.*]] = shl nsw i32 [[I30]], 15
-; SPIRV-NEXT:    [[I32:%.*]] = or i32 [[I31]], 4
-; SPIRV-NEXT:    [[I33:%.*]] = icmp eq i32 [[I27]], [[I32]]
-; SPIRV-NEXT:    [[I34:%.*]] = select i1 [[I33]], i32 [[ARG]], i32 [[I31]]
-; SPIRV-NEXT:    [[I35:%.*]] = lshr i32 [[I34]], 1
-; SPIRV-NEXT:    [[I36:%.*]] = insertelement <16 x i8> [[I4]], i8 [[ARG3:%.*]], i32 3
-; SPIRV-NEXT:    store <16 x i8> [[I36]], ptr [[ARG2]], align 16
-; SPIRV-NEXT:    ret i32 [[I35]]
-;
 bb:
   %i = or i32 %arg, 1
   %i4 = load <16 x i8>, ptr %arg2, align 16



More information about the llvm-commits mailing list