brintos

brintos / llvm-project-archived public Read only

0
0
Text · 35.3 KiB · 64e22e1 Raw
777 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S < %s -passes=newgvn,dce | FileCheck %s3 4; Analyze Load from clobbering Load.5 6define <vscale x 4 x i32> @load_store_clobber_load(ptr %p)  {7; CHECK-LABEL: @load_store_clobber_load(8; CHECK-NEXT:    [[LOAD1:%.*]] = load <vscale x 4 x i32>, ptr [[P:%.*]], align 169; CHECK-NEXT:    store <vscale x 4 x i32> zeroinitializer, ptr undef, align 1610; CHECK-NEXT:    [[ADD:%.*]] = add <vscale x 4 x i32> [[LOAD1]], [[LOAD1]]11; CHECK-NEXT:    ret <vscale x 4 x i32> [[ADD]]12;13  %load1 = load <vscale x 4 x i32>, ptr %p14  store <vscale x 4 x i32> zeroinitializer, ptr undef15  %load2 = load <vscale x 4 x i32>, ptr %p ; <- load to be eliminated16  %add = add <vscale x 4 x i32> %load1, %load217  ret <vscale x 4 x i32> %add18}19 20define <vscale x 4 x i32> @load_store_clobber_load_mayalias(ptr %p, ptr %p2) {21; CHECK-LABEL: @load_store_clobber_load_mayalias(22; CHECK-NEXT:    [[LOAD1:%.*]] = load <vscale x 4 x i32>, ptr [[P:%.*]], align 1623; CHECK-NEXT:    store <vscale x 4 x i32> zeroinitializer, ptr [[P2:%.*]], align 1624; CHECK-NEXT:    [[LOAD2:%.*]] = load <vscale x 4 x i32>, ptr [[P]], align 1625; CHECK-NEXT:    [[SUB:%.*]] = sub <vscale x 4 x i32> [[LOAD1]], [[LOAD2]]26; CHECK-NEXT:    ret <vscale x 4 x i32> [[SUB]]27;28  %load1 = load <vscale x 4 x i32>, ptr %p29  store <vscale x 4 x i32> zeroinitializer, ptr %p230  %load2 = load <vscale x 4 x i32>, ptr %p31  %sub = sub <vscale x 4 x i32> %load1, %load232  ret <vscale x 4 x i32> %sub33}34 35define <vscale x 4 x i32> @load_store_clobber_load_noalias(ptr noalias %p, ptr noalias %p2) {36; CHECK-LABEL: @load_store_clobber_load_noalias(37; CHECK-NEXT:    [[LOAD1:%.*]] = load <vscale x 4 x i32>, ptr [[P:%.*]], align 1638; CHECK-NEXT:    store <vscale x 4 x i32> zeroinitializer, ptr [[P2:%.*]], align 1639; CHECK-NEXT:    [[ADD:%.*]] = add <vscale x 4 x i32> [[LOAD1]], [[LOAD1]]40; CHECK-NEXT:    ret <vscale x 4 x i32> [[ADD]]41;42  %load1 = load <vscale x 4 x i32>, ptr %p43  store <vscale x 4 x i32> zeroinitializer, ptr %p244  %load2 = load <vscale x 4 x i32>, ptr %p ; <- load to be eliminated45  %add = add <vscale x 4 x i32> %load1, %load246  ret <vscale x 4 x i32> %add47}48 49; BasicAA return MayAlias for %gep1,%gep2, could improve as MustAlias.50define i32 @load_clobber_load_gep1(ptr %p) {51; CHECK-LABEL: @load_clobber_load_gep1(52; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P:%.*]], i64 0, i64 153; CHECK-NEXT:    [[LOAD1:%.*]] = load i32, ptr [[GEP1]], align 454; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr i32, ptr [[P]], i64 155; CHECK-NEXT:    [[LOAD2:%.*]] = load i32, ptr [[GEP2]], align 456; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[LOAD1]], [[LOAD2]]57; CHECK-NEXT:    ret i32 [[ADD]]58;59  %gep1 = getelementptr <vscale x 4 x i32>, ptr %p, i64 0, i64 160  %load1 = load i32, ptr %gep161  %gep2 = getelementptr i32, ptr %p, i64 162  %load2 = load i32, ptr %gep2 ; <- load could be eliminated63  %add = add i32 %load1, %load264  ret i32 %add65}66 67define i32 @load_clobber_load_gep2(ptr %p) {68; CHECK-LABEL: @load_clobber_load_gep2(69; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P:%.*]], i64 1, i64 070; CHECK-NEXT:    [[LOAD1:%.*]] = load i32, ptr [[GEP1]], align 471; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr i32, ptr [[P]], i64 472; CHECK-NEXT:    [[LOAD2:%.*]] = load i32, ptr [[GEP2]], align 473; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[LOAD1]], [[LOAD2]]74; CHECK-NEXT:    ret i32 [[ADD]]75;76  %gep1 = getelementptr <vscale x 4 x i32>, ptr %p, i64 1, i64 077  %load1 = load i32, ptr %gep178  %gep2 = getelementptr i32, ptr %p, i64 479  %load2 = load i32, ptr %gep2 ; <- can not determine at compile-time if %load1 and %load2 are same addr80  %add = add i32 %load1, %load281  ret i32 %add82}83 84; TODO: BasicAA return MayAlias for %gep1,%gep2, could improve as MustAlias.85define i32 @load_clobber_load_gep3(ptr %p) {86; CHECK-LABEL: @load_clobber_load_gep3(87; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P:%.*]], i64 1, i64 088; CHECK-NEXT:    [[LOAD1:%.*]] = load i32, ptr [[GEP1]], align 489; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr <vscale x 4 x float>, ptr [[P]], i64 1, i64 090; CHECK-NEXT:    [[LOAD2:%.*]] = load float, ptr [[GEP2]], align 491; CHECK-NEXT:    [[CAST:%.*]] = bitcast float [[LOAD2]] to i3292; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[LOAD1]], [[CAST]]93; CHECK-NEXT:    ret i32 [[ADD]]94;95  %gep1 = getelementptr <vscale x 4 x i32>, ptr %p, i64 1, i64 096  %load1 = load i32, ptr %gep197  %gep2 = getelementptr <vscale x 4 x float>, ptr %p, i64 1, i64 098  %load2 = load float, ptr %gep2 ; <- load could be eliminated99  %cast = bitcast float %load2 to i32100  %add = add i32 %load1, %cast101  ret i32 %add102}103 104define <vscale x 4 x i32> @load_clobber_load_fence(ptr %p) {105; CHECK-LABEL: @load_clobber_load_fence(106; CHECK-NEXT:    [[LOAD1:%.*]] = load <vscale x 4 x i32>, ptr [[P:%.*]], align 16107; CHECK-NEXT:    call void asm "", "~{memory}"()108; CHECK-NEXT:    [[LOAD2:%.*]] = load <vscale x 4 x i32>, ptr [[P]], align 16109; CHECK-NEXT:    [[SUB:%.*]] = sub <vscale x 4 x i32> [[LOAD1]], [[LOAD2]]110; CHECK-NEXT:    ret <vscale x 4 x i32> [[SUB]]111;112  %load1 = load <vscale x 4 x i32>, ptr %p113  call void asm "", "~{memory}"()114  %load2 = load <vscale x 4 x i32>, ptr %p115  %sub = sub <vscale x 4 x i32> %load1, %load2116  ret <vscale x 4 x i32> %sub117}118 119define <vscale x 4 x i32> @load_clobber_load_sideeffect(ptr %p) {120; CHECK-LABEL: @load_clobber_load_sideeffect(121; CHECK-NEXT:    [[LOAD1:%.*]] = load <vscale x 4 x i32>, ptr [[P:%.*]], align 16122; CHECK-NEXT:    call void asm sideeffect "", ""()123; CHECK-NEXT:    [[LOAD2:%.*]] = load <vscale x 4 x i32>, ptr [[P]], align 16124; CHECK-NEXT:    [[ADD:%.*]] = add <vscale x 4 x i32> [[LOAD1]], [[LOAD2]]125; CHECK-NEXT:    ret <vscale x 4 x i32> [[ADD]]126;127  %load1 = load <vscale x 4 x i32>, ptr %p128  call void asm sideeffect "", ""()129  %load2 = load <vscale x 4 x i32>, ptr %p130  %add = add <vscale x 4 x i32> %load1, %load2131  ret <vscale x 4 x i32> %add132}133 134; Analyze Load from clobbering Store.135 136define <vscale x 4 x i32> @store_forward_to_load(ptr %p) {137; CHECK-LABEL: @store_forward_to_load(138; CHECK-NEXT:    store <vscale x 4 x i32> zeroinitializer, ptr [[P:%.*]], align 16139; CHECK-NEXT:    ret <vscale x 4 x i32> zeroinitializer140;141  store <vscale x 4 x i32> zeroinitializer, ptr %p142  %load = load <vscale x 4 x i32>, ptr %p143  ret <vscale x 4 x i32> %load144}145 146define <vscale x 4 x i32> @store_forward_to_load_sideeffect(ptr %p) {147; CHECK-LABEL: @store_forward_to_load_sideeffect(148; CHECK-NEXT:    store <vscale x 4 x i32> zeroinitializer, ptr [[P:%.*]], align 16149; CHECK-NEXT:    call void asm sideeffect "", ""()150; CHECK-NEXT:    [[LOAD:%.*]] = load <vscale x 4 x i32>, ptr [[P]], align 16151; CHECK-NEXT:    ret <vscale x 4 x i32> [[LOAD]]152;153  store <vscale x 4 x i32> zeroinitializer, ptr %p154  call void asm sideeffect "", ""()155  %load = load <vscale x 4 x i32>, ptr %p156  ret <vscale x 4 x i32> %load157}158 159define i32 @store_clobber_load() {160; CHECK-LABEL: @store_clobber_load(161; CHECK-NEXT:    [[ALLOC:%.*]] = alloca <vscale x 4 x i32>, align 16162; CHECK-NEXT:    store <vscale x 4 x i32> undef, ptr [[ALLOC]], align 16163; CHECK-NEXT:    [[PTR:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[ALLOC]], i32 0, i32 1164; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[PTR]], align 4165; CHECK-NEXT:    ret i32 [[LOAD]]166;167  %alloc = alloca <vscale x 4 x i32>168  store <vscale x 4 x i32> undef, ptr %alloc169  %ptr = getelementptr <vscale x 4 x i32>, ptr %alloc, i32 0, i32 1170  %load = load i32, ptr %ptr171  ret i32 %load172}173 174; Analyze Load from clobbering MemInst.175 176declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1)177 178define i32 @memset_clobber_load(ptr %p) {179; CHECK-LABEL: @memset_clobber_load(180; CHECK-NEXT:    tail call void @llvm.memset.p0.i64(ptr [[P:%.*]], i8 1, i64 200, i1 false)181; CHECK-NEXT:    ret i32 16843009182;183  tail call void @llvm.memset.p0.i64(ptr %p, i8 1, i64 200, i1 false)184  %gep = getelementptr <vscale x 4 x i32>, ptr %p, i64 0, i64 5185  %load = load i32, ptr %gep186  ret i32 %load187}188 189define i32 @memset_clobber_load_vscaled_base(ptr %p) {190; CHECK-LABEL: @memset_clobber_load_vscaled_base(191; CHECK-NEXT:    tail call void @llvm.memset.p0.i64(ptr [[P:%.*]], i8 1, i64 200, i1 false)192; CHECK-NEXT:    [[GEP:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P]], i64 1, i64 1193; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[GEP]], align 4194; CHECK-NEXT:    ret i32 [[LOAD]]195;196  tail call void @llvm.memset.p0.i64(ptr %p, i8 1, i64 200, i1 false)197  %gep = getelementptr <vscale x 4 x i32>, ptr %p, i64 1, i64 1198  %load = load i32, ptr %gep199  ret i32 %load200}201 202define i32 @memset_clobber_load_nonconst_index(ptr %p, i64 %idx1, i64 %idx2) {203; CHECK-LABEL: @memset_clobber_load_nonconst_index(204; CHECK-NEXT:    tail call void @llvm.memset.p0.i64(ptr [[P:%.*]], i8 1, i64 200, i1 false)205; CHECK-NEXT:    [[GEP:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P]], i64 [[IDX1:%.*]], i64 [[IDX2:%.*]]206; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[GEP]], align 4207; CHECK-NEXT:    ret i32 [[LOAD]]208;209  tail call void @llvm.memset.p0.i64(ptr %p, i8 1, i64 200, i1 false)210  %gep = getelementptr <vscale x 4 x i32>, ptr %p, i64 %idx1, i64 %idx2211  %load = load i32, ptr %gep212  ret i32 %load213}214 215 216; Load elimination across BBs217 218define ptr @load_from_alloc_replaced_with_undef() {219; CHECK-LABEL: @load_from_alloc_replaced_with_undef(220; CHECK-NEXT:  entry:221; CHECK-NEXT:    [[A:%.*]] = alloca <vscale x 4 x i32>, align 16222; CHECK-NEXT:    [[GEP:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[A]], i64 0, i64 1223; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[GEP]], align 4224; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[LOAD]], 0225; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]226; CHECK:       if.then:227; CHECK-NEXT:    store <vscale x 4 x i32> zeroinitializer, ptr [[A]], align 16228; CHECK-NEXT:    br label [[IF_END]]229; CHECK:       if.end:230; CHECK-NEXT:    ret ptr [[A]]231;232entry:233  %a = alloca <vscale x 4 x i32>234  %gep = getelementptr <vscale x 4 x i32>, ptr %a, i64 0, i64 1235  %load = load i32, ptr %gep ; <- load to be eliminated236  %tobool = icmp eq i32 %load, 0 ; <- icmp to be eliminated237  br i1 %tobool, label %if.end, label %if.then238 239if.then:240  store <vscale x 4 x i32> zeroinitializer, ptr %a241  br label %if.end242 243if.end:244  ret ptr %a245}246 247define i32 @redundant_load_elimination_1(ptr %p) {248; CHECK-LABEL: @redundant_load_elimination_1(249; CHECK-NEXT:  entry:250; CHECK-NEXT:    [[GEP:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P:%.*]], i64 1, i64 1251; CHECK-NEXT:    [[LOAD1:%.*]] = load i32, ptr [[GEP]], align 4252; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[LOAD1]], 0253; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]254; CHECK:       if.then:255; CHECK-NEXT:    br label [[IF_END]]256; CHECK:       if.end:257; CHECK-NEXT:    ret i32 [[LOAD1]]258;259entry:260  %gep = getelementptr <vscale x 4 x i32>, ptr %p, i64 1, i64 1261  %load1 = load i32, ptr %gep262  %cmp = icmp eq i32 %load1, 0263  br i1 %cmp, label %if.then, label %if.end264 265if.then:266  %load2 = load i32, ptr %gep ; <- load to be eliminated267  %add = add i32 %load1, %load2268  br label %if.end269 270if.end:271  %result = phi i32 [ %add, %if.then ], [ %load1, %entry ]272  ret i32 %result273}274 275; TODO: BasicAA return MayAlias for %gep1,%gep2, could improve as NoAlias.276define void @redundant_load_elimination_2(i1 %c, ptr %p, ptr %q) {277; CHECK-LABEL: @redundant_load_elimination_2(278; CHECK-NEXT:  entry:279; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P:%.*]], i64 1, i64 1280; CHECK-NEXT:    store i32 0, ptr [[GEP1]], align 4281; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P]], i64 1, i64 0282; CHECK-NEXT:    store i32 1, ptr [[GEP2]], align 4283; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]284; CHECK:       if.then:285; CHECK-NEXT:    [[T:%.*]] = load i32, ptr [[GEP1]], align 4286; CHECK-NEXT:    store i32 [[T]], ptr [[Q:%.*]], align 4287; CHECK-NEXT:    ret void288; CHECK:       if.else:289; CHECK-NEXT:    ret void290;291entry:292  %gep1 = getelementptr <vscale x 4 x i32>, ptr %p, i64 1, i64 1293  store i32 0, ptr %gep1294  %gep2 = getelementptr <vscale x 4 x i32>, ptr %p, i64 1, i64 0295  store i32 1, ptr %gep2296  br i1 %c, label %if.else, label %if.then297 298if.then:299  %t = load i32, ptr %gep1 ; <- load could be eliminated300  store i32 %t, ptr %q301  ret void302 303if.else:304  ret void305}306 307define void @redundant_load_elimination_zero_index(i1 %c, ptr %p, ptr %q) {308; CHECK-LABEL: @redundant_load_elimination_zero_index(309; CHECK-NEXT:  entry:310; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P:%.*]], i64 0, i64 1311; CHECK-NEXT:    store i32 0, ptr [[GEP1]], align 4312; CHECK-NEXT:    store i32 1, ptr [[P]], align 4313; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]314; CHECK:       if.then:315; CHECK-NEXT:    store i32 0, ptr [[Q:%.*]], align 4316; CHECK-NEXT:    ret void317; CHECK:       if.else:318; CHECK-NEXT:    ret void319;320entry:321  %gep1 = getelementptr <vscale x 4 x i32>, ptr %p, i64 0, i64 1322  store i32 0, ptr %gep1323  store i32 1, ptr %p324  br i1 %c, label %if.else, label %if.then325 326if.then:327  %t = load i32, ptr %gep1 ; <- load could be eliminated328  store i32 %t, ptr %q329  ret void330 331if.else:332  ret void333}334 335define void @redundant_load_elimination_zero_index_1(i1 %c, ptr %p, ptr %q, i64 %i) {336; CHECK-LABEL: @redundant_load_elimination_zero_index_1(337; CHECK-NEXT:  entry:338; CHECK-NEXT:    [[J:%.*]] = add i64 [[I:%.*]], 1339; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P:%.*]], i64 0, i64 [[J]]340; CHECK-NEXT:    store i32 0, ptr [[GEP1]], align 4341; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P]], i64 0, i64 [[I]]342; CHECK-NEXT:    store i32 1, ptr [[GEP2]], align 4343; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]344; CHECK:       if.then:345; CHECK-NEXT:    store i32 0, ptr [[Q:%.*]], align 4346; CHECK-NEXT:    ret void347; CHECK:       if.else:348; CHECK-NEXT:    ret void349;350entry:351  %j = add i64 %i, 1352  %gep1 = getelementptr <vscale x 4 x i32>, ptr %p, i64 0, i64 %j353  store i32 0, ptr %gep1354  %gep2 = getelementptr <vscale x 4 x i32>, ptr %p, i64 0, i64 %i355  store i32 1, ptr %gep2356  br i1 %c, label %if.else, label %if.then357 358if.then:359  %t = load i32, ptr %gep1 ; <- load could be eliminated360  store i32 %t, ptr %q361  ret void362 363if.else:364  ret void365}366; TODO: load in if.then could have been eliminated367define void @missing_load_elimination(i1 %c, ptr %p, ptr %q, <vscale x 4 x i32> %v) {368; CHECK-LABEL: @missing_load_elimination(369; CHECK-NEXT:  entry:370; CHECK-NEXT:    store <vscale x 4 x i32> zeroinitializer, ptr [[P:%.*]], align 16371; CHECK-NEXT:    [[P1:%.*]] = getelementptr <vscale x 4 x i32>, ptr [[P]], i64 1372; CHECK-NEXT:    store <vscale x 4 x i32> [[V:%.*]], ptr [[P1]], align 16373; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]374; CHECK:       if.then:375; CHECK-NEXT:    [[T:%.*]] = load <vscale x 4 x i32>, ptr [[P]], align 16376; CHECK-NEXT:    store <vscale x 4 x i32> [[T]], ptr [[Q:%.*]], align 16377; CHECK-NEXT:    ret void378; CHECK:       if.else:379; CHECK-NEXT:    ret void380;381entry:382  store <vscale x 4 x i32> zeroinitializer, ptr %p383  %p1 = getelementptr <vscale x 4 x i32>, ptr %p, i64 1384  store <vscale x 4 x i32> %v, ptr %p1385  br i1 %c, label %if.else, label %if.then386 387if.then:388  %t = load <vscale x 4 x i32>, ptr %p ; load could be eliminated389  store <vscale x 4 x i32> %t, ptr %q390  ret void391 392if.else:393  ret void394}395 396; Different sizes / types397 398define <vscale x 16 x i8> @load_v16i8_store_v4i32_forward_load(ptr %p, <vscale x 4 x i32> %x)  {399; CHECK-LABEL: @load_v16i8_store_v4i32_forward_load(400; CHECK-NEXT:    store <vscale x 4 x i32> [[X:%.*]], ptr [[P:%.*]], align 16401; CHECK-NEXT:    [[LOAD:%.*]] = load <vscale x 16 x i8>, ptr [[P]], align 16402; CHECK-NEXT:    ret <vscale x 16 x i8> [[LOAD]]403;404  store <vscale x 4 x i32> %x, ptr %p405  %load = load <vscale x 16 x i8>, ptr %p406  ret <vscale x 16 x i8> %load407}408 409define <vscale x 4 x float> @load_v4f32_store_v4i32_forward_load(ptr %p, <vscale x 4 x i32> %x)  {410; CHECK-LABEL: @load_v4f32_store_v4i32_forward_load(411; CHECK-NEXT:    store <vscale x 4 x i32> [[X:%.*]], ptr [[P:%.*]], align 16412; CHECK-NEXT:    [[LOAD:%.*]] = load <vscale x 4 x float>, ptr [[P]], align 16413; CHECK-NEXT:    ret <vscale x 4 x float> [[LOAD]]414;415  store <vscale x 4 x i32> %x, ptr %p416  %load = load <vscale x 4 x float>, ptr %p417  ret <vscale x 4 x float> %load418}419 420define <vscale x 4 x float> @load_v4f32_store_v16i8_forward_load(ptr %p, <vscale x 16 x i8> %x)  {421; CHECK-LABEL: @load_v4f32_store_v16i8_forward_load(422; CHECK-NEXT:    store <vscale x 16 x i8> [[X:%.*]], ptr [[P:%.*]], align 16423; CHECK-NEXT:    [[LOAD:%.*]] = load <vscale x 4 x float>, ptr [[P]], align 16424; CHECK-NEXT:    ret <vscale x 4 x float> [[LOAD]]425;426  store <vscale x 16 x i8> %x, ptr %p427  %load = load <vscale x 4 x float>, ptr %p428  ret <vscale x 4 x float> %load429}430 431define <vscale x 4 x i32> @load_v4i32_store_v4f32_forward_load(ptr %p, <vscale x 4 x float> %x)  {432; CHECK-LABEL: @load_v4i32_store_v4f32_forward_load(433; CHECK-NEXT:    store <vscale x 4 x float> [[X:%.*]], ptr [[P:%.*]], align 16434; CHECK-NEXT:    [[LOAD:%.*]] = load <vscale x 4 x i32>, ptr [[P]], align 16435; CHECK-NEXT:    ret <vscale x 4 x i32> [[LOAD]]436;437  store <vscale x 4 x float> %x, ptr %p438  %load = load <vscale x 4 x i32>, ptr %p439  ret <vscale x 4 x i32> %load440}441 442define <vscale x 4 x i32> @load_v4i32_store_v4i64_forward_load(ptr %p, <vscale x 4 x i64> %x)  {443; CHECK-LABEL: @load_v4i32_store_v4i64_forward_load(444; CHECK-NEXT:    store <vscale x 4 x i64> [[X:%.*]], ptr [[P:%.*]], align 32445; CHECK-NEXT:    [[LOAD:%.*]] = load <vscale x 4 x i32>, ptr [[P]], align 16446; CHECK-NEXT:    ret <vscale x 4 x i32> [[LOAD]]447;448  store <vscale x 4 x i64> %x, ptr %p449  %load = load <vscale x 4 x i32>, ptr %p450  ret <vscale x 4 x i32> %load451}452 453define <vscale x 4 x i64> @load_v4i64_store_v4i32_forward_load(ptr %p, <vscale x 4 x i32> %x)  {454; CHECK-LABEL: @load_v4i64_store_v4i32_forward_load(455; CHECK-NEXT:    store <vscale x 4 x i32> [[X:%.*]], ptr [[P:%.*]], align 16456; CHECK-NEXT:    [[LOAD:%.*]] = load <vscale x 4 x i64>, ptr [[P]], align 32457; CHECK-NEXT:    ret <vscale x 4 x i64> [[LOAD]]458;459  store <vscale x 4 x i32> %x, ptr %p460  %load = load <vscale x 4 x i64>, ptr %p461  ret <vscale x 4 x i64> %load462}463 464define <vscale x 2 x i32> @load_v2i32_store_v4i32_forward_load(ptr %p, <vscale x 4 x i32> %x)  {465; CHECK-LABEL: @load_v2i32_store_v4i32_forward_load(466; CHECK-NEXT:    store <vscale x 4 x i32> [[X:%.*]], ptr [[P:%.*]], align 16467; CHECK-NEXT:    [[LOAD:%.*]] = load <vscale x 2 x i32>, ptr [[P]], align 8468; CHECK-NEXT:    ret <vscale x 2 x i32> [[LOAD]]469;470  store <vscale x 4 x i32> %x, ptr %p471  %load = load <vscale x 2 x i32>, ptr %p472  ret <vscale x 2 x i32> %load473}474 475define <vscale x 2 x i32> @load_v2i32_store_v4i32_forward_load_offsets(ptr %p, <vscale x 4 x i32> %x)  {476; CHECK-LABEL: @load_v2i32_store_v4i32_forward_load_offsets(477; CHECK-NEXT:    store <vscale x 4 x i32> [[X:%.*]], ptr [[P:%.*]], align 16478; CHECK-NEXT:    [[Q:%.*]] = getelementptr <vscale x 2 x i32>, ptr [[P]], i64 1479; CHECK-NEXT:    [[LOAD:%.*]] = load <vscale x 2 x i32>, ptr [[Q]], align 8480; CHECK-NEXT:    ret <vscale x 2 x i32> [[LOAD]]481;482  store <vscale x 4 x i32> %x, ptr %p483  %q = getelementptr <vscale x 2 x i32>, ptr %p, i64 1484  %load = load <vscale x 2 x i32>, ptr %q485  ret <vscale x 2 x i32> %load486}487 488define <vscale x 2 x i32> @load_v2i32_store_v4i32_forward_load_offsetc(ptr %p, <vscale x 4 x i32> %x)  {489; CHECK-LABEL: @load_v2i32_store_v4i32_forward_load_offsetc(490; CHECK-NEXT:    store <vscale x 4 x i32> [[X:%.*]], ptr [[P:%.*]], align 16491; CHECK-NEXT:    [[Q:%.*]] = getelementptr <2 x i32>, ptr [[P]], i64 1492; CHECK-NEXT:    [[LOAD:%.*]] = load <vscale x 2 x i32>, ptr [[Q]], align 8493; CHECK-NEXT:    ret <vscale x 2 x i32> [[LOAD]]494;495  store <vscale x 4 x i32> %x, ptr %p496  %q = getelementptr <2 x i32>, ptr %p, i64 1497  %load = load <vscale x 2 x i32>, ptr %q498  ret <vscale x 2 x i32> %load499}500 501define <vscale x 2 x ptr> @load_v2p0_store_v4i32_forward_load(ptr %p, <vscale x 4 x i32> %x)  {502; CHECK-LABEL: @load_v2p0_store_v4i32_forward_load(503; CHECK-NEXT:    store <vscale x 4 x i32> [[X:%.*]], ptr [[P:%.*]], align 16504; CHECK-NEXT:    [[LOAD:%.*]] = load <vscale x 2 x ptr>, ptr [[P]], align 16505; CHECK-NEXT:    ret <vscale x 2 x ptr> [[LOAD]]506;507  store <vscale x 4 x i32> %x, ptr %p508  %load = load <vscale x 2 x ptr>, ptr %p509  ret <vscale x 2 x ptr> %load510}511 512define <vscale x 2 x i64> @load_v2i64_store_v2p0_forward_load(ptr %p, <vscale x 2 x ptr> %x)  {513; CHECK-LABEL: @load_v2i64_store_v2p0_forward_load(514; CHECK-NEXT:    store <vscale x 2 x ptr> [[X:%.*]], ptr [[P:%.*]], align 16515; CHECK-NEXT:    [[LOAD:%.*]] = load <vscale x 2 x i64>, ptr [[P]], align 16516; CHECK-NEXT:    ret <vscale x 2 x i64> [[LOAD]]517;518  store <vscale x 2 x ptr> %x, ptr %p519  %load = load <vscale x 2 x i64>, ptr %p520  ret <vscale x 2 x i64> %load521}522 523define <vscale x 16 x i8> @load_nxv16i8_store_v4i32_forward_load(ptr %p, <4 x i32> %x)  {524; CHECK-LABEL: @load_nxv16i8_store_v4i32_forward_load(525; CHECK-NEXT:    store <4 x i32> [[X:%.*]], ptr [[P:%.*]], align 16526; CHECK-NEXT:    [[LOAD:%.*]] = load <vscale x 16 x i8>, ptr [[P]], align 16527; CHECK-NEXT:    ret <vscale x 16 x i8> [[LOAD]]528;529  store <4 x i32> %x, ptr %p530  %load = load <vscale x 16 x i8>, ptr %p531  ret <vscale x 16 x i8> %load532}533 534define <16 x i8> @load_v16i8_store_nxv4i32_forward_load(ptr %p, <vscale x 4 x i32> %x)  {535; CHECK-LABEL: @load_v16i8_store_nxv4i32_forward_load(536; CHECK-NEXT:    store <vscale x 4 x i32> [[X:%.*]], ptr [[P:%.*]], align 16537; CHECK-NEXT:    [[LOAD:%.*]] = load <16 x i8>, ptr [[P]], align 16538; CHECK-NEXT:    ret <16 x i8> [[LOAD]]539;540  store <vscale x 4 x i32> %x, ptr %p541  %load = load <16 x i8>, ptr %p542  ret <16 x i8> %load543}544 545define <vscale x 16 x i8> @load_v16i8_store_v4i32_forward_constant(ptr %p)  {546; CHECK-LABEL: @load_v16i8_store_v4i32_forward_constant(547; CHECK-NEXT:    store <vscale x 4 x i32> splat (i32 4), ptr [[P:%.*]], align 16548; CHECK-NEXT:    [[LOAD:%.*]] = load <vscale x 16 x i8>, ptr [[P]], align 16549; CHECK-NEXT:    ret <vscale x 16 x i8> [[LOAD]]550;551  store <vscale x 4 x i32> splat (i32 4), ptr %p552  %load = load <vscale x 16 x i8>, ptr %p553  ret <vscale x 16 x i8> %load554}555 556define <vscale x 16 x i8> @load_v16i8_struct_store_v4i32_forward_load(ptr %p, { <vscale x 4 x i32> } %x)  {557; CHECK-LABEL: @load_v16i8_struct_store_v4i32_forward_load(558; CHECK-NEXT:    store { <vscale x 4 x i32> } [[X:%.*]], ptr [[P:%.*]], align 16559; CHECK-NEXT:    [[LOAD:%.*]] = load <vscale x 16 x i8>, ptr [[P]], align 16560; CHECK-NEXT:    ret <vscale x 16 x i8> [[LOAD]]561;562  store { <vscale x 4 x i32> } %x, ptr %p563  %load = load <vscale x 16 x i8>, ptr %p564  ret <vscale x 16 x i8> %load565}566 567define {<vscale x 16 x i8>} @load_v16i8_store_v4i32_struct_forward_load(ptr %p, <vscale x 4 x i32> %x)  {568; CHECK-LABEL: @load_v16i8_store_v4i32_struct_forward_load(569; CHECK-NEXT:    store <vscale x 4 x i32> [[X:%.*]], ptr [[P:%.*]], align 16570; CHECK-NEXT:    [[LOAD:%.*]] = load { <vscale x 16 x i8> }, ptr [[P]], align 16571; CHECK-NEXT:    ret { <vscale x 16 x i8> } [[LOAD]]572;573  store <vscale x 4 x i32> %x, ptr %p574  %load = load { <vscale x 16 x i8> }, ptr %p575  ret { <vscale x 16 x i8> } %load576}577 578define { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } @bigexample({ <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } %a) vscale_range(1,16) {579; CHECK-LABEL: @bigexample(580; CHECK-NEXT:  entry:581; CHECK-NEXT:    [[REF_TMP:%.*]] = alloca { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> }, align 16582; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr nonnull [[REF_TMP]])583; CHECK-NEXT:    [[A_ELT:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } [[A:%.*]], 0584; CHECK-NEXT:    store <vscale x 4 x i32> [[A_ELT]], ptr [[REF_TMP]], align 16585; CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.vscale.i64()586; CHECK-NEXT:    [[TMP1:%.*]] = shl i64 [[TMP0]], 4587; CHECK-NEXT:    [[REF_TMP_REPACK1:%.*]] = getelementptr inbounds i8, ptr [[REF_TMP]], i64 [[TMP1]]588; CHECK-NEXT:    [[A_ELT2:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } [[A]], 1589; CHECK-NEXT:    store <vscale x 4 x i32> [[A_ELT2]], ptr [[REF_TMP_REPACK1]], align 16590; CHECK-NEXT:    [[TMP3:%.*]] = shl i64 [[TMP0]], 5591; CHECK-NEXT:    [[REF_TMP_REPACK3:%.*]] = getelementptr inbounds i8, ptr [[REF_TMP]], i64 [[TMP3]]592; CHECK-NEXT:    [[A_ELT4:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } [[A]], 2593; CHECK-NEXT:    store <vscale x 4 x i32> [[A_ELT4]], ptr [[REF_TMP_REPACK3]], align 16594; CHECK-NEXT:    [[TMP5:%.*]] = mul i64 [[TMP0]], 48595; CHECK-NEXT:    [[REF_TMP_REPACK5:%.*]] = getelementptr inbounds i8, ptr [[REF_TMP]], i64 [[TMP5]]596; CHECK-NEXT:    [[A_ELT6:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } [[A]], 3597; CHECK-NEXT:    store <vscale x 4 x i32> [[A_ELT6]], ptr [[REF_TMP_REPACK5]], align 16598; CHECK-NEXT:    [[DOTUNPACK:%.*]] = load <vscale x 16 x i8>, ptr [[REF_TMP]], align 16599; CHECK-NEXT:    [[TMP6:%.*]] = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } poison, <vscale x 16 x i8> [[DOTUNPACK]], 0600; CHECK-NEXT:    [[DOTUNPACK8:%.*]] = load <vscale x 16 x i8>, ptr [[REF_TMP_REPACK1]], align 16601; CHECK-NEXT:    [[TMP9:%.*]] = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP6]], <vscale x 16 x i8> [[DOTUNPACK8]], 1602; CHECK-NEXT:    [[DOTUNPACK10:%.*]] = load <vscale x 16 x i8>, ptr [[REF_TMP_REPACK3]], align 16603; CHECK-NEXT:    [[TMP12:%.*]] = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP9]], <vscale x 16 x i8> [[DOTUNPACK10]], 2604; CHECK-NEXT:    [[DOTUNPACK12:%.*]] = load <vscale x 16 x i8>, ptr [[REF_TMP_REPACK5]], align 16605; CHECK-NEXT:    [[TMP15:%.*]] = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP12]], <vscale x 16 x i8> [[DOTUNPACK12]], 3606; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr nonnull [[REF_TMP]])607; CHECK-NEXT:    ret { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP15]]608;609entry:610  %ref.tmp = alloca { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> }, align 16611  call void @llvm.lifetime.start.p0(ptr nonnull %ref.tmp)612  %a.elt = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } %a, 0613  store <vscale x 4 x i32> %a.elt, ptr %ref.tmp, align 16614  %0 = call i64 @llvm.vscale.i64()615  %1 = shl i64 %0, 4616  %ref.tmp.repack1 = getelementptr inbounds i8, ptr %ref.tmp, i64 %1617  %a.elt2 = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } %a, 1618  store <vscale x 4 x i32> %a.elt2, ptr %ref.tmp.repack1, align 16619  %2 = call i64 @llvm.vscale.i64()620  %3 = shl i64 %2, 5621  %ref.tmp.repack3 = getelementptr inbounds i8, ptr %ref.tmp, i64 %3622  %a.elt4 = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } %a, 2623  store <vscale x 4 x i32> %a.elt4, ptr %ref.tmp.repack3, align 16624  %4 = call i64 @llvm.vscale.i64()625  %5 = mul i64 %4, 48626  %ref.tmp.repack5 = getelementptr inbounds i8, ptr %ref.tmp, i64 %5627  %a.elt6 = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } %a, 3628  store <vscale x 4 x i32> %a.elt6, ptr %ref.tmp.repack5, align 16629  %.unpack = load <vscale x 16 x i8>, ptr %ref.tmp, align 16630  %6 = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } poison, <vscale x 16 x i8> %.unpack, 0631  %7 = call i64 @llvm.vscale.i64()632  %8 = shl i64 %7, 4633  %.elt7 = getelementptr inbounds i8, ptr %ref.tmp, i64 %8634  %.unpack8 = load <vscale x 16 x i8>, ptr %.elt7, align 16635  %9 = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } %6, <vscale x 16 x i8> %.unpack8, 1636  %10 = call i64 @llvm.vscale.i64()637  %11 = shl i64 %10, 5638  %.elt9 = getelementptr inbounds i8, ptr %ref.tmp, i64 %11639  %.unpack10 = load <vscale x 16 x i8>, ptr %.elt9, align 16640  %12 = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } %9, <vscale x 16 x i8> %.unpack10, 2641  %13 = call i64 @llvm.vscale.i64()642  %14 = mul i64 %13, 48643  %.elt11 = getelementptr inbounds i8, ptr %ref.tmp, i64 %14644  %.unpack12 = load <vscale x 16 x i8>, ptr %.elt11, align 16645  %15 = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } %12, <vscale x 16 x i8> %.unpack12, 3646  call void @llvm.lifetime.end.p0(ptr nonnull %ref.tmp)647  ret { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } %15648}649 650define <vscale x 4 x float> @scalable_store_to_fixed_load(<vscale x 4 x float> %.coerce) vscale_range(4,4) {651; CHECK-LABEL: @scalable_store_to_fixed_load(652; CHECK-NEXT:  entry:653; CHECK-NEXT:    [[RETVAL:%.*]] = alloca { <16 x float> }, align 64654; CHECK-NEXT:    [[TMP0:%.*]] = fadd <vscale x 4 x float> [[DOTCOERCE:%.*]], [[DOTCOERCE]]655; CHECK-NEXT:    store <vscale x 4 x float> [[TMP0]], ptr [[RETVAL]], align 16656; CHECK-NEXT:    [[TMP1:%.*]] = load <16 x float>, ptr [[RETVAL]], align 64657; CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = tail call <vscale x 4 x float> @llvm.vector.insert.nxv4f32.v16f32(<vscale x 4 x float> poison, <16 x float> [[TMP1]], i64 0)658; CHECK-NEXT:    ret <vscale x 4 x float> [[CAST_SCALABLE]]659;660entry:661  %retval = alloca { <16 x float> }662  %0 = fadd <vscale x 4 x float> %.coerce, %.coerce663  store <vscale x 4 x float> %0, ptr %retval664  %1 = load <16 x float>, ptr %retval665  %cast.scalable = tail call <vscale x 4 x float> @llvm.vector.insert.nxv4f32.v16f32(<vscale x 4 x float> poison, <16 x float> %1, i64 0)666  ret <vscale x 4 x float> %cast.scalable667}668 669; Here, only the lower bound for the vscale is known, but this is enough to allow a forward to a load to 16 elements.670define <vscale x 4 x float> @scalable_store_to_fixed_load_only_lower_bound(<vscale x 4 x float> %a) vscale_range(4) {671; CHECK-LABEL: @scalable_store_to_fixed_load_only_lower_bound(672; CHECK-NEXT:  entry:673; CHECK-NEXT:    [[RETVAL:%.*]] = alloca { <vscale x 4 x float> }, align 16674; CHECK-NEXT:    store <vscale x 4 x float> [[A:%.*]], ptr [[RETVAL]], align 16675; CHECK-NEXT:    [[TMP0:%.*]] = load <16 x float>, ptr [[RETVAL]], align 64676; CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = tail call <vscale x 4 x float> @llvm.vector.insert.nxv4f32.v16f32(<vscale x 4 x float> poison, <16 x float> [[TMP0]], i64 0)677; CHECK-NEXT:    ret <vscale x 4 x float> [[CAST_SCALABLE]]678;679entry:680  %retval = alloca { <vscale x 4 x float> }681  store <vscale x 4 x float> %a, ptr %retval682  %1 = load <16 x float>, ptr %retval683  %cast.scalable = tail call <vscale x 4 x float> @llvm.vector.insert.nxv4f32.v16f32(<vscale x 4 x float> poison, <16 x float> %1, i64 0)684  ret <vscale x 4 x float> %cast.scalable685}686 687define <vscale x 4 x float> @scalable_store_to_fixed_load_with_offset(<vscale x 4 x float> %a) vscale_range(4,4) {688; CHECK-LABEL: @scalable_store_to_fixed_load_with_offset(689; CHECK-NEXT:  entry:690; CHECK-NEXT:    [[PTR:%.*]] = alloca { <32 x float> }, align 128691; CHECK-NEXT:    store <vscale x 4 x float> [[A:%.*]], ptr [[PTR]], align 16692; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 8693; CHECK-NEXT:    [[TMP0:%.*]] = load <16 x float>, ptr [[GEP]], align 64694; CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = tail call <vscale x 4 x float> @llvm.vector.insert.nxv4f32.v16f32(<vscale x 4 x float> poison, <16 x float> [[TMP0]], i64 0)695; CHECK-NEXT:    ret <vscale x 4 x float> [[CAST_SCALABLE]]696;697entry:698  %ptr = alloca { <32 x float> }699  store <vscale x 4 x float> %a, ptr %ptr700  %gep = getelementptr inbounds i8, ptr %ptr, i64 8701  %1 = load <16 x float>, ptr %gep702  %cast.scalable = tail call <vscale x 4 x float> @llvm.vector.insert.nxv4f32.v16f32(<vscale x 4 x float> poison, <16 x float> %1, i64 0)703  ret <vscale x 4 x float> %cast.scalable704}705 706define <vscale x 4 x float> @scalable_store_to_fixed_load_unknown_vscale(<vscale x 4 x float> %.coerce) {707; CHECK-LABEL: @scalable_store_to_fixed_load_unknown_vscale(708; CHECK-NEXT:  entry:709; CHECK-NEXT:    [[RETVAL:%.*]] = alloca { <16 x float> }, align 64710; CHECK-NEXT:    [[TMP0:%.*]] = fadd <vscale x 4 x float> [[DOTCOERCE:%.*]], [[DOTCOERCE]]711; CHECK-NEXT:    store <vscale x 4 x float> [[TMP0]], ptr [[RETVAL]], align 16712; CHECK-NEXT:    [[TMP1:%.*]] = load <16 x float>, ptr [[RETVAL]], align 64713; CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = tail call <vscale x 4 x float> @llvm.vector.insert.nxv4f32.v16f32(<vscale x 4 x float> poison, <16 x float> [[TMP1]], i64 0)714; CHECK-NEXT:    ret <vscale x 4 x float> [[CAST_SCALABLE]]715;716entry:717  %retval = alloca { <16 x float> }718  %0 = fadd <vscale x 4 x float> %.coerce, %.coerce719  store <vscale x 4 x float> %0, ptr %retval720  %1 = load <16 x float>, ptr %retval721  %cast.scalable = tail call <vscale x 4 x float> @llvm.vector.insert.nxv4f32.v16f32(<vscale x 4 x float> poison, <16 x float> %1, i64 0)722  ret <vscale x 4 x float> %cast.scalable723}724 725define <vscale x 4 x float> @scalable_store_to_fixed_load_size_missmatch(<vscale x 4 x float> %.coerce) vscale_range(4,4) {726; CHECK-LABEL: @scalable_store_to_fixed_load_size_missmatch(727; CHECK-NEXT:  entry:728; CHECK-NEXT:    [[RETVAL:%.*]] = alloca { <32 x float> }, align 128729; CHECK-NEXT:    [[TMP0:%.*]] = fadd <vscale x 4 x float> [[DOTCOERCE:%.*]], [[DOTCOERCE]]730; CHECK-NEXT:    store <vscale x 4 x float> [[TMP0]], ptr [[RETVAL]], align 16731; CHECK-NEXT:    [[TMP1:%.*]] = load <32 x float>, ptr [[RETVAL]], align 128732; CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = tail call <vscale x 4 x float> @llvm.vector.insert.nxv4f32.v32f32(<vscale x 4 x float> poison, <32 x float> [[TMP1]], i64 0)733; CHECK-NEXT:    ret <vscale x 4 x float> [[CAST_SCALABLE]]734;735entry:736  %retval = alloca { <32 x float> }737  %0 = fadd <vscale x 4 x float> %.coerce, %.coerce738  store <vscale x 4 x float> %0, ptr %retval739  %1 = load <32 x float>, ptr %retval740  %cast.scalable = tail call <vscale x 4 x float> @llvm.vector.insert.nxv4f32.v32f32(<vscale x 4 x float> poison, <32 x float> %1, i64 0)741  ret <vscale x 4 x float> %cast.scalable742}743 744define <vscale x 4 x i32> @scalable_store_to_fixed_load_different_types(<vscale x 4 x float> %a) vscale_range(4,4) {745; CHECK-LABEL: @scalable_store_to_fixed_load_different_types(746; CHECK-NEXT:  entry:747; CHECK-NEXT:    [[PTR:%.*]] = alloca { <16 x float> }, align 64748; CHECK-NEXT:    store <vscale x 4 x float> [[A:%.*]], ptr [[PTR]], align 16749; CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i32>, ptr [[PTR]], align 64750; CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v16i32(<vscale x 4 x i32> poison, <16 x i32> [[TMP0]], i64 0)751; CHECK-NEXT:    ret <vscale x 4 x i32> [[CAST_SCALABLE]]752;753entry:754  %ptr = alloca { <16 x float> }755  store <vscale x 4 x float> %a, ptr %ptr756  %1 = load <16 x i32>, ptr %ptr757  %cast.scalable = tail call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v16i32(<vscale x 4 x i32> poison, <16 x i32> %1, i64 0)758  ret <vscale x 4 x i32> %cast.scalable759}760 761; This function does not have a fixed vscale, but the loaded vector is still known762; to be smaller or equal in size compared to the stored vector.763define <4 x float> @scalable_store_to_small_fixed_load(<vscale x 4 x float> %a) {764; CHECK-LABEL: @scalable_store_to_small_fixed_load(765; CHECK-NEXT:  entry:766; CHECK-NEXT:    [[PTR:%.*]] = alloca <vscale x 4 x float>, align 16767; CHECK-NEXT:    store <vscale x 4 x float> [[A:%.*]], ptr [[PTR]], align 16768; CHECK-NEXT:    [[TMP0:%.*]] = load <4 x float>, ptr [[PTR]], align 16769; CHECK-NEXT:    ret <4 x float> [[TMP0]]770;771entry:772  %ptr = alloca <vscale x 4 x float>773  store <vscale x 4 x float> %a, ptr %ptr774  %1 = load <4 x float>, ptr %ptr775  ret <4 x float> %1776}777