808 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=riscv64 -mattr=+experimental-p -enable-p-ext-codegen -verify-machineinstrs < %s | FileCheck %s3 4; Test basic add/sub operations for v4i165define void @test_padd_h(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {6; CHECK-LABEL: test_padd_h:7; CHECK: # %bb.0:8; CHECK-NEXT: ld a1, 0(a1)9; CHECK-NEXT: ld a2, 0(a2)10; CHECK-NEXT: padd.h a1, a1, a211; CHECK-NEXT: sd a1, 0(a0)12; CHECK-NEXT: ret13 %a = load <4 x i16>, ptr %a_ptr14 %b = load <4 x i16>, ptr %b_ptr15 %res = add <4 x i16> %a, %b16 store <4 x i16> %res, ptr %ret_ptr17 ret void18}19 20define void @test_psub_h(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {21; CHECK-LABEL: test_psub_h:22; CHECK: # %bb.0:23; CHECK-NEXT: ld a1, 0(a1)24; CHECK-NEXT: ld a2, 0(a2)25; CHECK-NEXT: psub.h a1, a1, a226; CHECK-NEXT: sd a1, 0(a0)27; CHECK-NEXT: ret28 %a = load <4 x i16>, ptr %a_ptr29 %b = load <4 x i16>, ptr %b_ptr30 %res = sub <4 x i16> %a, %b31 store <4 x i16> %res, ptr %ret_ptr32 ret void33}34 35; Test basic add/sub operations for v8i836define void @test_padd_b(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {37; CHECK-LABEL: test_padd_b:38; CHECK: # %bb.0:39; CHECK-NEXT: ld a1, 0(a1)40; CHECK-NEXT: ld a2, 0(a2)41; CHECK-NEXT: padd.b a1, a1, a242; CHECK-NEXT: sd a1, 0(a0)43; CHECK-NEXT: ret44 %a = load <8 x i8>, ptr %a_ptr45 %b = load <8 x i8>, ptr %b_ptr46 %res = add <8 x i8> %a, %b47 store <8 x i8> %res, ptr %ret_ptr48 ret void49}50 51define void @test_psub_b(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {52; CHECK-LABEL: test_psub_b:53; CHECK: # %bb.0:54; CHECK-NEXT: ld a1, 0(a1)55; CHECK-NEXT: ld a2, 0(a2)56; CHECK-NEXT: psub.b a1, a1, a257; CHECK-NEXT: sd a1, 0(a0)58; CHECK-NEXT: ret59 %a = load <8 x i8>, ptr %a_ptr60 %b = load <8 x i8>, ptr %b_ptr61 %res = sub <8 x i8> %a, %b62 store <8 x i8> %res, ptr %ret_ptr63 ret void64}65 66; Test saturating add operations for v4i1667define void @test_psadd_h(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {68; CHECK-LABEL: test_psadd_h:69; CHECK: # %bb.0:70; CHECK-NEXT: ld a1, 0(a1)71; CHECK-NEXT: ld a2, 0(a2)72; CHECK-NEXT: psadd.h a1, a1, a273; CHECK-NEXT: sd a1, 0(a0)74; CHECK-NEXT: ret75 %a = load <4 x i16>, ptr %a_ptr76 %b = load <4 x i16>, ptr %b_ptr77 %res = call <4 x i16> @llvm.sadd.sat.v4i16(<4 x i16> %a, <4 x i16> %b)78 store <4 x i16> %res, ptr %ret_ptr79 ret void80}81 82define void @test_psaddu_h(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {83; CHECK-LABEL: test_psaddu_h:84; CHECK: # %bb.0:85; CHECK-NEXT: ld a1, 0(a1)86; CHECK-NEXT: ld a2, 0(a2)87; CHECK-NEXT: psaddu.h a1, a1, a288; CHECK-NEXT: sd a1, 0(a0)89; CHECK-NEXT: ret90 %a = load <4 x i16>, ptr %a_ptr91 %b = load <4 x i16>, ptr %b_ptr92 %res = call <4 x i16> @llvm.uadd.sat.v4i16(<4 x i16> %a, <4 x i16> %b)93 store <4 x i16> %res, ptr %ret_ptr94 ret void95}96 97; Test saturating sub operations for v4i1698define void @test_pssub_h(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {99; CHECK-LABEL: test_pssub_h:100; CHECK: # %bb.0:101; CHECK-NEXT: ld a1, 0(a1)102; CHECK-NEXT: ld a2, 0(a2)103; CHECK-NEXT: pssub.h a1, a1, a2104; CHECK-NEXT: sd a1, 0(a0)105; CHECK-NEXT: ret106 %a = load <4 x i16>, ptr %a_ptr107 %b = load <4 x i16>, ptr %b_ptr108 %res = call <4 x i16> @llvm.ssub.sat.v4i16(<4 x i16> %a, <4 x i16> %b)109 store <4 x i16> %res, ptr %ret_ptr110 ret void111}112 113define void @test_pssubu_h(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {114; CHECK-LABEL: test_pssubu_h:115; CHECK: # %bb.0:116; CHECK-NEXT: ld a1, 0(a1)117; CHECK-NEXT: ld a2, 0(a2)118; CHECK-NEXT: pssubu.h a1, a1, a2119; CHECK-NEXT: sd a1, 0(a0)120; CHECK-NEXT: ret121 %a = load <4 x i16>, ptr %a_ptr122 %b = load <4 x i16>, ptr %b_ptr123 %res = call <4 x i16> @llvm.usub.sat.v4i16(<4 x i16> %a, <4 x i16> %b)124 store <4 x i16> %res, ptr %ret_ptr125 ret void126}127 128; Test saturating add operations for v8i8129define void @test_psadd_b(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {130; CHECK-LABEL: test_psadd_b:131; CHECK: # %bb.0:132; CHECK-NEXT: ld a1, 0(a1)133; CHECK-NEXT: ld a2, 0(a2)134; CHECK-NEXT: psadd.b a1, a1, a2135; CHECK-NEXT: sd a1, 0(a0)136; CHECK-NEXT: ret137 %a = load <8 x i8>, ptr %a_ptr138 %b = load <8 x i8>, ptr %b_ptr139 %res = call <8 x i8> @llvm.sadd.sat.v8i8(<8 x i8> %a, <8 x i8> %b)140 store <8 x i8> %res, ptr %ret_ptr141 ret void142}143 144define void @test_psaddu_b(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {145; CHECK-LABEL: test_psaddu_b:146; CHECK: # %bb.0:147; CHECK-NEXT: ld a1, 0(a1)148; CHECK-NEXT: ld a2, 0(a2)149; CHECK-NEXT: psaddu.b a1, a1, a2150; CHECK-NEXT: sd a1, 0(a0)151; CHECK-NEXT: ret152 %a = load <8 x i8>, ptr %a_ptr153 %b = load <8 x i8>, ptr %b_ptr154 %res = call <8 x i8> @llvm.uadd.sat.v8i8(<8 x i8> %a, <8 x i8> %b)155 store <8 x i8> %res, ptr %ret_ptr156 ret void157}158 159; Test saturating sub operations for v8i8160define void @test_pssub_b(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {161; CHECK-LABEL: test_pssub_b:162; CHECK: # %bb.0:163; CHECK-NEXT: ld a1, 0(a1)164; CHECK-NEXT: ld a2, 0(a2)165; CHECK-NEXT: pssub.b a1, a1, a2166; CHECK-NEXT: sd a1, 0(a0)167; CHECK-NEXT: ret168 %a = load <8 x i8>, ptr %a_ptr169 %b = load <8 x i8>, ptr %b_ptr170 %res = call <8 x i8> @llvm.ssub.sat.v8i8(<8 x i8> %a, <8 x i8> %b)171 store <8 x i8> %res, ptr %ret_ptr172 ret void173}174 175define void @test_pssubu_b(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {176; CHECK-LABEL: test_pssubu_b:177; CHECK: # %bb.0:178; CHECK-NEXT: ld a1, 0(a1)179; CHECK-NEXT: ld a2, 0(a2)180; CHECK-NEXT: pssubu.b a1, a1, a2181; CHECK-NEXT: sd a1, 0(a0)182; CHECK-NEXT: ret183 %a = load <8 x i8>, ptr %a_ptr184 %b = load <8 x i8>, ptr %b_ptr185 %res = call <8 x i8> @llvm.usub.sat.v8i8(<8 x i8> %a, <8 x i8> %b)186 store <8 x i8> %res, ptr %ret_ptr187 ret void188}189 190; Test averaging floor signed operations for v4i16191; avgfloors pattern: (a + b) arithmetic shift right 1192define void @test_paadd_h(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {193; CHECK-LABEL: test_paadd_h:194; CHECK: # %bb.0:195; CHECK-NEXT: ld a1, 0(a1)196; CHECK-NEXT: ld a2, 0(a2)197; CHECK-NEXT: paadd.h a1, a1, a2198; CHECK-NEXT: sd a1, 0(a0)199; CHECK-NEXT: ret200 %a = load <4 x i16>, ptr %a_ptr201 %b = load <4 x i16>, ptr %b_ptr202 %ext.a = sext <4 x i16> %a to <4 x i32>203 %ext.b = sext <4 x i16> %b to <4 x i32>204 %add = add nsw <4 x i32> %ext.a, %ext.b205 %shift = ashr <4 x i32> %add, <i32 1, i32 1, i32 1, i32 1>206 %res = trunc <4 x i32> %shift to <4 x i16>207 store <4 x i16> %res, ptr %ret_ptr208 ret void209}210 211; Test averaging floor unsigned operations for v4i16212; avgflooru pattern: (a & b) + ((a ^ b) >> 1)213define void @test_paaddu_h(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {214; CHECK-LABEL: test_paaddu_h:215; CHECK: # %bb.0:216; CHECK-NEXT: ld a1, 0(a1)217; CHECK-NEXT: ld a2, 0(a2)218; CHECK-NEXT: paaddu.h a1, a1, a2219; CHECK-NEXT: sd a1, 0(a0)220; CHECK-NEXT: ret221 %a = load <4 x i16>, ptr %a_ptr222 %b = load <4 x i16>, ptr %b_ptr223 %and = and <4 x i16> %a, %b224 %xor = xor <4 x i16> %a, %b225 %shift = lshr <4 x i16> %xor, <i16 1, i16 1, i16 1, i16 1>226 %res = add <4 x i16> %and, %shift227 store <4 x i16> %res, ptr %ret_ptr228 ret void229}230 231; Test averaging floor signed operations for v8i8232define void @test_paadd_b(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {233; CHECK-LABEL: test_paadd_b:234; CHECK: # %bb.0:235; CHECK-NEXT: ld a1, 0(a1)236; CHECK-NEXT: ld a2, 0(a2)237; CHECK-NEXT: paadd.b a1, a1, a2238; CHECK-NEXT: sd a1, 0(a0)239; CHECK-NEXT: ret240 %a = load <8 x i8>, ptr %a_ptr241 %b = load <8 x i8>, ptr %b_ptr242 %ext.a = sext <8 x i8> %a to <8 x i16>243 %ext.b = sext <8 x i8> %b to <8 x i16>244 %add = add nsw <8 x i16> %ext.a, %ext.b245 %shift = ashr <8 x i16> %add, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>246 %res = trunc <8 x i16> %shift to <8 x i8>247 store <8 x i8> %res, ptr %ret_ptr248 ret void249}250 251; Test averaging floor unsigned operations for v8i8252define void @test_paaddu_b(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {253; CHECK-LABEL: test_paaddu_b:254; CHECK: # %bb.0:255; CHECK-NEXT: ld a1, 0(a1)256; CHECK-NEXT: ld a2, 0(a2)257; CHECK-NEXT: paaddu.b a1, a1, a2258; CHECK-NEXT: sd a1, 0(a0)259; CHECK-NEXT: ret260 %a = load <8 x i8>, ptr %a_ptr261 %b = load <8 x i8>, ptr %b_ptr262 %and = and <8 x i8> %a, %b263 %xor = xor <8 x i8> %a, %b264 %shift = lshr <8 x i8> %xor, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>265 %res = add <8 x i8> %and, %shift266 store <8 x i8> %res, ptr %ret_ptr267 ret void268}269 270; Test absolute difference signed for v4i16271; abds pattern: sub(smax(a,b), smin(a,b))272define void @test_pdif_h(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {273; CHECK-LABEL: test_pdif_h:274; CHECK: # %bb.0:275; CHECK-NEXT: ld a1, 0(a1)276; CHECK-NEXT: ld a2, 0(a2)277; CHECK-NEXT: pdif.h a1, a1, a2278; CHECK-NEXT: sd a1, 0(a0)279; CHECK-NEXT: ret280 %a = load <4 x i16>, ptr %a_ptr281 %b = load <4 x i16>, ptr %b_ptr282 %min = call <4 x i16> @llvm.smin.v4i16(<4 x i16> %a, <4 x i16> %b)283 %max = call <4 x i16> @llvm.smax.v4i16(<4 x i16> %a, <4 x i16> %b)284 %res = sub <4 x i16> %max, %min285 store <4 x i16> %res, ptr %ret_ptr286 ret void287}288 289; Test absolute difference unsigned for v4i16290; abdu pattern: sub(umax(a,b), umin(a,b))291define void @test_pdifu_h(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {292; CHECK-LABEL: test_pdifu_h:293; CHECK: # %bb.0:294; CHECK-NEXT: ld a1, 0(a1)295; CHECK-NEXT: ld a2, 0(a2)296; CHECK-NEXT: pdifu.h a1, a1, a2297; CHECK-NEXT: sd a1, 0(a0)298; CHECK-NEXT: ret299 %a = load <4 x i16>, ptr %a_ptr300 %b = load <4 x i16>, ptr %b_ptr301 %min = call <4 x i16> @llvm.umin.v4i16(<4 x i16> %a, <4 x i16> %b)302 %max = call <4 x i16> @llvm.umax.v4i16(<4 x i16> %a, <4 x i16> %b)303 %res = sub <4 x i16> %max, %min304 store <4 x i16> %res, ptr %ret_ptr305 ret void306}307 308; Test absolute difference signed for v8i8309define void @test_pdif_b(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {310; CHECK-LABEL: test_pdif_b:311; CHECK: # %bb.0:312; CHECK-NEXT: ld a1, 0(a1)313; CHECK-NEXT: ld a2, 0(a2)314; CHECK-NEXT: pdif.b a1, a1, a2315; CHECK-NEXT: sd a1, 0(a0)316; CHECK-NEXT: ret317 %a = load <8 x i8>, ptr %a_ptr318 %b = load <8 x i8>, ptr %b_ptr319 %min = call <8 x i8> @llvm.smin.v8i8(<8 x i8> %a, <8 x i8> %b)320 %max = call <8 x i8> @llvm.smax.v8i8(<8 x i8> %a, <8 x i8> %b)321 %res = sub <8 x i8> %max, %min322 store <8 x i8> %res, ptr %ret_ptr323 ret void324}325 326; Test absolute difference unsigned for v8i8327define void @test_pdifu_b(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {328; CHECK-LABEL: test_pdifu_b:329; CHECK: # %bb.0:330; CHECK-NEXT: ld a1, 0(a1)331; CHECK-NEXT: ld a2, 0(a2)332; CHECK-NEXT: pdifu.b a1, a1, a2333; CHECK-NEXT: sd a1, 0(a0)334; CHECK-NEXT: ret335 %a = load <8 x i8>, ptr %a_ptr336 %b = load <8 x i8>, ptr %b_ptr337 %min = call <8 x i8> @llvm.umin.v8i8(<8 x i8> %a, <8 x i8> %b)338 %max = call <8 x i8> @llvm.umax.v8i8(<8 x i8> %a, <8 x i8> %b)339 %res = sub <8 x i8> %max, %min340 store <8 x i8> %res, ptr %ret_ptr341 ret void342}343 344; Test averaging floor subtraction signed for v4i16345; pasub pattern: (a - b) arithmetic shift right 1346define void @test_pasub_h(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {347; CHECK-LABEL: test_pasub_h:348; CHECK: # %bb.0:349; CHECK-NEXT: ld a1, 0(a1)350; CHECK-NEXT: ld a2, 0(a2)351; CHECK-NEXT: pasub.h a1, a1, a2352; CHECK-NEXT: sd a1, 0(a0)353; CHECK-NEXT: ret354 %a = load <4 x i16>, ptr %a_ptr355 %b = load <4 x i16>, ptr %b_ptr356 %a_ext = sext <4 x i16> %a to <4 x i32>357 %b_ext = sext <4 x i16> %b to <4 x i32>358 %sub = sub <4 x i32> %a_ext, %b_ext359 %res = ashr <4 x i32> %sub, <i32 1, i32 1, i32 1, i32 1>360 %res_trunc = trunc <4 x i32> %res to <4 x i16>361 store <4 x i16> %res_trunc, ptr %ret_ptr362 ret void363}364 365; Test averaging floor subtraction unsigned for v4i16366; pasubu pattern: (a - b) logical shift right 1367define void @test_pasubu_h(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {368; CHECK-LABEL: test_pasubu_h:369; CHECK: # %bb.0:370; CHECK-NEXT: ld a1, 0(a1)371; CHECK-NEXT: ld a2, 0(a2)372; CHECK-NEXT: pasubu.h a1, a1, a2373; CHECK-NEXT: sd a1, 0(a0)374; CHECK-NEXT: ret375 %a = load <4 x i16>, ptr %a_ptr376 %b = load <4 x i16>, ptr %b_ptr377 %a_ext = zext <4 x i16> %a to <4 x i32>378 %b_ext = zext <4 x i16> %b to <4 x i32>379 %sub = sub <4 x i32> %a_ext, %b_ext380 %res = lshr <4 x i32> %sub, <i32 1, i32 1, i32 1, i32 1>381 %res_trunc = trunc <4 x i32> %res to <4 x i16>382 store <4 x i16> %res_trunc, ptr %ret_ptr383 ret void384}385 386; Test averaging floor subtraction signed for v8i8387define void @test_pasub_b(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {388; CHECK-LABEL: test_pasub_b:389; CHECK: # %bb.0:390; CHECK-NEXT: ld a1, 0(a1)391; CHECK-NEXT: ld a2, 0(a2)392; CHECK-NEXT: pasub.b a1, a1, a2393; CHECK-NEXT: sd a1, 0(a0)394; CHECK-NEXT: ret395 %a = load <8 x i8>, ptr %a_ptr396 %b = load <8 x i8>, ptr %b_ptr397 %a_ext = sext <8 x i8> %a to <8 x i16>398 %b_ext = sext <8 x i8> %b to <8 x i16>399 %sub = sub <8 x i16> %a_ext, %b_ext400 %res = ashr <8 x i16> %sub, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>401 %res_trunc = trunc <8 x i16> %res to <8 x i8>402 store <8 x i8> %res_trunc, ptr %ret_ptr403 ret void404}405 406; Test averaging floor subtraction unsigned for v8i8407define void @test_pasubu_b(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {408; CHECK-LABEL: test_pasubu_b:409; CHECK: # %bb.0:410; CHECK-NEXT: ld a1, 0(a1)411; CHECK-NEXT: ld a2, 0(a2)412; CHECK-NEXT: pasubu.b a1, a1, a2413; CHECK-NEXT: sd a1, 0(a0)414; CHECK-NEXT: ret415 %a = load <8 x i8>, ptr %a_ptr416 %b = load <8 x i8>, ptr %b_ptr417 %a_ext = zext <8 x i8> %a to <8 x i16>418 %b_ext = zext <8 x i8> %b to <8 x i16>419 %sub = sub <8 x i16> %a_ext, %b_ext420 %res = lshr <8 x i16> %sub, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>421 %res_trunc = trunc <8 x i16> %res to <8 x i8>422 store <8 x i8> %res_trunc, ptr %ret_ptr423 ret void424}425 426; Test PLI (pack load immediate) for v4i16427define void @test_pli_h(ptr %ret_ptr) {428; CHECK-LABEL: test_pli_h:429; CHECK: # %bb.0:430; CHECK-NEXT: pli.h a1, 100431; CHECK-NEXT: sd a1, 0(a0)432; CHECK-NEXT: ret433 %res = add <4 x i16> <i16 100, i16 100, i16 100, i16 100>, <i16 0, i16 0, i16 0, i16 0>434 store <4 x i16> %res, ptr %ret_ptr435 ret void436}437 438; Test PLI for v8i8 with unsigned immediate439define void @test_pli_b(ptr %ret_ptr) {440; CHECK-LABEL: test_pli_b:441; CHECK: # %bb.0:442; CHECK-NEXT: pli.b a1, 64443; CHECK-NEXT: sd a1, 0(a0)444; CHECK-NEXT: ret445 %res = add <8 x i8> <i8 64, i8 64, i8 64, i8 64, i8 64, i8 64, i8 64, i8 64>, <i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>446 store <8 x i8> %res, ptr %ret_ptr447 ret void448}449 450; Test PLI for v2i32 with signed immediate451define void @test_pli_w(ptr %ret_ptr) {452; CHECK-LABEL: test_pli_w:453; CHECK: # %bb.0:454; CHECK-NEXT: pli.w a1, -256455; CHECK-NEXT: sd a1, 0(a0)456; CHECK-NEXT: ret457 %res = add <2 x i32> <i32 -256, i32 -256>, <i32 0, i32 0>458 store <2 x i32> %res, ptr %ret_ptr459 ret void460}461 462define void @test_extract_vector_16(ptr %ret_ptr, ptr %a_ptr) {463; CHECK-LABEL: test_extract_vector_16:464; CHECK: # %bb.0:465; CHECK-NEXT: ld a1, 0(a1)466; CHECK-NEXT: sh a1, 0(a0)467; CHECK-NEXT: ret468 %a = load <4 x i16>, ptr %a_ptr469 %extracted = extractelement <4 x i16> %a, i32 0470 store i16 %extracted, ptr %ret_ptr471 ret void472}473 474define void @test_extract_vector_8(ptr %ret_ptr, ptr %a_ptr) {475; CHECK-LABEL: test_extract_vector_8:476; CHECK: # %bb.0:477; CHECK-NEXT: ld a1, 0(a1)478; CHECK-NEXT: sb a1, 0(a0)479; CHECK-NEXT: ret480 %a = load <8 x i8>, ptr %a_ptr481 %extracted = extractelement <8 x i8> %a, i32 0482 store i8 %extracted, ptr %ret_ptr483 ret void484}485 486define void @test_extract_vector_32(ptr %ret_ptr, ptr %a_ptr) {487; CHECK-LABEL: test_extract_vector_32:488; CHECK: # %bb.0:489; CHECK-NEXT: ld a1, 0(a1)490; CHECK-NEXT: sw a1, 0(a0)491; CHECK-NEXT: ret492 %a = load <2 x i32>, ptr %a_ptr493 %extracted = extractelement <2 x i32> %a, i32 0494 store i32 %extracted, ptr %ret_ptr495 ret void496}497 498define void @test_extract_vector_32_elem1(ptr %ret_ptr, ptr %a_ptr) {499; CHECK-LABEL: test_extract_vector_32_elem1:500; CHECK: # %bb.0:501; CHECK-NEXT: lw a1, 4(a1)502; CHECK-NEXT: sw a1, 0(a0)503; CHECK-NEXT: ret504 %a = load <2 x i32>, ptr %a_ptr505 %extracted = extractelement <2 x i32> %a, i32 1506 store i32 %extracted, ptr %ret_ptr507 ret void508}509 510; Test basic add/sub operations for v2i32 (RV64 only)511define void @test_padd_w(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {512; CHECK-LABEL: test_padd_w:513; CHECK: # %bb.0:514; CHECK-NEXT: ld a1, 0(a1)515; CHECK-NEXT: ld a2, 0(a2)516; CHECK-NEXT: padd.w a1, a1, a2517; CHECK-NEXT: sd a1, 0(a0)518; CHECK-NEXT: ret519 %a = load <2 x i32>, ptr %a_ptr520 %b = load <2 x i32>, ptr %b_ptr521 %res = add <2 x i32> %a, %b522 store <2 x i32> %res, ptr %ret_ptr523 ret void524}525 526define void @test_psub_w(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {527; CHECK-LABEL: test_psub_w:528; CHECK: # %bb.0:529; CHECK-NEXT: ld a1, 0(a1)530; CHECK-NEXT: ld a2, 0(a2)531; CHECK-NEXT: psub.w a1, a1, a2532; CHECK-NEXT: sd a1, 0(a0)533; CHECK-NEXT: ret534 %a = load <2 x i32>, ptr %a_ptr535 %b = load <2 x i32>, ptr %b_ptr536 %res = sub <2 x i32> %a, %b537 store <2 x i32> %res, ptr %ret_ptr538 ret void539}540 541; Test saturating add operations for v2i32 (RV64 only)542define void @test_psadd_w(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {543; CHECK-LABEL: test_psadd_w:544; CHECK: # %bb.0:545; CHECK-NEXT: ld a1, 0(a1)546; CHECK-NEXT: ld a2, 0(a2)547; CHECK-NEXT: psadd.w a1, a1, a2548; CHECK-NEXT: sd a1, 0(a0)549; CHECK-NEXT: ret550 %a = load <2 x i32>, ptr %a_ptr551 %b = load <2 x i32>, ptr %b_ptr552 %res = call <2 x i32> @llvm.sadd.sat.v2i32(<2 x i32> %a, <2 x i32> %b)553 store <2 x i32> %res, ptr %ret_ptr554 ret void555}556 557define void @test_psaddu_w(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {558; CHECK-LABEL: test_psaddu_w:559; CHECK: # %bb.0:560; CHECK-NEXT: ld a1, 0(a1)561; CHECK-NEXT: ld a2, 0(a2)562; CHECK-NEXT: psaddu.w a1, a1, a2563; CHECK-NEXT: sd a1, 0(a0)564; CHECK-NEXT: ret565 %a = load <2 x i32>, ptr %a_ptr566 %b = load <2 x i32>, ptr %b_ptr567 %res = call <2 x i32> @llvm.uadd.sat.v2i32(<2 x i32> %a, <2 x i32> %b)568 store <2 x i32> %res, ptr %ret_ptr569 ret void570}571 572; Test saturating sub operations for v2i32 (RV64 only)573define void @test_pssub_w(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {574; CHECK-LABEL: test_pssub_w:575; CHECK: # %bb.0:576; CHECK-NEXT: ld a1, 0(a1)577; CHECK-NEXT: ld a2, 0(a2)578; CHECK-NEXT: pssub.w a1, a1, a2579; CHECK-NEXT: sd a1, 0(a0)580; CHECK-NEXT: ret581 %a = load <2 x i32>, ptr %a_ptr582 %b = load <2 x i32>, ptr %b_ptr583 %res = call <2 x i32> @llvm.ssub.sat.v2i32(<2 x i32> %a, <2 x i32> %b)584 store <2 x i32> %res, ptr %ret_ptr585 ret void586}587 588define void @test_pssubu_w(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {589; CHECK-LABEL: test_pssubu_w:590; CHECK: # %bb.0:591; CHECK-NEXT: ld a1, 0(a1)592; CHECK-NEXT: ld a2, 0(a2)593; CHECK-NEXT: pssubu.w a1, a1, a2594; CHECK-NEXT: sd a1, 0(a0)595; CHECK-NEXT: ret596 %a = load <2 x i32>, ptr %a_ptr597 %b = load <2 x i32>, ptr %b_ptr598 %res = call <2 x i32> @llvm.usub.sat.v2i32(<2 x i32> %a, <2 x i32> %b)599 store <2 x i32> %res, ptr %ret_ptr600 ret void601}602 603; Test averaging floor signed operations for v2i32 (RV64 only)604; avgfloors pattern: (a + b) arithmetic shift right 1605define void @test_paadd_w(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {606; CHECK-LABEL: test_paadd_w:607; CHECK: # %bb.0:608; CHECK-NEXT: ld a1, 0(a1)609; CHECK-NEXT: ld a2, 0(a2)610; CHECK-NEXT: paadd.w a1, a1, a2611; CHECK-NEXT: sd a1, 0(a0)612; CHECK-NEXT: ret613 %a = load <2 x i32>, ptr %a_ptr614 %b = load <2 x i32>, ptr %b_ptr615 %ext.a = sext <2 x i32> %a to <2 x i64>616 %ext.b = sext <2 x i32> %b to <2 x i64>617 %add = add nsw <2 x i64> %ext.a, %ext.b618 %shift = ashr <2 x i64> %add, <i64 1, i64 1>619 %res = trunc <2 x i64> %shift to <2 x i32>620 store <2 x i32> %res, ptr %ret_ptr621 ret void622}623 624; Test averaging floor unsigned operations for v2i32 (RV64 only)625; avgflooru pattern: (a & b) + ((a ^ b) >> 1)626define void @test_paaddu_w(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {627; CHECK-LABEL: test_paaddu_w:628; CHECK: # %bb.0:629; CHECK-NEXT: ld a1, 0(a1)630; CHECK-NEXT: ld a2, 0(a2)631; CHECK-NEXT: paaddu.w a1, a1, a2632; CHECK-NEXT: sd a1, 0(a0)633; CHECK-NEXT: ret634 %a = load <2 x i32>, ptr %a_ptr635 %b = load <2 x i32>, ptr %b_ptr636 %and = and <2 x i32> %a, %b637 %xor = xor <2 x i32> %a, %b638 %shift = lshr <2 x i32> %xor, <i32 1, i32 1>639 %res = add <2 x i32> %and, %shift640 store <2 x i32> %res, ptr %ret_ptr641 ret void642}643 644; Test averaging floor subtraction signed for v2i32 (RV64 only)645; pasub pattern: (a - b) arithmetic shift right 1646define void @test_pasub_w(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {647; CHECK-LABEL: test_pasub_w:648; CHECK: # %bb.0:649; CHECK-NEXT: ld a1, 0(a1)650; CHECK-NEXT: ld a2, 0(a2)651; CHECK-NEXT: pasub.w a1, a1, a2652; CHECK-NEXT: sd a1, 0(a0)653; CHECK-NEXT: ret654 %a = load <2 x i32>, ptr %a_ptr655 %b = load <2 x i32>, ptr %b_ptr656 %a_ext = sext <2 x i32> %a to <2 x i64>657 %b_ext = sext <2 x i32> %b to <2 x i64>658 %sub = sub <2 x i64> %a_ext, %b_ext659 %res = ashr <2 x i64> %sub, <i64 1, i64 1>660 %res_trunc = trunc <2 x i64> %res to <2 x i32>661 store <2 x i32> %res_trunc, ptr %ret_ptr662 ret void663}664 665; Test averaging floor subtraction unsigned for v2i32 (RV64 only)666; pasubu pattern: (a - b) logical shift right 1667define void @test_pasubu_w(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {668; CHECK-LABEL: test_pasubu_w:669; CHECK: # %bb.0:670; CHECK-NEXT: ld a1, 0(a1)671; CHECK-NEXT: ld a2, 0(a2)672; CHECK-NEXT: pasubu.w a1, a1, a2673; CHECK-NEXT: sd a1, 0(a0)674; CHECK-NEXT: ret675 %a = load <2 x i32>, ptr %a_ptr676 %b = load <2 x i32>, ptr %b_ptr677 %a_ext = zext <2 x i32> %a to <2 x i64>678 %b_ext = zext <2 x i32> %b to <2 x i64>679 %sub = sub <2 x i64> %a_ext, %b_ext680 %res = lshr <2 x i64> %sub, <i64 1, i64 1>681 %res_trunc = trunc <2 x i64> %res to <2 x i32>682 store <2 x i32> %res_trunc, ptr %ret_ptr683 ret void684}685 686; Test for splat687define void @test_non_const_splat_i32(ptr %ret_ptr, ptr %a_ptr, i32 %elt) {688; CHECK-LABEL: test_non_const_splat_i32:689; CHECK: # %bb.0:690; CHECK-NEXT: padd.ws a1, zero, a2691; CHECK-NEXT: sd a1, 0(a0)692; CHECK-NEXT: ret693 %a = load <2 x i32>, ptr %a_ptr694 %insert = insertelement <2 x i32> poison, i32 %elt, i32 0695 %splat = shufflevector <2 x i32> %insert, <2 x i32> poison, <2 x i32> zeroinitializer696 store <2 x i32> %splat, ptr %ret_ptr697 ret void698}699 700define void @test_build_vector_i8(ptr %ret_ptr, i8 %a, i8 %b, i8 %c, i8 %d, i8 %e, i8 %f, i8 %g, i8 %h) {701; CHECK-LABEL: test_build_vector_i8:702; CHECK: # %bb.0:703; CHECK-NEXT: lbu t0, 0(sp)704; CHECK-NEXT: ppack.h a5, a5, a6705; CHECK-NEXT: ppack.h a3, a3, a4706; CHECK-NEXT: ppack.h a1, a1, a2707; CHECK-NEXT: ppack.h a2, a7, t0708; CHECK-NEXT: ppack.w a2, a5, a2709; CHECK-NEXT: ppack.w a1, a1, a3710; CHECK-NEXT: pack a1, a1, a2711; CHECK-NEXT: sd a1, 0(a0)712; CHECK-NEXT: ret713 %v0 = insertelement <8 x i8> poison, i8 %a, i32 0714 %v1 = insertelement <8 x i8> %v0, i8 %b, i32 1715 %v2 = insertelement <8 x i8> %v1, i8 %c, i32 2716 %v3 = insertelement <8 x i8> %v2, i8 %d, i32 3717 %v4 = insertelement <8 x i8> %v3, i8 %e, i32 4718 %v5 = insertelement <8 x i8> %v4, i8 %f, i32 5719 %v6 = insertelement <8 x i8> %v5, i8 %g, i32 6720 %v7 = insertelement <8 x i8> %v6, i8 %h, i32 7721 store <8 x i8> %v7, ptr %ret_ptr722 ret void723}724 725define void @test_build_vector_i16(ptr %ret_ptr, i16 %a, i16 %b, i16 %c, i16 %d) {726; CHECK-LABEL: test_build_vector_i16:727; CHECK: # %bb.0:728; CHECK-NEXT: ppack.w a3, a3, a4729; CHECK-NEXT: ppack.w a1, a1, a2730; CHECK-NEXT: pack a1, a1, a3731; CHECK-NEXT: sd a1, 0(a0)732; CHECK-NEXT: ret733 %v0 = insertelement <4 x i16> poison, i16 %a, i32 0734 %v1 = insertelement <4 x i16> %v0, i16 %b, i32 1735 %v2 = insertelement <4 x i16> %v1, i16 %c, i32 2736 %v3 = insertelement <4 x i16> %v2, i16 %d, i32 3737 store <4 x i16> %v3, ptr %ret_ptr738 ret void739}740 741define void @test_build_vector_i32(ptr %ret_ptr, i32 %a, i32 %b) {742; CHECK-LABEL: test_build_vector_i32:743; CHECK: # %bb.0:744; CHECK-NEXT: pack a1, a1, a2745; CHECK-NEXT: sd a1, 0(a0)746; CHECK-NEXT: ret747 %v0 = insertelement <2 x i32> poison, i32 %a, i32 0748 %v1 = insertelement <2 x i32> %v0, i32 %b, i32 1749 store <2 x i32> %v1, ptr %ret_ptr750 ret void751}752 753; Test logical shift left immediate for v4i16754define void @test_pslli_h(ptr %ret_ptr, ptr %a_ptr) {755; CHECK-LABEL: test_pslli_h:756; CHECK: # %bb.0:757; CHECK-NEXT: ld a1, 0(a1)758; CHECK-NEXT: pslli.h a1, a1, 2759; CHECK-NEXT: sd a1, 0(a0)760; CHECK-NEXT: ret761 %a = load <4 x i16>, ptr %a_ptr762 %res = shl <4 x i16> %a, splat(i16 2)763 store <4 x i16> %res, ptr %ret_ptr764 ret void765}766 767; Test logical shift left immediate for v8i8768define void @test_pslli_b(ptr %ret_ptr, ptr %a_ptr) {769; CHECK-LABEL: test_pslli_b:770; CHECK: # %bb.0:771; CHECK-NEXT: ld a1, 0(a1)772; CHECK-NEXT: pslli.b a1, a1, 2773; CHECK-NEXT: sd a1, 0(a0)774; CHECK-NEXT: ret775 %a = load <8 x i8>, ptr %a_ptr776 %res = shl <8 x i8> %a, splat(i8 2)777 store <8 x i8> %res, ptr %ret_ptr778 ret void779}780 781; Test logical shift left immediate for v2i32782define void @test_pslli_w(ptr %ret_ptr, ptr %a_ptr) {783; CHECK-LABEL: test_pslli_w:784; CHECK: # %bb.0:785; CHECK-NEXT: ld a1, 0(a1)786; CHECK-NEXT: pslli.w a1, a1, 2787; CHECK-NEXT: sd a1, 0(a0)788; CHECK-NEXT: ret789 %a = load <2 x i32>, ptr %a_ptr790 %res = shl <2 x i32> %a, splat(i32 2)791 store <2 x i32> %res, ptr %ret_ptr792 ret void793}794 795; Test arithmetic saturation shift left immediate for v2i32796define void @test_psslai_w(ptr %ret_ptr, ptr %a_ptr) {797; CHECK-LABEL: test_psslai_w:798; CHECK: # %bb.0:799; CHECK-NEXT: ld a1, 0(a1)800; CHECK-NEXT: psslai.w a1, a1, 2801; CHECK-NEXT: sd a1, 0(a0)802; CHECK-NEXT: ret803 %a = load <2 x i32>, ptr %a_ptr804 %res = call <2 x i32> @llvm.sshl.sat.v2i32(<2 x i32> %a, <2 x i32> splat(i32 2))805 store <2 x i32> %res, ptr %ret_ptr806 ret void807}808