490 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=riscv32 -mattr=+v -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,RV323; RUN: llc -mtriple=riscv64 -mattr=+v -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,RV644 5define void @splat_v16i8(ptr %x, i8 %y) {6; CHECK-LABEL: splat_v16i8:7; CHECK: # %bb.0:8; CHECK-NEXT: vsetivli zero, 16, e8, m1, ta, ma9; CHECK-NEXT: vmv.v.x v8, a110; CHECK-NEXT: vse8.v v8, (a0)11; CHECK-NEXT: ret12 %a = insertelement <16 x i8> poison, i8 %y, i32 013 %b = shufflevector <16 x i8> %a, <16 x i8> poison, <16 x i32> zeroinitializer14 store <16 x i8> %b, ptr %x15 ret void16}17 18define void @splat_v8i16(ptr %x, i16 %y) {19; CHECK-LABEL: splat_v8i16:20; CHECK: # %bb.0:21; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma22; CHECK-NEXT: vmv.v.x v8, a123; CHECK-NEXT: vse16.v v8, (a0)24; CHECK-NEXT: ret25 %a = insertelement <8 x i16> poison, i16 %y, i32 026 %b = shufflevector <8 x i16> %a, <8 x i16> poison, <8 x i32> zeroinitializer27 store <8 x i16> %b, ptr %x28 ret void29}30 31define void @splat_v4i32(ptr %x, i32 %y) {32; CHECK-LABEL: splat_v4i32:33; CHECK: # %bb.0:34; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma35; CHECK-NEXT: vmv.v.x v8, a136; CHECK-NEXT: vse32.v v8, (a0)37; CHECK-NEXT: ret38 %a = insertelement <4 x i32> poison, i32 %y, i32 039 %b = shufflevector <4 x i32> %a, <4 x i32> poison, <4 x i32> zeroinitializer40 store <4 x i32> %b, ptr %x41 ret void42}43 44define void @splat_v2i64(ptr %x, i64 %y) {45; RV32-LABEL: splat_v2i64:46; RV32: # %bb.0:47; RV32-NEXT: addi sp, sp, -1648; RV32-NEXT: .cfi_def_cfa_offset 1649; RV32-NEXT: sw a1, 8(sp)50; RV32-NEXT: sw a2, 12(sp)51; RV32-NEXT: addi a1, sp, 852; RV32-NEXT: vsetivli zero, 2, e64, m1, ta, ma53; RV32-NEXT: vlse64.v v8, (a1), zero54; RV32-NEXT: vse64.v v8, (a0)55; RV32-NEXT: addi sp, sp, 1656; RV32-NEXT: .cfi_def_cfa_offset 057; RV32-NEXT: ret58;59; RV64-LABEL: splat_v2i64:60; RV64: # %bb.0:61; RV64-NEXT: vsetivli zero, 2, e64, m1, ta, ma62; RV64-NEXT: vmv.v.x v8, a163; RV64-NEXT: vse64.v v8, (a0)64; RV64-NEXT: ret65 %a = insertelement <2 x i64> poison, i64 %y, i32 066 %b = shufflevector <2 x i64> %a, <2 x i64> poison, <2 x i32> zeroinitializer67 store <2 x i64> %b, ptr %x68 ret void69}70 71define void @splat_v32i8(ptr %x, i8 %y) {72; CHECK-LABEL: splat_v32i8:73; CHECK: # %bb.0:74; CHECK-NEXT: li a2, 3275; CHECK-NEXT: vsetvli zero, a2, e8, m2, ta, ma76; CHECK-NEXT: vmv.v.x v8, a177; CHECK-NEXT: vse8.v v8, (a0)78; CHECK-NEXT: ret79 %a = insertelement <32 x i8> poison, i8 %y, i32 080 %b = shufflevector <32 x i8> %a, <32 x i8> poison, <32 x i32> zeroinitializer81 store <32 x i8> %b, ptr %x82 ret void83}84 85define void @splat_v16i16(ptr %x, i16 %y) {86; CHECK-LABEL: splat_v16i16:87; CHECK: # %bb.0:88; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma89; CHECK-NEXT: vmv.v.x v8, a190; CHECK-NEXT: vse16.v v8, (a0)91; CHECK-NEXT: ret92 %a = insertelement <16 x i16> poison, i16 %y, i32 093 %b = shufflevector <16 x i16> %a, <16 x i16> poison, <16 x i32> zeroinitializer94 store <16 x i16> %b, ptr %x95 ret void96}97 98define void @splat_v8i32(ptr %x, i32 %y) {99; CHECK-LABEL: splat_v8i32:100; CHECK: # %bb.0:101; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma102; CHECK-NEXT: vmv.v.x v8, a1103; CHECK-NEXT: vse32.v v8, (a0)104; CHECK-NEXT: ret105 %a = insertelement <8 x i32> poison, i32 %y, i32 0106 %b = shufflevector <8 x i32> %a, <8 x i32> poison, <8 x i32> zeroinitializer107 store <8 x i32> %b, ptr %x108 ret void109}110 111define void @splat_v4i64(ptr %x, i64 %y) {112; RV32-LABEL: splat_v4i64:113; RV32: # %bb.0:114; RV32-NEXT: addi sp, sp, -16115; RV32-NEXT: .cfi_def_cfa_offset 16116; RV32-NEXT: sw a1, 8(sp)117; RV32-NEXT: sw a2, 12(sp)118; RV32-NEXT: addi a1, sp, 8119; RV32-NEXT: vsetivli zero, 4, e64, m2, ta, ma120; RV32-NEXT: vlse64.v v8, (a1), zero121; RV32-NEXT: vse64.v v8, (a0)122; RV32-NEXT: addi sp, sp, 16123; RV32-NEXT: .cfi_def_cfa_offset 0124; RV32-NEXT: ret125;126; RV64-LABEL: splat_v4i64:127; RV64: # %bb.0:128; RV64-NEXT: vsetivli zero, 4, e64, m2, ta, ma129; RV64-NEXT: vmv.v.x v8, a1130; RV64-NEXT: vse64.v v8, (a0)131; RV64-NEXT: ret132 %a = insertelement <4 x i64> poison, i64 %y, i32 0133 %b = shufflevector <4 x i64> %a, <4 x i64> poison, <4 x i32> zeroinitializer134 store <4 x i64> %b, ptr %x135 ret void136}137 138define void @splat_zero_v16i8(ptr %x) {139; CHECK-LABEL: splat_zero_v16i8:140; CHECK: # %bb.0:141; CHECK-NEXT: vsetivli zero, 16, e8, m1, ta, ma142; CHECK-NEXT: vmv.v.i v8, 0143; CHECK-NEXT: vse8.v v8, (a0)144; CHECK-NEXT: ret145 store <16 x i8> splat (i8 0), ptr %x146 ret void147}148 149define void @splat_zero_v8i16(ptr %x) {150; CHECK-LABEL: splat_zero_v8i16:151; CHECK: # %bb.0:152; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma153; CHECK-NEXT: vmv.v.i v8, 0154; CHECK-NEXT: vse16.v v8, (a0)155; CHECK-NEXT: ret156 store <8 x i16> splat (i16 0), ptr %x157 ret void158}159 160define void @splat_zero_v4i32(ptr %x) {161; CHECK-LABEL: splat_zero_v4i32:162; CHECK: # %bb.0:163; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma164; CHECK-NEXT: vmv.v.i v8, 0165; CHECK-NEXT: vse32.v v8, (a0)166; CHECK-NEXT: ret167 store <4 x i32> splat (i32 0), ptr %x168 ret void169}170 171define void @splat_zero_v2i64(ptr %x) {172; CHECK-LABEL: splat_zero_v2i64:173; CHECK: # %bb.0:174; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma175; CHECK-NEXT: vmv.v.i v8, 0176; CHECK-NEXT: vse64.v v8, (a0)177; CHECK-NEXT: ret178 store <2 x i64> splat (i64 0), ptr %x179 ret void180}181 182define void @splat_zero_v32i8(ptr %x) {183; CHECK-LABEL: splat_zero_v32i8:184; CHECK: # %bb.0:185; CHECK-NEXT: li a1, 32186; CHECK-NEXT: vsetvli zero, a1, e8, m2, ta, ma187; CHECK-NEXT: vmv.v.i v8, 0188; CHECK-NEXT: vse8.v v8, (a0)189; CHECK-NEXT: ret190 store <32 x i8> splat (i8 0), ptr %x191 ret void192}193 194define void @splat_zero_v16i16(ptr %x) {195; CHECK-LABEL: splat_zero_v16i16:196; CHECK: # %bb.0:197; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma198; CHECK-NEXT: vmv.v.i v8, 0199; CHECK-NEXT: vse16.v v8, (a0)200; CHECK-NEXT: ret201 store <16 x i16> splat (i16 0), ptr %x202 ret void203}204 205define void @splat_zero_v8i32(ptr %x) {206; CHECK-LABEL: splat_zero_v8i32:207; CHECK: # %bb.0:208; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma209; CHECK-NEXT: vmv.v.i v8, 0210; CHECK-NEXT: vse32.v v8, (a0)211; CHECK-NEXT: ret212 store <8 x i32> splat (i32 0), ptr %x213 ret void214}215 216define void @splat_zero_v4i64(ptr %x) {217; CHECK-LABEL: splat_zero_v4i64:218; CHECK: # %bb.0:219; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma220; CHECK-NEXT: vmv.v.i v8, 0221; CHECK-NEXT: vse64.v v8, (a0)222; CHECK-NEXT: ret223 store <4 x i64> splat (i64 0), ptr %x224 ret void225}226 227define void @splat_zero_v2i16(ptr %p) {228; CHECK-LABEL: splat_zero_v2i16:229; CHECK: # %bb.0:230; CHECK-NEXT: sw zero, 0(a0)231; CHECK-NEXT: ret232 store <2 x i16> zeroinitializer, ptr %p233 ret void234}235 236define void @splat_zero_v2i16_unaligned(ptr %p) {237; CHECK-LABEL: splat_zero_v2i16_unaligned:238; CHECK: # %bb.0:239; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma240; CHECK-NEXT: vmv.v.i v8, 0241; CHECK-NEXT: vsetivli zero, 4, e8, mf4, ta, ma242; CHECK-NEXT: vse8.v v8, (a0)243; CHECK-NEXT: ret244 store <2 x i16> zeroinitializer, ptr %p, align 1245 ret void246}247 248define void @splat_zero_v4i16(ptr %p) {249; RV32-LABEL: splat_zero_v4i16:250; RV32: # %bb.0:251; RV32-NEXT: vsetivli zero, 4, e16, mf2, ta, ma252; RV32-NEXT: vmv.v.i v8, 0253; RV32-NEXT: vse16.v v8, (a0)254; RV32-NEXT: ret255;256; RV64-LABEL: splat_zero_v4i16:257; RV64: # %bb.0:258; RV64-NEXT: sd zero, 0(a0)259; RV64-NEXT: ret260 store <4 x i16> zeroinitializer, ptr %p261 ret void262}263 264define void @splat_zero_v2i32(ptr %p) {265; RV32-LABEL: splat_zero_v2i32:266; RV32: # %bb.0:267; RV32-NEXT: vsetivli zero, 2, e32, mf2, ta, ma268; RV32-NEXT: vmv.v.i v8, 0269; RV32-NEXT: vse32.v v8, (a0)270; RV32-NEXT: ret271;272; RV64-LABEL: splat_zero_v2i32:273; RV64: # %bb.0:274; RV64-NEXT: sd zero, 0(a0)275; RV64-NEXT: ret276 store <2 x i32> zeroinitializer, ptr %p277 ret void278}279 280; Not a power of two and requires more than two scalar stores.281define void @splat_zero_v7i16(ptr %p) {282; CHECK-LABEL: splat_zero_v7i16:283; CHECK: # %bb.0:284; CHECK-NEXT: vsetivli zero, 7, e16, m1, ta, ma285; CHECK-NEXT: vmv.v.i v8, 0286; CHECK-NEXT: vse16.v v8, (a0)287; CHECK-NEXT: ret288 store <7 x i16> zeroinitializer, ptr %p289 ret void290}291 292define void @splat_allones_v16i8(ptr %x) {293; CHECK-LABEL: splat_allones_v16i8:294; CHECK: # %bb.0:295; CHECK-NEXT: vsetivli zero, 16, e8, m1, ta, ma296; CHECK-NEXT: vmv.v.i v8, -1297; CHECK-NEXT: vse8.v v8, (a0)298; CHECK-NEXT: ret299 store <16 x i8> splat (i8 -1), ptr %x300 ret void301}302 303define void @splat_allones_v8i16(ptr %x) {304; CHECK-LABEL: splat_allones_v8i16:305; CHECK: # %bb.0:306; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma307; CHECK-NEXT: vmv.v.i v8, -1308; CHECK-NEXT: vse16.v v8, (a0)309; CHECK-NEXT: ret310 store <8 x i16> splat (i16 -1), ptr %x311 ret void312}313 314define void @splat_allones_v4i32(ptr %x) {315; CHECK-LABEL: splat_allones_v4i32:316; CHECK: # %bb.0:317; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma318; CHECK-NEXT: vmv.v.i v8, -1319; CHECK-NEXT: vse32.v v8, (a0)320; CHECK-NEXT: ret321 store <4 x i32> splat (i32 -1), ptr %x322 ret void323}324 325define void @splat_allones_v2i64(ptr %x) {326; CHECK-LABEL: splat_allones_v2i64:327; CHECK: # %bb.0:328; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma329; CHECK-NEXT: vmv.v.i v8, -1330; CHECK-NEXT: vse64.v v8, (a0)331; CHECK-NEXT: ret332 store <2 x i64> splat (i64 -1), ptr %x333 ret void334}335 336define void @splat_allones_v32i8(ptr %x) {337; CHECK-LABEL: splat_allones_v32i8:338; CHECK: # %bb.0:339; CHECK-NEXT: li a1, 32340; CHECK-NEXT: vsetvli zero, a1, e8, m2, ta, ma341; CHECK-NEXT: vmv.v.i v8, -1342; CHECK-NEXT: vse8.v v8, (a0)343; CHECK-NEXT: ret344 store <32 x i8> splat (i8 -1), ptr %x345 ret void346}347 348define void @splat_allones_v16i16(ptr %x) {349; CHECK-LABEL: splat_allones_v16i16:350; CHECK: # %bb.0:351; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma352; CHECK-NEXT: vmv.v.i v8, -1353; CHECK-NEXT: vse16.v v8, (a0)354; CHECK-NEXT: ret355 store <16 x i16> splat (i16 -1), ptr %x356 ret void357}358 359define void @splat_allones_v8i32(ptr %x) {360; CHECK-LABEL: splat_allones_v8i32:361; CHECK: # %bb.0:362; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma363; CHECK-NEXT: vmv.v.i v8, -1364; CHECK-NEXT: vse32.v v8, (a0)365; CHECK-NEXT: ret366 store <8 x i32> splat (i32 -1), ptr %x367 ret void368}369 370define void @splat_allones_v4i64(ptr %x) {371; CHECK-LABEL: splat_allones_v4i64:372; CHECK: # %bb.0:373; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma374; CHECK-NEXT: vmv.v.i v8, -1375; CHECK-NEXT: vse64.v v8, (a0)376; CHECK-NEXT: ret377 store <4 x i64> splat (i64 -1), ptr %x378 ret void379}380 381; This requires a bitcast on RV32 due to type legalization rewriting the382; build_vector to v8i32.383; FIXME: We should prevent this and use the implicit sign extension of vmv.v.x384; with SEW=64 on RV32.385define void @splat_allones_with_use_v4i64(ptr %x) {386; CHECK-LABEL: splat_allones_with_use_v4i64:387; CHECK: # %bb.0:388; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma389; CHECK-NEXT: vle64.v v8, (a0)390; CHECK-NEXT: vadd.vi v8, v8, -1391; CHECK-NEXT: vse64.v v8, (a0)392; CHECK-NEXT: ret393 %a = load <4 x i64>, ptr %x394 %b = add <4 x i64> %a, <i64 -1, i64 -1, i64 -1, i64 -1>395 store <4 x i64> %b, ptr %x396 ret void397}398 399; This test used to crash at LMUL=8 when inserting a v16i64 subvector into400; nxv8i64 at index 0: the v16i64 type was used to get the LMUL, the size of401; which exceeded maximum-expected size of 512. The scalable container type of402; nxv8i64 should have been used instead.403define void @vadd_vx_v16i64(ptr %a, i64 %b, ptr %c) {404; RV32-LABEL: vadd_vx_v16i64:405; RV32: # %bb.0:406; RV32-NEXT: addi sp, sp, -16407; RV32-NEXT: .cfi_def_cfa_offset 16408; RV32-NEXT: vsetivli zero, 16, e64, m8, ta, ma409; RV32-NEXT: vle64.v v8, (a0)410; RV32-NEXT: sw a1, 8(sp)411; RV32-NEXT: sw a2, 12(sp)412; RV32-NEXT: addi a0, sp, 8413; RV32-NEXT: vlse64.v v16, (a0), zero414; RV32-NEXT: vadd.vv v8, v8, v16415; RV32-NEXT: vse64.v v8, (a3)416; RV32-NEXT: addi sp, sp, 16417; RV32-NEXT: .cfi_def_cfa_offset 0418; RV32-NEXT: ret419;420; RV64-LABEL: vadd_vx_v16i64:421; RV64: # %bb.0:422; RV64-NEXT: vsetivli zero, 16, e64, m8, ta, ma423; RV64-NEXT: vle64.v v8, (a0)424; RV64-NEXT: vadd.vx v8, v8, a1425; RV64-NEXT: vse64.v v8, (a2)426; RV64-NEXT: ret427 %va = load <16 x i64>, ptr %a428 %head = insertelement <16 x i64> poison, i64 %b, i32 0429 %splat = shufflevector <16 x i64> %head, <16 x i64> poison, <16 x i32> zeroinitializer430 %vc = add <16 x i64> %va, %splat431 store <16 x i64> %vc, ptr %c432 ret void433}434 435define <2 x i64> @vadd_vx_v2i64_to_sub(<2 x i64> %va) {436; RV32-LABEL: vadd_vx_v2i64_to_sub:437; RV32: # %bb.0:438; RV32-NEXT: addi sp, sp, -16439; RV32-NEXT: .cfi_def_cfa_offset 16440; RV32-NEXT: li a0, -256441; RV32-NEXT: li a1, 1442; RV32-NEXT: sw a1, 8(sp)443; RV32-NEXT: sw a0, 12(sp)444; RV32-NEXT: addi a0, sp, 8445; RV32-NEXT: vsetivli zero, 2, e64, m1, ta, ma446; RV32-NEXT: vlse64.v v9, (a0), zero447; RV32-NEXT: vadd.vv v8, v8, v9448; RV32-NEXT: addi sp, sp, 16449; RV32-NEXT: .cfi_def_cfa_offset 0450; RV32-NEXT: ret451;452; RV64-LABEL: vadd_vx_v2i64_to_sub:453; RV64: # %bb.0:454; RV64-NEXT: li a0, -1455; RV64-NEXT: srli a0, a0, 24456; RV64-NEXT: vsetivli zero, 2, e64, m1, ta, ma457; RV64-NEXT: vsub.vx v8, v8, a0458; RV64-NEXT: ret459 %v = add <2 x i64> splat (i64 -1099511627775), %va460 ret <2 x i64> %v461}462 463define <2 x i64> @vadd_vx_v2i64_to_sub_swapped(<2 x i64> %va) {464; RV32-LABEL: vadd_vx_v2i64_to_sub_swapped:465; RV32: # %bb.0:466; RV32-NEXT: addi sp, sp, -16467; RV32-NEXT: .cfi_def_cfa_offset 16468; RV32-NEXT: li a0, -256469; RV32-NEXT: li a1, 1470; RV32-NEXT: sw a1, 8(sp)471; RV32-NEXT: sw a0, 12(sp)472; RV32-NEXT: addi a0, sp, 8473; RV32-NEXT: vsetivli zero, 2, e64, m1, ta, ma474; RV32-NEXT: vlse64.v v9, (a0), zero475; RV32-NEXT: vadd.vv v8, v8, v9476; RV32-NEXT: addi sp, sp, 16477; RV32-NEXT: .cfi_def_cfa_offset 0478; RV32-NEXT: ret479;480; RV64-LABEL: vadd_vx_v2i64_to_sub_swapped:481; RV64: # %bb.0:482; RV64-NEXT: li a0, -1483; RV64-NEXT: srli a0, a0, 24484; RV64-NEXT: vsetivli zero, 2, e64, m1, ta, ma485; RV64-NEXT: vsub.vx v8, v8, a0486; RV64-NEXT: ret487 %v = add <2 x i64> %va, splat (i64 -1099511627775)488 ret <2 x i64> %v489}490