412 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 62; RUN: llc --mtriple=loongarch32 --mattr=+32s,+lsx < %s | FileCheck %s --check-prefixes=CHECK,LA323; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s --check-prefixes=CHECK,LA644 5define void @and_not_combine_v16i8(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind {6; CHECK-LABEL: and_not_combine_v16i8:7; CHECK: # %bb.0: # %entry8; CHECK-NEXT: vld $vr0, $a2, 09; CHECK-NEXT: vld $vr1, $a3, 010; CHECK-NEXT: vld $vr2, $a1, 011; CHECK-NEXT: vsub.b $vr0, $vr0, $vr112; CHECK-NEXT: vandn.v $vr0, $vr0, $vr213; CHECK-NEXT: vst $vr0, $a0, 014; CHECK-NEXT: ret15entry:16 %v0 = load <16 x i8>, ptr %a017 %v1 = load <16 x i8>, ptr %a118 %v2 = load <16 x i8>, ptr %a219 %not = xor <16 x i8> %v1, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>20 %add = add <16 x i8> %not, %v221 %and = and <16 x i8> %v0, %add22 store <16 x i8> %and, ptr %res23 ret void24}25 26define void @and_not_combine_v8i16(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind {27; CHECK-LABEL: and_not_combine_v8i16:28; CHECK: # %bb.0: # %entry29; CHECK-NEXT: vld $vr0, $a2, 030; CHECK-NEXT: vld $vr1, $a3, 031; CHECK-NEXT: vld $vr2, $a1, 032; CHECK-NEXT: vsub.h $vr0, $vr0, $vr133; CHECK-NEXT: vandn.v $vr0, $vr0, $vr234; CHECK-NEXT: vst $vr0, $a0, 035; CHECK-NEXT: ret36entry:37 %v0 = load <8 x i16>, ptr %a038 %v1 = load <8 x i16>, ptr %a139 %v2 = load <8 x i16>, ptr %a240 %not = xor <8 x i16> %v1, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>41 %add = add <8 x i16> %not, %v242 %and = and <8 x i16> %v0, %add43 store <8 x i16> %and, ptr %res44 ret void45}46 47define void @and_not_combine_v4i32(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind {48; CHECK-LABEL: and_not_combine_v4i32:49; CHECK: # %bb.0: # %entry50; CHECK-NEXT: vld $vr0, $a2, 051; CHECK-NEXT: vld $vr1, $a3, 052; CHECK-NEXT: vld $vr2, $a1, 053; CHECK-NEXT: vsub.w $vr0, $vr0, $vr154; CHECK-NEXT: vandn.v $vr0, $vr0, $vr255; CHECK-NEXT: vst $vr0, $a0, 056; CHECK-NEXT: ret57entry:58 %v0 = load <4 x i32>, ptr %a059 %v1 = load <4 x i32>, ptr %a160 %v2 = load <4 x i32>, ptr %a261 %not = xor <4 x i32> %v1, <i32 -1, i32 -1, i32 -1, i32 -1>62 %add = add <4 x i32> %not, %v263 %and = and <4 x i32> %v0, %add64 store <4 x i32> %and, ptr %res65 ret void66}67 68define void @and_not_combine_v2i64(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind {69; CHECK-LABEL: and_not_combine_v2i64:70; CHECK: # %bb.0: # %entry71; CHECK-NEXT: vld $vr0, $a2, 072; CHECK-NEXT: vld $vr1, $a3, 073; CHECK-NEXT: vld $vr2, $a1, 074; CHECK-NEXT: vsub.d $vr0, $vr0, $vr175; CHECK-NEXT: vandn.v $vr0, $vr0, $vr276; CHECK-NEXT: vst $vr0, $a0, 077; CHECK-NEXT: ret78entry:79 %v0 = load <2 x i64>, ptr %a080 %v1 = load <2 x i64>, ptr %a181 %v2 = load <2 x i64>, ptr %a282 %not = xor <2 x i64> %v1, <i64 -1, i64 -1>83 %add = add <2 x i64> %not, %v284 %and = and <2 x i64> %v0, %add85 store <2 x i64> %and, ptr %res86 ret void87}88 89define void @pre_not_and_not_combine_v16i8(ptr %res, ptr %a, i8 %b) nounwind {90; CHECK-LABEL: pre_not_and_not_combine_v16i8:91; CHECK: # %bb.0:92; CHECK-NEXT: vld $vr0, $a1, 093; CHECK-NEXT: vreplgr2vr.b $vr1, $a294; CHECK-NEXT: vnor.v $vr0, $vr0, $vr195; CHECK-NEXT: vst $vr0, $a0, 096; CHECK-NEXT: ret97 %v0 = load <16 x i8>, ptr %a98 %b.not = xor i8 %b, -199 %b.not.ele = insertelement <16 x i8> poison, i8 %b.not, i64 0100 %v1.not = shufflevector <16 x i8> %b.not.ele, <16 x i8> poison, <16 x i32> zeroinitializer101 %v0.not = xor <16 x i8> %v0, splat (i8 -1)102 %and = and <16 x i8> %v0.not, %v1.not103 store <16 x i8> %and, ptr %res104 ret void105}106 107define void @post_not_and_not_combine_v16i8(ptr %res, ptr %a, i8 %b) nounwind {108; CHECK-LABEL: post_not_and_not_combine_v16i8:109; CHECK: # %bb.0:110; CHECK-NEXT: vld $vr0, $a1, 0111; CHECK-NEXT: vreplgr2vr.b $vr1, $a2112; CHECK-NEXT: vnor.v $vr0, $vr0, $vr1113; CHECK-NEXT: vst $vr0, $a0, 0114; CHECK-NEXT: ret115 %v0 = load <16 x i8>, ptr %a116 %b.ele = insertelement <16 x i8> poison, i8 %b, i64 0117 %v1 = shufflevector <16 x i8> %b.ele, <16 x i8> poison, <16 x i32> zeroinitializer118 %v0.not = xor <16 x i8> %v0, splat (i8 -1)119 %v1.not = xor <16 x i8> %v1, splat (i8 -1)120 %and = and <16 x i8> %v0.not, %v1.not121 store <16 x i8> %and, ptr %res122 ret void123}124 125define void @pre_not_and_not_combine_v8i16(ptr %res, ptr %a, i16 %b) nounwind {126; CHECK-LABEL: pre_not_and_not_combine_v8i16:127; CHECK: # %bb.0:128; CHECK-NEXT: vld $vr0, $a1, 0129; CHECK-NEXT: vreplgr2vr.h $vr1, $a2130; CHECK-NEXT: vnor.v $vr0, $vr0, $vr1131; CHECK-NEXT: vst $vr0, $a0, 0132; CHECK-NEXT: ret133 %v0 = load <8 x i16>, ptr %a134 %b.not = xor i16 %b, -1135 %b.not.ele = insertelement <8 x i16> poison, i16 %b.not, i64 0136 %v1.not = shufflevector <8 x i16> %b.not.ele, <8 x i16> poison, <8 x i32> zeroinitializer137 %v0.not = xor <8 x i16> %v0, splat (i16 -1)138 %and = and <8 x i16> %v0.not, %v1.not139 store <8 x i16> %and, ptr %res140 ret void141}142 143define void @post_not_and_not_combine_v8i16(ptr %res, ptr %a, i16 %b) nounwind {144; CHECK-LABEL: post_not_and_not_combine_v8i16:145; CHECK: # %bb.0:146; CHECK-NEXT: vld $vr0, $a1, 0147; CHECK-NEXT: vreplgr2vr.h $vr1, $a2148; CHECK-NEXT: vnor.v $vr0, $vr0, $vr1149; CHECK-NEXT: vst $vr0, $a0, 0150; CHECK-NEXT: ret151 %v0 = load <8 x i16>, ptr %a152 %b.ele = insertelement <8 x i16> poison, i16 %b, i64 0153 %v1 = shufflevector <8 x i16> %b.ele, <8 x i16> poison, <8 x i32> zeroinitializer154 %v0.not = xor <8 x i16> %v0, splat (i16 -1)155 %v1.not = xor <8 x i16> %v1, splat (i16 -1)156 %and = and <8 x i16> %v0.not, %v1.not157 store <8 x i16> %and, ptr %res158 ret void159}160 161define void @pre_not_and_not_combine_v4i32(ptr %res, ptr %a, i32 %b) nounwind {162; CHECK-LABEL: pre_not_and_not_combine_v4i32:163; CHECK: # %bb.0:164; CHECK-NEXT: vld $vr0, $a1, 0165; CHECK-NEXT: vreplgr2vr.w $vr1, $a2166; CHECK-NEXT: vnor.v $vr0, $vr0, $vr1167; CHECK-NEXT: vst $vr0, $a0, 0168; CHECK-NEXT: ret169 %v0 = load <4 x i32>, ptr %a170 %b.not = xor i32 %b, -1171 %b.not.ele = insertelement <4 x i32> poison, i32 %b.not, i64 0172 %v1.not = shufflevector <4 x i32> %b.not.ele, <4 x i32> poison, <4 x i32> zeroinitializer173 %v0.not = xor <4 x i32> %v0, splat (i32 -1)174 %and = and <4 x i32> %v0.not, %v1.not175 store <4 x i32> %and, ptr %res176 ret void177}178 179define void @post_not_and_not_combine_v4i32(ptr %res, ptr %a, i32 %b) nounwind {180; CHECK-LABEL: post_not_and_not_combine_v4i32:181; CHECK: # %bb.0:182; CHECK-NEXT: vld $vr0, $a1, 0183; CHECK-NEXT: vreplgr2vr.w $vr1, $a2184; CHECK-NEXT: vnor.v $vr0, $vr0, $vr1185; CHECK-NEXT: vst $vr0, $a0, 0186; CHECK-NEXT: ret187 %v0 = load <4 x i32>, ptr %a188 %b.ele = insertelement <4 x i32> poison, i32 %b, i64 0189 %v1 = shufflevector <4 x i32> %b.ele, <4 x i32> poison, <4 x i32> zeroinitializer190 %v0.not = xor <4 x i32> %v0, splat (i32 -1)191 %v1.not = xor <4 x i32> %v1, splat (i32 -1)192 %and = and <4 x i32> %v0.not, %v1.not193 store <4 x i32> %and, ptr %res194 ret void195}196 197define void @pre_not_and_not_combine_v2i64(ptr %res, ptr %a, i64 %b) nounwind {198; LA32-LABEL: pre_not_and_not_combine_v2i64:199; LA32: # %bb.0:200; LA32-NEXT: vld $vr0, $a1, 0201; LA32-NEXT: nor $a1, $a3, $zero202; LA32-NEXT: nor $a2, $a2, $zero203; LA32-NEXT: vinsgr2vr.w $vr1, $a2, 0204; LA32-NEXT: vinsgr2vr.w $vr1, $a1, 1205; LA32-NEXT: vreplvei.d $vr1, $vr1, 0206; LA32-NEXT: vandn.v $vr0, $vr0, $vr1207; LA32-NEXT: vst $vr0, $a0, 0208; LA32-NEXT: ret209;210; LA64-LABEL: pre_not_and_not_combine_v2i64:211; LA64: # %bb.0:212; LA64-NEXT: vld $vr0, $a1, 0213; LA64-NEXT: vreplgr2vr.d $vr1, $a2214; LA64-NEXT: vnor.v $vr0, $vr0, $vr1215; LA64-NEXT: vst $vr0, $a0, 0216; LA64-NEXT: ret217 %v0 = load <2 x i64>, ptr %a218 %b.not = xor i64 %b, -1219 %b.not.ele = insertelement <2 x i64> poison, i64 %b.not, i64 0220 %v1.not = shufflevector <2 x i64> %b.not.ele, <2 x i64> poison, <2 x i32> zeroinitializer221 %v0.not = xor <2 x i64> %v0, splat (i64 -1)222 %and = and <2 x i64> %v0.not, %v1.not223 store <2 x i64> %and, ptr %res224 ret void225}226 227define void @post_not_and_not_combine_v2i64(ptr %res, ptr %a, i64 %b) nounwind {228; LA32-LABEL: post_not_and_not_combine_v2i64:229; LA32: # %bb.0:230; LA32-NEXT: vld $vr0, $a1, 0231; LA32-NEXT: vinsgr2vr.w $vr1, $a2, 0232; LA32-NEXT: vinsgr2vr.w $vr1, $a3, 1233; LA32-NEXT: vreplvei.d $vr1, $vr1, 0234; LA32-NEXT: vnor.v $vr0, $vr0, $vr1235; LA32-NEXT: vst $vr0, $a0, 0236; LA32-NEXT: ret237;238; LA64-LABEL: post_not_and_not_combine_v2i64:239; LA64: # %bb.0:240; LA64-NEXT: vld $vr0, $a1, 0241; LA64-NEXT: vreplgr2vr.d $vr1, $a2242; LA64-NEXT: vnor.v $vr0, $vr0, $vr1243; LA64-NEXT: vst $vr0, $a0, 0244; LA64-NEXT: ret245 %v0 = load <2 x i64>, ptr %a246 %b.ele = insertelement <2 x i64> poison, i64 %b, i64 0247 %v1 = shufflevector <2 x i64> %b.ele, <2 x i64> poison, <2 x i32> zeroinitializer248 %v0.not = xor <2 x i64> %v0, splat (i64 -1)249 %v1.not = xor <2 x i64> %v1, splat (i64 -1)250 %and = and <2 x i64> %v0.not, %v1.not251 store <2 x i64> %and, ptr %res252 ret void253}254 255define void @and_not_combine_splatimm_v16i8(ptr %res, ptr %a0) nounwind {256; CHECK-LABEL: and_not_combine_splatimm_v16i8:257; CHECK: # %bb.0:258; CHECK-NEXT: vld $vr0, $a1, 0259; CHECK-NEXT: vnori.b $vr0, $vr0, 3260; CHECK-NEXT: vst $vr0, $a0, 0261; CHECK-NEXT: ret262 %v0 = load <16 x i8>, ptr %a0263 %and = and <16 x i8> %v0, splat (i8 -4)264 %xor = xor <16 x i8> %and, splat (i8 -4)265 store <16 x i8> %xor, ptr %res266 ret void267}268 269define void @and_not_combine_splatimm_v8i16(ptr %res, ptr %a0) nounwind {270; CHECK-LABEL: and_not_combine_splatimm_v8i16:271; CHECK: # %bb.0:272; CHECK-NEXT: vld $vr0, $a1, 0273; CHECK-NEXT: vrepli.h $vr1, -4274; CHECK-NEXT: vandn.v $vr0, $vr0, $vr1275; CHECK-NEXT: vst $vr0, $a0, 0276; CHECK-NEXT: ret277 %v0 = load <8 x i16>, ptr %a0278 %and = and <8 x i16> %v0, splat (i16 -4)279 %xor = xor <8 x i16> %and, splat (i16 -4)280 store <8 x i16> %xor, ptr %res281 ret void282}283 284define void @and_not_combine_splatimm_v4i32(ptr %res, ptr %a0) nounwind {285; CHECK-LABEL: and_not_combine_splatimm_v4i32:286; CHECK: # %bb.0:287; CHECK-NEXT: vld $vr0, $a1, 0288; CHECK-NEXT: vrepli.w $vr1, -4289; CHECK-NEXT: vandn.v $vr0, $vr0, $vr1290; CHECK-NEXT: vst $vr0, $a0, 0291; CHECK-NEXT: ret292 %v0 = load <4 x i32>, ptr %a0293 %and = and <4 x i32> %v0, splat (i32 -4)294 %xor = xor <4 x i32> %and, splat (i32 -4)295 store <4 x i32> %xor, ptr %res296 ret void297}298 299define void @and_not_combine_splatimm_v2i64(ptr %res, ptr %a0) nounwind {300; CHECK-LABEL: and_not_combine_splatimm_v2i64:301; CHECK: # %bb.0:302; CHECK-NEXT: vld $vr0, $a1, 0303; CHECK-NEXT: vrepli.d $vr1, -4304; CHECK-NEXT: vandn.v $vr0, $vr0, $vr1305; CHECK-NEXT: vst $vr0, $a0, 0306; CHECK-NEXT: ret307 %v0 = load <2 x i64>, ptr %a0308 %and = and <2 x i64> %v0, splat (i64 -4)309 %xor = xor <2 x i64> %and, splat (i64 -4)310 store <2 x i64> %xor, ptr %res311 ret void312}313 314define void @and_or_not_combine_v16i8(ptr %pa, ptr %pb, ptr %pv, ptr %dst) nounwind {315; CHECK-LABEL: and_or_not_combine_v16i8:316; CHECK: # %bb.0:317; CHECK-NEXT: vld $vr0, $a0, 0318; CHECK-NEXT: vld $vr1, $a2, 0319; CHECK-NEXT: vld $vr2, $a1, 0320; CHECK-NEXT: vseq.b $vr0, $vr1, $vr0321; CHECK-NEXT: vseq.b $vr1, $vr1, $vr2322; CHECK-NEXT: vand.v $vr0, $vr0, $vr1323; CHECK-NEXT: vnori.b $vr0, $vr0, 251324; CHECK-NEXT: vst $vr0, $a3, 0325; CHECK-NEXT: ret326 %a = load <16 x i8>, ptr %pa327 %b = load <16 x i8>, ptr %pb328 %v = load <16 x i8>, ptr %pv329 %ca = icmp ne <16 x i8> %v, %a330 %cb = icmp ne <16 x i8> %v, %b331 %or = or <16 x i1> %ca, %cb332 %ext = sext <16 x i1> %or to <16 x i8>333 %and = and <16 x i8> %ext, splat (i8 4)334 store <16 x i8> %and, ptr %dst335 ret void336}337 338define void @and_or_not_combine_v8i16(ptr %pa, ptr %pb, ptr %pv, ptr %dst) nounwind {339; CHECK-LABEL: and_or_not_combine_v8i16:340; CHECK: # %bb.0:341; CHECK-NEXT: vld $vr0, $a0, 0342; CHECK-NEXT: vld $vr1, $a2, 0343; CHECK-NEXT: vld $vr2, $a1, 0344; CHECK-NEXT: vseq.h $vr0, $vr1, $vr0345; CHECK-NEXT: vseq.h $vr1, $vr1, $vr2346; CHECK-NEXT: vand.v $vr0, $vr0, $vr1347; CHECK-NEXT: vrepli.h $vr1, 4348; CHECK-NEXT: vandn.v $vr0, $vr0, $vr1349; CHECK-NEXT: vst $vr0, $a3, 0350; CHECK-NEXT: ret351 %a = load <8 x i16>, ptr %pa352 %b = load <8 x i16>, ptr %pb353 %v = load <8 x i16>, ptr %pv354 %ca = icmp ne <8 x i16> %v, %a355 %cb = icmp ne <8 x i16> %v, %b356 %or = or <8 x i1> %ca, %cb357 %ext = sext <8 x i1> %or to <8 x i16>358 %and = and <8 x i16> %ext, splat (i16 4)359 store <8 x i16> %and, ptr %dst360 ret void361}362 363define void @and_or_not_combine_v4i32(ptr %pa, ptr %pb, ptr %pv, ptr %dst) nounwind {364; CHECK-LABEL: and_or_not_combine_v4i32:365; CHECK: # %bb.0:366; CHECK-NEXT: vld $vr0, $a0, 0367; CHECK-NEXT: vld $vr1, $a2, 0368; CHECK-NEXT: vld $vr2, $a1, 0369; CHECK-NEXT: vseq.w $vr0, $vr1, $vr0370; CHECK-NEXT: vseq.w $vr1, $vr1, $vr2371; CHECK-NEXT: vand.v $vr0, $vr0, $vr1372; CHECK-NEXT: vrepli.w $vr1, 4373; CHECK-NEXT: vandn.v $vr0, $vr0, $vr1374; CHECK-NEXT: vst $vr0, $a3, 0375; CHECK-NEXT: ret376 %a = load <4 x i32>, ptr %pa377 %b = load <4 x i32>, ptr %pb378 %v = load <4 x i32>, ptr %pv379 %ca = icmp ne <4 x i32> %v, %a380 %cb = icmp ne <4 x i32> %v, %b381 %or = or <4 x i1> %ca, %cb382 %ext = sext <4 x i1> %or to <4 x i32>383 %and = and <4 x i32> %ext, splat (i32 4)384 store <4 x i32> %and, ptr %dst385 ret void386}387 388define void @and_or_not_combine_v2i64(ptr %pa, ptr %pb, ptr %pv, ptr %dst) nounwind {389; CHECK-LABEL: and_or_not_combine_v2i64:390; CHECK: # %bb.0:391; CHECK-NEXT: vld $vr0, $a0, 0392; CHECK-NEXT: vld $vr1, $a2, 0393; CHECK-NEXT: vld $vr2, $a1, 0394; CHECK-NEXT: vseq.d $vr0, $vr1, $vr0395; CHECK-NEXT: vseq.d $vr1, $vr1, $vr2396; CHECK-NEXT: vand.v $vr0, $vr0, $vr1397; CHECK-NEXT: vrepli.d $vr1, 4398; CHECK-NEXT: vandn.v $vr0, $vr0, $vr1399; CHECK-NEXT: vst $vr0, $a3, 0400; CHECK-NEXT: ret401 %a = load <2 x i64>, ptr %pa402 %b = load <2 x i64>, ptr %pb403 %v = load <2 x i64>, ptr %pv404 %ca = icmp ne <2 x i64> %v, %a405 %cb = icmp ne <2 x i64> %v, %b406 %or = or <2 x i1> %ca, %cb407 %ext = sext <2 x i1> %or to <2 x i64>408 %and = and <2 x i64> %ext, splat (i64 4)409 store <2 x i64> %and, ptr %dst410 ret void411}412