500 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=instcombine -S < %s | FileCheck %s3; RUN: opt -passes=instcombine -use-constant-int-for-fixed-length-splat -S < %s | FileCheck %s4 5declare <2 x double> @llvm.masked.load.v2f64.p0(ptr %ptrs, i32, <2 x i1> %mask, <2 x double> %src0)6declare void @llvm.masked.store.v2f64.p0(<2 x double> %val, ptr %ptrs, i32, <2 x i1> %mask)7declare <2 x double> @llvm.masked.gather.v2f64.v2p0(<2 x ptr> %ptrs, i32, <2 x i1> %mask, <2 x double> %passthru)8declare <4 x double> @llvm.masked.gather.v4f64.v4p0(<4 x ptr> %ptrs, i32, <4 x i1> %mask, <4 x double> %passthru)9declare void @llvm.masked.scatter.v2f64.v2p0(<2 x double> %val, <2 x ptr> %ptrs, i32, <2 x i1> %mask)10 11define <2 x double> @load_zeromask(ptr %ptr, <2 x double> %passthru) {12; CHECK-LABEL: @load_zeromask(13; CHECK-NEXT: ret <2 x double> [[PASSTHRU:%.*]]14;15 %res = call <2 x double> @llvm.masked.load.v2f64.p0(ptr %ptr, i32 1, <2 x i1> zeroinitializer, <2 x double> %passthru)16 ret <2 x double> %res17}18 19define <2 x double> @load_zero_withpoison_mask(ptr %ptr, <2 x double> %passthru) {20; CHECK-LABEL: @load_zero_withpoison_mask(21; CHECK-NEXT: ret <2 x double> [[PASSTHRU:%.*]]22;23 %res = call <2 x double> @llvm.masked.load.v2f64.p0(ptr %ptr, i32 1, <2 x i1> <i1 0, i1 poison>, <2 x double> %passthru)24 ret <2 x double> %res25}26 27define <2 x double> @load_onemask(ptr %ptr, <2 x double> %passthru) {28; CHECK-LABEL: @load_onemask(29; CHECK-NEXT: [[UNMASKEDLOAD:%.*]] = load <2 x double>, ptr [[PTR:%.*]], align 230; CHECK-NEXT: ret <2 x double> [[UNMASKEDLOAD]]31;32 %res = call <2 x double> @llvm.masked.load.v2f64.p0(ptr %ptr, i32 2, <2 x i1> <i1 1, i1 1>, <2 x double> %passthru)33 ret <2 x double> %res34}35 36define <2 x double> @load_undefmask(ptr %ptr, <2 x double> %passthru) {37; CHECK-LABEL: @load_undefmask(38; CHECK-NEXT: [[UNMASKEDLOAD:%.*]] = load <2 x double>, ptr [[PTR:%.*]], align 239; CHECK-NEXT: ret <2 x double> [[UNMASKEDLOAD]]40;41 %res = call <2 x double> @llvm.masked.load.v2f64.p0(ptr %ptr, i32 2, <2 x i1> <i1 1, i1 undef>, <2 x double> %passthru)42 ret <2 x double> %res43}44 45@G = external global i846 47define <2 x double> @load_cemask(ptr %ptr, <2 x double> %passthru) {48; CHECK-LABEL: @load_cemask(49; CHECK-NEXT: [[RES:%.*]] = call <2 x double> @llvm.masked.load.v2f64.p0(ptr align 2 [[PTR:%.*]], <2 x i1> <i1 true, i1 ptrtoint (ptr @G to i1)>, <2 x double> [[PASSTHRU:%.*]])50; CHECK-NEXT: ret <2 x double> [[RES]]51;52 %res = call <2 x double> @llvm.masked.load.v2f64.p0(ptr %ptr, i32 2, <2 x i1> <i1 1, i1 ptrtoint (ptr @G to i1)>, <2 x double> %passthru)53 ret <2 x double> %res54}55 56define <2 x double> @load_lane0(ptr %ptr, double %pt) {57; CHECK-LABEL: @load_lane0(58; CHECK-NEXT: [[PTV2:%.*]] = insertelement <2 x double> poison, double [[PT:%.*]], i64 159; CHECK-NEXT: [[RES:%.*]] = call <2 x double> @llvm.masked.load.v2f64.p0(ptr align 2 [[PTR:%.*]], <2 x i1> <i1 true, i1 false>, <2 x double> [[PTV2]])60; CHECK-NEXT: ret <2 x double> [[RES]]61;62 %ptv1 = insertelement <2 x double> undef, double %pt, i64 063 %ptv2 = insertelement <2 x double> %ptv1, double %pt, i64 164 %res = call <2 x double> @llvm.masked.load.v2f64.p0(ptr %ptr, i32 2, <2 x i1> <i1 true, i1 false>, <2 x double> %ptv2)65 ret <2 x double> %res66}67 68define double @load_all(ptr %base, double %pt) {69; CHECK-LABEL: @load_all(70; CHECK-NEXT: [[PTRS:%.*]] = getelementptr double, ptr [[BASE:%.*]], <4 x i64> <i64 0, i64 poison, i64 2, i64 3>71; CHECK-NEXT: [[RES:%.*]] = call <4 x double> @llvm.masked.gather.v4f64.v4p0(<4 x ptr> align 4 [[PTRS]], <4 x i1> <i1 true, i1 false, i1 true, i1 true>, <4 x double> poison)72; CHECK-NEXT: [[ELT:%.*]] = extractelement <4 x double> [[RES]], i64 273; CHECK-NEXT: ret double [[ELT]]74;75 %ptrs = getelementptr double, ptr %base, <4 x i64> <i64 0, i64 1, i64 2, i64 3>76 %res = call <4 x double> @llvm.masked.gather.v4f64.v4p0(<4 x ptr> %ptrs, i32 4, <4 x i1> <i1 true, i1 false, i1 true, i1 true>, <4 x double> undef)77 %elt = extractelement <4 x double> %res, i64 278 ret double %elt79}80 81define <2 x double> @load_generic(ptr %ptr, double %pt, <2 x i1> %mask) {82; CHECK-LABEL: @load_generic(83; CHECK-NEXT: [[PTV1:%.*]] = insertelement <2 x double> poison, double [[PT:%.*]], i64 084; CHECK-NEXT: [[PTV2:%.*]] = shufflevector <2 x double> [[PTV1]], <2 x double> poison, <2 x i32> zeroinitializer85; CHECK-NEXT: [[RES:%.*]] = call <2 x double> @llvm.masked.load.v2f64.p0(ptr align 4 [[PTR:%.*]], <2 x i1> [[MASK:%.*]], <2 x double> [[PTV2]])86; CHECK-NEXT: ret <2 x double> [[RES]]87;88 %ptv1 = insertelement <2 x double> undef, double %pt, i64 089 %ptv2 = insertelement <2 x double> %ptv1, double %pt, i64 190 %res = call <2 x double> @llvm.masked.load.v2f64.p0(ptr %ptr, i32 4, <2 x i1> %mask, <2 x double> %ptv2)91 ret <2 x double> %res92}93 94define <2 x double> @load_speculative(ptr dereferenceable(16) align 4 %ptr, double %pt, <2 x i1> %mask) nofree nosync {95; CHECK-LABEL: @load_speculative(96; CHECK-NEXT: [[PTV1:%.*]] = insertelement <2 x double> poison, double [[PT:%.*]], i64 097; CHECK-NEXT: [[PTV2:%.*]] = shufflevector <2 x double> [[PTV1]], <2 x double> poison, <2 x i32> zeroinitializer98; CHECK-NEXT: [[UNMASKEDLOAD:%.*]] = load <2 x double>, ptr [[PTR:%.*]], align 499; CHECK-NEXT: [[RES:%.*]] = select <2 x i1> [[MASK:%.*]], <2 x double> [[UNMASKEDLOAD]], <2 x double> [[PTV2]]100; CHECK-NEXT: ret <2 x double> [[RES]]101;102 %ptv1 = insertelement <2 x double> undef, double %pt, i64 0103 %ptv2 = insertelement <2 x double> %ptv1, double %pt, i64 1104 %res = call <2 x double> @llvm.masked.load.v2f64.p0(ptr %ptr, i32 4, <2 x i1> %mask, <2 x double> %ptv2)105 ret <2 x double> %res106}107 108define <2 x double> @load_speculative_less_aligned(ptr dereferenceable(16) %ptr, double %pt, <2 x i1> %mask) nofree nosync {109; CHECK-LABEL: @load_speculative_less_aligned(110; CHECK-NEXT: [[PTV1:%.*]] = insertelement <2 x double> poison, double [[PT:%.*]], i64 0111; CHECK-NEXT: [[PTV2:%.*]] = shufflevector <2 x double> [[PTV1]], <2 x double> poison, <2 x i32> zeroinitializer112; CHECK-NEXT: [[UNMASKEDLOAD:%.*]] = load <2 x double>, ptr [[PTR:%.*]], align 4113; CHECK-NEXT: [[RES:%.*]] = select <2 x i1> [[MASK:%.*]], <2 x double> [[UNMASKEDLOAD]], <2 x double> [[PTV2]]114; CHECK-NEXT: ret <2 x double> [[RES]]115;116 %ptv1 = insertelement <2 x double> undef, double %pt, i64 0117 %ptv2 = insertelement <2 x double> %ptv1, double %pt, i64 1118 %res = call <2 x double> @llvm.masked.load.v2f64.p0(ptr %ptr, i32 4, <2 x i1> %mask, <2 x double> %ptv2)119 ret <2 x double> %res120}121 122; Can't speculate since only half of required size is known deref123 124define <2 x double> @load_spec_neg_size(ptr dereferenceable(8) %ptr, double %pt, <2 x i1> %mask) nofree nosync {125; CHECK-LABEL: @load_spec_neg_size(126; CHECK-NEXT: [[PTV1:%.*]] = insertelement <2 x double> poison, double [[PT:%.*]], i64 0127; CHECK-NEXT: [[PTV2:%.*]] = shufflevector <2 x double> [[PTV1]], <2 x double> poison, <2 x i32> zeroinitializer128; CHECK-NEXT: [[RES:%.*]] = call <2 x double> @llvm.masked.load.v2f64.p0(ptr nonnull align 4 [[PTR:%.*]], <2 x i1> [[MASK:%.*]], <2 x double> [[PTV2]])129; CHECK-NEXT: ret <2 x double> [[RES]]130;131 %ptv1 = insertelement <2 x double> undef, double %pt, i64 0132 %ptv2 = insertelement <2 x double> %ptv1, double %pt, i64 1133 %res = call <2 x double> @llvm.masked.load.v2f64.p0(ptr %ptr, i32 4, <2 x i1> %mask, <2 x double> %ptv2)134 ret <2 x double> %res135}136 137; Can only speculate one lane (but it's the only one active)138define <2 x double> @load_spec_lan0(ptr dereferenceable(8) %ptr, double %pt, <2 x i1> %mask) nofree nosync {139; CHECK-LABEL: @load_spec_lan0(140; CHECK-NEXT: [[PTV1:%.*]] = insertelement <2 x double> poison, double [[PT:%.*]], i64 0141; CHECK-NEXT: [[PTV2:%.*]] = shufflevector <2 x double> [[PTV1]], <2 x double> poison, <2 x i32> zeroinitializer142; CHECK-NEXT: [[MASK2:%.*]] = insertelement <2 x i1> [[MASK:%.*]], i1 false, i64 1143; CHECK-NEXT: [[RES:%.*]] = call <2 x double> @llvm.masked.load.v2f64.p0(ptr nonnull align 4 [[PTR:%.*]], <2 x i1> [[MASK2]], <2 x double> [[PTV2]])144; CHECK-NEXT: ret <2 x double> [[RES]]145;146 %ptv1 = insertelement <2 x double> undef, double %pt, i64 0147 %ptv2 = insertelement <2 x double> %ptv1, double %pt, i64 1148 %mask2 = insertelement <2 x i1> %mask, i1 false, i64 1149 %res = call <2 x double> @llvm.masked.load.v2f64.p0(ptr %ptr, i32 4, <2 x i1> %mask2, <2 x double> %ptv2)150 ret <2 x double> %res151}152 153define void @store_zeromask(ptr %ptr, <2 x double> %val) {154; CHECK-LABEL: @store_zeromask(155; CHECK-NEXT: ret void156;157 call void @llvm.masked.store.v2f64.p0(<2 x double> %val, ptr %ptr, i32 4, <2 x i1> zeroinitializer)158 ret void159}160 161define void @store_poisonmask(ptr %ptr, <2 x double> %val) {162; CHECK-LABEL: @store_poisonmask(163; CHECK-NEXT: ret void164;165 call void @llvm.masked.store.v2f64.p0(<2 x double> %val, ptr %ptr, i32 4, <2 x i1> splat(i1 poison))166 ret void167}168 169define void @store_onemask(ptr %ptr, <2 x double> %val) {170; CHECK-LABEL: @store_onemask(171; CHECK-NEXT: store <2 x double> [[VAL:%.*]], ptr [[PTR:%.*]], align 4172; CHECK-NEXT: ret void173;174 call void @llvm.masked.store.v2f64.p0(<2 x double> %val, ptr %ptr, i32 4, <2 x i1> <i1 1, i1 1>)175 ret void176}177 178define void @store_one_withpoison_mask(ptr %ptr, <2 x double> %val) {179; CHECK-LABEL: @store_one_withpoison_mask(180; CHECK-NEXT: store <2 x double> [[VAL:%.*]], ptr [[PTR:%.*]], align 4181; CHECK-NEXT: ret void182;183 call void @llvm.masked.store.v2f64.p0(<2 x double> %val, ptr %ptr, i32 4, <2 x i1> <i1 1, i1 poison>)184 ret void185}186 187define void @store_demandedelts(ptr %ptr, double %val) {188; CHECK-LABEL: @store_demandedelts(189; CHECK-NEXT: [[VALVEC1:%.*]] = insertelement <2 x double> poison, double [[VAL:%.*]], i64 0190; CHECK-NEXT: call void @llvm.masked.store.v2f64.p0(<2 x double> [[VALVEC1]], ptr align 4 [[PTR:%.*]], <2 x i1> <i1 true, i1 false>)191; CHECK-NEXT: ret void192;193 %valvec1 = insertelement <2 x double> undef, double %val, i32 0194 %valvec2 = insertelement <2 x double> %valvec1, double %val, i32 1195 call void @llvm.masked.store.v2f64.p0(<2 x double> %valvec2, ptr %ptr, i32 4, <2 x i1> <i1 true, i1 false>)196 ret void197}198 199define <2 x double> @gather_generic(<2 x ptr> %ptrs, <2 x i1> %mask, <2 x double> %passthru) {200; CHECK-LABEL: @gather_generic(201; CHECK-NEXT: [[RES:%.*]] = call <2 x double> @llvm.masked.gather.v2f64.v2p0(<2 x ptr> align 4 [[PTRS:%.*]], <2 x i1> [[MASK:%.*]], <2 x double> [[PASSTHRU:%.*]])202; CHECK-NEXT: ret <2 x double> [[RES]]203;204 %res = call <2 x double> @llvm.masked.gather.v2f64.v2p0(<2 x ptr> %ptrs, i32 4, <2 x i1> %mask, <2 x double> %passthru)205 ret <2 x double> %res206}207 208 209define <2 x double> @gather_zeromask(<2 x ptr> %ptrs, <2 x double> %passthru) {210; CHECK-LABEL: @gather_zeromask(211; CHECK-NEXT: ret <2 x double> [[PASSTHRU:%.*]]212;213 %res = call <2 x double> @llvm.masked.gather.v2f64.v2p0(<2 x ptr> %ptrs, i32 4, <2 x i1> zeroinitializer, <2 x double> %passthru)214 ret <2 x double> %res215}216 217define <2 x double> @gather_zero_withpoison_mask(<2 x ptr> %ptrs, <2 x double> %passthru) {218; CHECK-LABEL: @gather_zero_withpoison_mask(219; CHECK-NEXT: ret <2 x double> [[PASSTHRU:%.*]]220;221 %res = call <2 x double> @llvm.masked.gather.v2f64.v2p0(<2 x ptr> %ptrs, i32 4, <2 x i1> <i1 0, i1 poison>, <2 x double> %passthru)222 ret <2 x double> %res223}224 225define <2 x double> @gather_onemask(<2 x ptr> %ptrs, <2 x double> %passthru) {226; CHECK-LABEL: @gather_onemask(227; CHECK-NEXT: [[RES:%.*]] = call <2 x double> @llvm.masked.gather.v2f64.v2p0(<2 x ptr> align 4 [[PTRS:%.*]], <2 x i1> splat (i1 true), <2 x double> poison)228; CHECK-NEXT: ret <2 x double> [[RES]]229;230 %res = call <2 x double> @llvm.masked.gather.v2f64.v2p0(<2 x ptr> %ptrs, i32 4, <2 x i1> <i1 true, i1 true>, <2 x double> %passthru)231 ret <2 x double> %res232}233 234define <2 x double> @gather_one_withpoisonmask(<2 x ptr> %ptrs, <2 x double> %passthru) {235; CHECK-LABEL: @gather_one_withpoisonmask(236; CHECK-NEXT: [[RES:%.*]] = call <2 x double> @llvm.masked.gather.v2f64.v2p0(<2 x ptr> align 4 [[PTRS:%.*]], <2 x i1> <i1 true, i1 poison>, <2 x double> [[PASSTHRU:%.*]])237; CHECK-NEXT: ret <2 x double> [[RES]]238;239 %res = call <2 x double> @llvm.masked.gather.v2f64.v2p0(<2 x ptr> %ptrs, i32 4, <2 x i1> <i1 true, i1 poison>, <2 x double> %passthru)240 ret <2 x double> %res241}242 243define <4 x double> @gather_lane2(ptr %base, double %pt) {244; CHECK-LABEL: @gather_lane2(245; CHECK-NEXT: [[PTRS:%.*]] = getelementptr double, ptr [[BASE:%.*]], <4 x i64> <i64 poison, i64 poison, i64 2, i64 poison>246; CHECK-NEXT: [[PT_V1:%.*]] = insertelement <4 x double> poison, double [[PT:%.*]], i64 0247; CHECK-NEXT: [[PT_V2:%.*]] = shufflevector <4 x double> [[PT_V1]], <4 x double> poison, <4 x i32> <i32 0, i32 0, i32 poison, i32 0>248; CHECK-NEXT: [[RES:%.*]] = call <4 x double> @llvm.masked.gather.v4f64.v4p0(<4 x ptr> align 4 [[PTRS]], <4 x i1> <i1 false, i1 false, i1 true, i1 false>, <4 x double> [[PT_V2]])249; CHECK-NEXT: ret <4 x double> [[RES]]250;251 %ptrs = getelementptr double, ptr %base, <4 x i64> <i64 0, i64 1, i64 2, i64 3>252 %pt_v1 = insertelement <4 x double> undef, double %pt, i64 0253 %pt_v2 = shufflevector <4 x double> %pt_v1, <4 x double> undef, <4 x i32> zeroinitializer254 %res = call <4 x double> @llvm.masked.gather.v4f64.v4p0(<4 x ptr> %ptrs, i32 4, <4 x i1> <i1 false, i1 false, i1 true, i1 false>, <4 x double> %pt_v2)255 ret <4 x double> %res256}257 258define <2 x double> @gather_lane0_maybe(ptr %base, double %pt, <2 x i1> %mask) {259; CHECK-LABEL: @gather_lane0_maybe(260; CHECK-NEXT: [[PTRS:%.*]] = getelementptr double, ptr [[BASE:%.*]], <2 x i64> <i64 0, i64 1>261; CHECK-NEXT: [[PT_V1:%.*]] = insertelement <2 x double> poison, double [[PT:%.*]], i64 0262; CHECK-NEXT: [[PT_V2:%.*]] = shufflevector <2 x double> [[PT_V1]], <2 x double> poison, <2 x i32> zeroinitializer263; CHECK-NEXT: [[MASK2:%.*]] = insertelement <2 x i1> [[MASK:%.*]], i1 false, i64 1264; CHECK-NEXT: [[RES:%.*]] = call <2 x double> @llvm.masked.gather.v2f64.v2p0(<2 x ptr> align 4 [[PTRS]], <2 x i1> [[MASK2]], <2 x double> [[PT_V2]])265; CHECK-NEXT: ret <2 x double> [[RES]]266;267 %ptrs = getelementptr double, ptr %base, <2 x i64> <i64 0, i64 1>268 %pt_v1 = insertelement <2 x double> undef, double %pt, i64 0269 %pt_v2 = insertelement <2 x double> %pt_v1, double %pt, i64 1270 %mask2 = insertelement <2 x i1> %mask, i1 false, i64 1271 %res = call <2 x double> @llvm.masked.gather.v2f64.v2p0(<2 x ptr> %ptrs, i32 4, <2 x i1> %mask2, <2 x double> %pt_v2)272 ret <2 x double> %res273}274 275define <2 x double> @gather_lane0_maybe_spec(ptr %base, double %pt, <2 x i1> %mask) {276; CHECK-LABEL: @gather_lane0_maybe_spec(277; CHECK-NEXT: [[PTRS:%.*]] = getelementptr double, ptr [[BASE:%.*]], <2 x i64> <i64 0, i64 1>278; CHECK-NEXT: [[PT_V1:%.*]] = insertelement <2 x double> poison, double [[PT:%.*]], i64 0279; CHECK-NEXT: [[PT_V2:%.*]] = shufflevector <2 x double> [[PT_V1]], <2 x double> poison, <2 x i32> zeroinitializer280; CHECK-NEXT: [[MASK2:%.*]] = insertelement <2 x i1> [[MASK:%.*]], i1 false, i64 1281; CHECK-NEXT: [[RES:%.*]] = call <2 x double> @llvm.masked.gather.v2f64.v2p0(<2 x ptr> align 4 [[PTRS]], <2 x i1> [[MASK2]], <2 x double> [[PT_V2]])282; CHECK-NEXT: ret <2 x double> [[RES]]283;284 %ptrs = getelementptr double, ptr %base, <2 x i64> <i64 0, i64 1>285 %pt_v1 = insertelement <2 x double> undef, double %pt, i64 0286 %pt_v2 = insertelement <2 x double> %pt_v1, double %pt, i64 1287 %mask2 = insertelement <2 x i1> %mask, i1 false, i64 1288 %res = call <2 x double> @llvm.masked.gather.v2f64.v2p0(<2 x ptr> %ptrs, i32 4, <2 x i1> %mask2, <2 x double> %pt_v2)289 ret <2 x double> %res290}291 292 293define void @scatter_zeromask(<2 x ptr> %ptrs, <2 x double> %val) {294; CHECK-LABEL: @scatter_zeromask(295; CHECK-NEXT: ret void296;297 call void @llvm.masked.scatter.v2f64.v2p0(<2 x double> %val, <2 x ptr> %ptrs, i32 8, <2 x i1> zeroinitializer)298 ret void299}300 301define void @scatter_zero_withpoison_mask(<2 x ptr> %ptrs, <2 x double> %val) {302; CHECK-LABEL: @scatter_zero_withpoison_mask(303; CHECK-NEXT: ret void304;305 call void @llvm.masked.scatter.v2f64.v2p0(<2 x double> %val, <2 x ptr> %ptrs, i32 8, <2 x i1> <i1 0, i1 poison>)306 ret void307}308 309define void @scatter_one_withpoison_mask(<2 x ptr> %ptrs, <2 x double> %val) {310; CHECK-LABEL: @scatter_one_withpoison_mask(311; CHECK-NEXT: call void @llvm.masked.scatter.v2f64.v2p0(<2 x double> [[VAL:%.*]], <2 x ptr> align 8 [[PTRS:%.*]], <2 x i1> <i1 true, i1 poison>)312; CHECK-NEXT: ret void313;314 call void @llvm.masked.scatter.v2f64.v2p0(<2 x double> %val, <2 x ptr> %ptrs, i32 8, <2 x i1> <i1 1, i1 poison>)315 ret void316}317 318define void @scatter_demandedelts(ptr %ptr, double %val) {319; CHECK-LABEL: @scatter_demandedelts(320; CHECK-NEXT: [[PTRS:%.*]] = getelementptr double, ptr [[PTR:%.*]], <2 x i64> <i64 0, i64 poison>321; CHECK-NEXT: [[VALVEC1:%.*]] = insertelement <2 x double> poison, double [[VAL:%.*]], i64 0322; CHECK-NEXT: call void @llvm.masked.scatter.v2f64.v2p0(<2 x double> [[VALVEC1]], <2 x ptr> align 8 [[PTRS]], <2 x i1> <i1 true, i1 false>)323; CHECK-NEXT: ret void324;325 %ptrs = getelementptr double, ptr %ptr, <2 x i64> <i64 0, i64 1>326 %valvec1 = insertelement <2 x double> undef, double %val, i32 0327 %valvec2 = insertelement <2 x double> %valvec1, double %val, i32 1328 call void @llvm.masked.scatter.v2f64.v2p0(<2 x double> %valvec2, <2 x ptr> %ptrs, i32 8, <2 x i1> <i1 true, i1 false>)329 ret void330}331 332 333; Test scatters that can be simplified to scalar stores.334 335;; Value splat (mask is not used)336define void @scatter_v4i16_uniform_vals_uniform_ptrs_no_all_active_mask(ptr %dst, i16 %val) {337; CHECK-LABEL: @scatter_v4i16_uniform_vals_uniform_ptrs_no_all_active_mask(338; CHECK-NEXT: entry:339; CHECK-NEXT: store i16 [[VAL:%.*]], ptr [[DST:%.*]], align 2340; CHECK-NEXT: ret void341;342entry:343 %broadcast.splatinsert = insertelement <4 x ptr> poison, ptr %dst, i32 0344 %broadcast.splat = shufflevector <4 x ptr> %broadcast.splatinsert, <4 x ptr> poison, <4 x i32> zeroinitializer345 %broadcast.value = insertelement <4 x i16> poison, i16 %val, i32 0346 %broadcast.splatvalue = shufflevector <4 x i16> %broadcast.value, <4 x i16> poison, <4 x i32> zeroinitializer347 call void @llvm.masked.scatter.v4i16.v4p0(<4 x i16> %broadcast.splatvalue, <4 x ptr> %broadcast.splat, i32 2, <4 x i1> <i1 0, i1 0, i1 1, i1 1>)348 ret void349}350 351define void @scatter_nxv4i16_uniform_vals_uniform_ptrs_all_active_mask(ptr %dst, i16 %val) {352; CHECK-LABEL: @scatter_nxv4i16_uniform_vals_uniform_ptrs_all_active_mask(353; CHECK-NEXT: entry:354; CHECK-NEXT: store i16 [[VAL:%.*]], ptr [[DST:%.*]], align 2355; CHECK-NEXT: ret void356;357entry:358 %broadcast.splatinsert = insertelement <vscale x 4 x ptr> poison, ptr %dst, i32 0359 %broadcast.splat = shufflevector <vscale x 4 x ptr> %broadcast.splatinsert, <vscale x 4 x ptr> poison, <vscale x 4 x i32> zeroinitializer360 %broadcast.value = insertelement <vscale x 4 x i16> poison, i16 %val, i32 0361 %broadcast.splatvalue = shufflevector <vscale x 4 x i16> %broadcast.value, <vscale x 4 x i16> poison, <vscale x 4 x i32> zeroinitializer362 call void @llvm.masked.scatter.nxv4i16.nxv4p0(<vscale x 4 x i16> %broadcast.splatvalue, <vscale x 4 x ptr> %broadcast.splat, i32 2, <vscale x 4 x i1> splat (i1 true))363 ret void364}365 366;; The pointer is splat and mask is all active, but value is not a splat367define void @scatter_v4i16_no_uniform_vals_uniform_ptrs_all_active_mask(ptr %dst, ptr %src) {368; CHECK-LABEL: @scatter_v4i16_no_uniform_vals_uniform_ptrs_all_active_mask(369; CHECK-NEXT: entry:370; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i16>, ptr [[SRC:%.*]], align 2371; CHECK-NEXT: [[TMP0:%.*]] = extractelement <4 x i16> [[WIDE_LOAD]], i64 3372; CHECK-NEXT: store i16 [[TMP0]], ptr [[DST:%.*]], align 2373; CHECK-NEXT: ret void374;375entry:376 %broadcast.splatinsert = insertelement <4 x ptr> poison, ptr %dst, i32 0377 %broadcast.splat = shufflevector <4 x ptr> %broadcast.splatinsert, <4 x ptr> poison, <4 x i32> zeroinitializer378 %wide.load = load <4 x i16>, ptr %src, align 2379 call void @llvm.masked.scatter.v4i16.v4p0(<4 x i16> %wide.load, <4 x ptr> %broadcast.splat, i32 2, <4 x i1> <i1 1, i1 1, i1 1, i1 1>)380 ret void381}382 383define void @scatter_nxv4i16_no_uniform_vals_uniform_ptrs_all_active_mask(ptr %dst, ptr %src) {384; CHECK-LABEL: @scatter_nxv4i16_no_uniform_vals_uniform_ptrs_all_active_mask(385; CHECK-NEXT: entry:386; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <vscale x 4 x i16>, ptr [[SRC:%.*]], align 2387; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.vscale.i32()388; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i32 [[TMP0]], 2389; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], -1390; CHECK-NEXT: [[TMP3:%.*]] = extractelement <vscale x 4 x i16> [[WIDE_LOAD]], i32 [[TMP2]]391; CHECK-NEXT: store i16 [[TMP3]], ptr [[DST:%.*]], align 2392; CHECK-NEXT: ret void393;394entry:395 %broadcast.splatinsert = insertelement <vscale x 4 x ptr> poison, ptr %dst, i32 0396 %broadcast.splat = shufflevector <vscale x 4 x ptr> %broadcast.splatinsert, <vscale x 4 x ptr> poison, <vscale x 4 x i32> zeroinitializer397 %wide.load = load <vscale x 4 x i16>, ptr %src, align 2398 call void @llvm.masked.scatter.nxv4i16.nxv4p0(<vscale x 4 x i16> %wide.load, <vscale x 4 x ptr> %broadcast.splat, i32 2, <vscale x 4 x i1> splat (i1 true))399 ret void400}401 402; Negative scatter tests403 404;; Pointer is splat, but mask is not all active and value is not a splat405define void @negative_scatter_v4i16_no_uniform_vals_uniform_ptrs_all_inactive_mask(ptr %dst, ptr %src) {406; CHECK-LABEL: @negative_scatter_v4i16_no_uniform_vals_uniform_ptrs_all_inactive_mask(407; CHECK-NEXT: [[INSERT_ELT:%.*]] = insertelement <4 x ptr> poison, ptr [[DST:%.*]], i64 0408; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x ptr> [[INSERT_ELT]], <4 x ptr> poison, <4 x i32> <i32 poison, i32 poison, i32 0, i32 0>409; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i16>, ptr [[SRC:%.*]], align 2410; CHECK-NEXT: call void @llvm.masked.scatter.v4i16.v4p0(<4 x i16> [[WIDE_LOAD]], <4 x ptr> align 2 [[BROADCAST_SPLAT]], <4 x i1> <i1 false, i1 false, i1 true, i1 true>)411; CHECK-NEXT: ret void412;413 %insert.elt = insertelement <4 x ptr> poison, ptr %dst, i32 0414 %broadcast.splat = shufflevector <4 x ptr> %insert.elt, <4 x ptr> poison, <4 x i32> zeroinitializer415 %wide.load = load <4 x i16>, ptr %src, align 2416 call void @llvm.masked.scatter.v4i16.v4p0(<4 x i16> %wide.load, <4 x ptr> %broadcast.splat, i32 2, <4 x i1> <i1 0, i1 0, i1 1, i1 1>)417 ret void418}419 420;; The pointer in NOT a splat421define void @negative_scatter_v4i16_no_uniform_vals_no_uniform_ptrs_all_active_mask(<4 x ptr> %inPtr, ptr %src) {422; CHECK-LABEL: @negative_scatter_v4i16_no_uniform_vals_no_uniform_ptrs_all_active_mask(423; CHECK-NEXT: [[BROADCAST:%.*]] = shufflevector <4 x ptr> [[INPTR:%.*]], <4 x ptr> poison, <4 x i32> zeroinitializer424; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i16>, ptr [[SRC:%.*]], align 2425; CHECK-NEXT: call void @llvm.masked.scatter.v4i16.v4p0(<4 x i16> [[WIDE_LOAD]], <4 x ptr> align 2 [[BROADCAST]], <4 x i1> splat (i1 true))426; CHECK-NEXT: ret void427;428 %broadcast= shufflevector <4 x ptr> %inPtr, <4 x ptr> poison, <4 x i32> zeroinitializer429 %wide.load = load <4 x i16>, ptr %src, align 2430 call void @llvm.masked.scatter.v4i16.v4p0(<4 x i16> %wide.load, <4 x ptr> %broadcast, i32 2, <4 x i1> <i1 1, i1 1, i1 1, i1 1> )431 ret void432}433 434 435; Function Attrs:436declare void @llvm.masked.scatter.v4i16.v4p0(<4 x i16>, <4 x ptr>, i32 immarg, <4 x i1>)437declare void @llvm.masked.scatter.nxv4i16.nxv4p0(<vscale x 4 x i16>, <vscale x 4 x ptr>, i32 immarg, <vscale x 4 x i1>)438 439; Test gathers that can be simplified to scalar load + splat440 441;; Splat address and all active mask442define <vscale x 2 x i64> @gather_nxv2i64_uniform_ptrs_all_active_mask(ptr %src) {443; CHECK-LABEL: @gather_nxv2i64_uniform_ptrs_all_active_mask(444; CHECK-NEXT: [[LOAD_SCALAR:%.*]] = load i64, ptr [[SRC:%.*]], align 8445; CHECK-NEXT: [[BROADCAST_SPLATINSERT1:%.*]] = insertelement <vscale x 2 x i64> poison, i64 [[LOAD_SCALAR]], i64 0446; CHECK-NEXT: [[BROADCAST_SPLAT2:%.*]] = shufflevector <vscale x 2 x i64> [[BROADCAST_SPLATINSERT1]], <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer447; CHECK-NEXT: ret <vscale x 2 x i64> [[BROADCAST_SPLAT2]]448;449 %broadcast.splatinsert = insertelement <vscale x 2 x ptr> poison, ptr %src, i32 0450 %broadcast.splat = shufflevector <vscale x 2 x ptr> %broadcast.splatinsert, <vscale x 2 x ptr> poison, <vscale x 2 x i32> zeroinitializer451 %res = call <vscale x 2 x i64> @llvm.masked.gather.nxv2i64(<vscale x 2 x ptr> %broadcast.splat, i32 8, <vscale x 2 x i1> splat (i1 true), <vscale x 2 x i64> undef)452 ret <vscale x 2 x i64> %res453}454 455define <2 x i64> @gather_v2i64_uniform_ptrs_all_active_mask(ptr %src) {456; CHECK-LABEL: @gather_v2i64_uniform_ptrs_all_active_mask(457; CHECK-NEXT: [[LOAD_SCALAR:%.*]] = load i64, ptr [[SRC:%.*]], align 8458; CHECK-NEXT: [[BROADCAST_SPLATINSERT1:%.*]] = insertelement <2 x i64> poison, i64 [[LOAD_SCALAR]], i64 0459; CHECK-NEXT: [[BROADCAST_SPLAT2:%.*]] = shufflevector <2 x i64> [[BROADCAST_SPLATINSERT1]], <2 x i64> poison, <2 x i32> zeroinitializer460; CHECK-NEXT: ret <2 x i64> [[BROADCAST_SPLAT2]]461;462 %broadcast.splatinsert = insertelement <2 x ptr> poison, ptr %src, i32 0463 %broadcast.splat = shufflevector <2 x ptr> %broadcast.splatinsert, <2 x ptr> poison, <2 x i32> zeroinitializer464 %res = call <2 x i64> @llvm.masked.gather.v2i64(<2 x ptr> %broadcast.splat, i32 8, <2 x i1> <i1 1, i1 1>, <2 x i64> undef)465 ret <2 x i64> %res466}467 468; Negative gather tests469 470;; Vector of pointers is not a splat.471define <2 x i64> @negative_gather_v2i64_non_uniform_ptrs_all_active_mask(<2 x ptr> %inVal, ptr %src ) {472; CHECK-LABEL: @negative_gather_v2i64_non_uniform_ptrs_all_active_mask(473; CHECK-NEXT: [[INSERT_VALUE:%.*]] = insertelement <2 x ptr> [[INVAL:%.*]], ptr [[SRC:%.*]], i64 1474; CHECK-NEXT: [[RES:%.*]] = call <2 x i64> @llvm.masked.gather.v2i64.v2p0(<2 x ptr> align 8 [[INSERT_VALUE]], <2 x i1> splat (i1 true), <2 x i64> poison)475; CHECK-NEXT: ret <2 x i64> [[RES]]476;477 %insert.value = insertelement <2 x ptr> %inVal, ptr %src, i32 1478 %res = call <2 x i64> @llvm.masked.gather.v2i64(<2 x ptr> %insert.value, i32 8, <2 x i1><i1 1, i1 1>, <2 x i64> undef)479 ret <2 x i64> %res480}481 482;; Unknown mask value483define <2 x i64> @negative_gather_v2i64_uniform_ptrs_no_all_active_mask(ptr %src, <2 x i1> %mask) {484; CHECK-LABEL: @negative_gather_v2i64_uniform_ptrs_no_all_active_mask(485; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <2 x ptr> poison, ptr [[SRC:%.*]], i64 0486; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <2 x ptr> [[BROADCAST_SPLATINSERT]], <2 x ptr> poison, <2 x i32> zeroinitializer487; CHECK-NEXT: [[RES:%.*]] = call <2 x i64> @llvm.masked.gather.v2i64.v2p0(<2 x ptr> align 8 [[BROADCAST_SPLAT]], <2 x i1> [[MASK:%.*]], <2 x i64> undef)488; CHECK-NEXT: ret <2 x i64> [[RES]]489;490 %broadcast.splatinsert = insertelement <2 x ptr> poison, ptr %src, i32 0491 %broadcast.splat = shufflevector <2 x ptr> %broadcast.splatinsert, <2 x ptr> poison, <2 x i32> zeroinitializer492 %res = call <2 x i64> @llvm.masked.gather.v2i64(<2 x ptr> %broadcast.splat, i32 8, <2 x i1> %mask, <2 x i64> undef)493 ret <2 x i64> %res494}495 496; Function Attrs:497declare <vscale x 2 x i64> @llvm.masked.gather.nxv2i64(<vscale x 2 x ptr>, i32, <vscale x 2 x i1>, <vscale x 2 x i64>)498declare <2 x i64> @llvm.masked.gather.v2i64(<2 x ptr>, i32, <2 x i1>, <2 x i64>)499 500