588 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 22; RUN: llc -mtriple=riscv32 -mattr=+v,+zvfh -verify-machineinstrs < %s | FileCheck %s -check-prefixes=CHECK,CHECK-NO-MISALIGN,RV323; RUN: llc -mtriple=riscv64 -mattr=+v,+zvfh -verify-machineinstrs < %s | FileCheck %s -check-prefixes=CHECK,CHECK-NO-MISALIGN,RV644; RUN: llc -mtriple=riscv64 -mattr=+v,+zvfh,+unaligned-vector-mem -verify-machineinstrs < %s | FileCheck %s -check-prefixes=CHECK,RV64,RV64-MISALIGN5 6; RUN: llc -mtriple=riscv64 -mattr=+f,+zfh,+zve64f,+zvl128b,+zvfh -verify-machineinstrs < %s | FileCheck %s -check-prefixes=CHECK,CHECK-NO-MISALIGN,ZVE64F7 8; The two loads are contigous and should be folded into one9define void @widen_2xv4i16(ptr %x, ptr %z) {10; CHECK-LABEL: widen_2xv4i16:11; CHECK: # %bb.0:12; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma13; CHECK-NEXT: vle64.v v8, (a0)14; CHECK-NEXT: vse64.v v8, (a1)15; CHECK-NEXT: ret16 %a = load <4 x i16>, ptr %x17 %b.gep = getelementptr i8, ptr %x, i64 818 %b = load <4 x i16>, ptr %b.gep19 %c = shufflevector <4 x i16> %a, <4 x i16> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>20 store <8 x i16> %c, ptr %z21 ret void22}23 24define void @widen_3xv4i16(ptr %x, ptr %z) {25; CHECK-LABEL: widen_3xv4i16:26; CHECK: # %bb.0:27; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma28; CHECK-NEXT: vle16.v v8, (a0)29; CHECK-NEXT: addi a2, a0, 830; CHECK-NEXT: vle16.v v9, (a2)31; CHECK-NEXT: addi a0, a0, 1632; CHECK-NEXT: vle16.v v10, (a0)33; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma34; CHECK-NEXT: vslideup.vi v8, v9, 435; CHECK-NEXT: vsetivli zero, 12, e16, m2, ta, ma36; CHECK-NEXT: vslideup.vi v8, v10, 837; CHECK-NEXT: vse16.v v8, (a1)38; CHECK-NEXT: ret39 %a = load <4 x i16>, ptr %x40 %b.gep = getelementptr i8, ptr %x, i64 841 %b = load <4 x i16>, ptr %b.gep42 %c.gep = getelementptr i8, ptr %b.gep, i64 843 %c = load <4 x i16>, ptr %c.gep44 %d.0 = shufflevector <4 x i16> %a, <4 x i16> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>45 %d.1 = shufflevector <4 x i16> %c, <4 x i16> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison>46 %d.2 = shufflevector <8 x i16> %d.0, <8 x i16> %d.1, <12 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11>47 store <12 x i16> %d.2, ptr %z48 ret void49}50 51define void @widen_4xv4i16(ptr %x, ptr %z) {52; CHECK-LABEL: widen_4xv4i16:53; CHECK: # %bb.0:54; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma55; CHECK-NEXT: vle64.v v8, (a0)56; CHECK-NEXT: vse64.v v8, (a1)57; CHECK-NEXT: ret58 %a = load <4 x i16>, ptr %x59 %b.gep = getelementptr i8, ptr %x, i64 860 %b = load <4 x i16>, ptr %b.gep61 %c.gep = getelementptr i8, ptr %b.gep, i64 862 %c = load <4 x i16>, ptr %c.gep63 %d.gep = getelementptr i8, ptr %c.gep, i64 864 %d = load <4 x i16>, ptr %d.gep65 %e.0 = shufflevector <4 x i16> %a, <4 x i16> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>66 %e.1 = shufflevector <4 x i16> %c, <4 x i16> %d, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>67 %e.2 = shufflevector <8 x i16> %e.0, <8 x i16> %e.1, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>68 store <16 x i16> %e.2, ptr %z69 ret void70}71 72define void @widen_4xv4i16_unaligned(ptr %x, ptr %z) {73; CHECK-NO-MISALIGN-LABEL: widen_4xv4i16_unaligned:74; CHECK-NO-MISALIGN: # %bb.0:75; CHECK-NO-MISALIGN-NEXT: vsetivli zero, 8, e16, m1, ta, ma76; CHECK-NO-MISALIGN-NEXT: vle8.v v8, (a0)77; CHECK-NO-MISALIGN-NEXT: addi a2, a0, 1678; CHECK-NO-MISALIGN-NEXT: vle8.v v10, (a2)79; CHECK-NO-MISALIGN-NEXT: addi a2, a0, 880; CHECK-NO-MISALIGN-NEXT: addi a0, a0, 2481; CHECK-NO-MISALIGN-NEXT: vle8.v v9, (a0)82; CHECK-NO-MISALIGN-NEXT: vle8.v v11, (a2)83; CHECK-NO-MISALIGN-NEXT: vslideup.vi v10, v9, 484; CHECK-NO-MISALIGN-NEXT: vslideup.vi v8, v11, 485; CHECK-NO-MISALIGN-NEXT: vsetivli zero, 16, e16, m2, ta, ma86; CHECK-NO-MISALIGN-NEXT: vslideup.vi v8, v10, 887; CHECK-NO-MISALIGN-NEXT: vse16.v v8, (a1)88; CHECK-NO-MISALIGN-NEXT: ret89;90; RV64-MISALIGN-LABEL: widen_4xv4i16_unaligned:91; RV64-MISALIGN: # %bb.0:92; RV64-MISALIGN-NEXT: vsetivli zero, 4, e64, m2, ta, ma93; RV64-MISALIGN-NEXT: vle64.v v8, (a0)94; RV64-MISALIGN-NEXT: vse64.v v8, (a1)95; RV64-MISALIGN-NEXT: ret96 %a = load <4 x i16>, ptr %x, align 197 %b.gep = getelementptr i8, ptr %x, i64 898 %b = load <4 x i16>, ptr %b.gep, align 199 %c.gep = getelementptr i8, ptr %b.gep, i64 8100 %c = load <4 x i16>, ptr %c.gep, align 1101 %d.gep = getelementptr i8, ptr %c.gep, i64 8102 %d = load <4 x i16>, ptr %d.gep, align 1103 %e.0 = shufflevector <4 x i16> %a, <4 x i16> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>104 %e.1 = shufflevector <4 x i16> %c, <4 x i16> %d, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>105 %e.2 = shufflevector <8 x i16> %e.0, <8 x i16> %e.1, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>106 store <16 x i16> %e.2, ptr %z107 ret void108}109 110; Should be a strided load - with type coercion to i64111define void @strided_constant(ptr %x, ptr %z) {112; CHECK-LABEL: strided_constant:113; CHECK: # %bb.0:114; CHECK-NEXT: li a2, 16115; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma116; CHECK-NEXT: vlse64.v v8, (a0), a2117; CHECK-NEXT: vse64.v v8, (a1)118; CHECK-NEXT: ret119 %a = load <4 x i16>, ptr %x120 %b.gep = getelementptr i8, ptr %x, i64 16121 %b = load <4 x i16>, ptr %b.gep122 %c = shufflevector <4 x i16> %a, <4 x i16> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>123 store <8 x i16> %c, ptr %z124 ret void125}126 127; Should be a strided load128define void @strided_constant_64(ptr %x, ptr %z) {129; CHECK-LABEL: strided_constant_64:130; CHECK: # %bb.0:131; CHECK-NEXT: li a2, 64132; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma133; CHECK-NEXT: vlse64.v v8, (a0), a2134; CHECK-NEXT: vse64.v v8, (a1)135; CHECK-NEXT: ret136 %a = load <4 x i16>, ptr %x137 %b.gep = getelementptr i8, ptr %x, i64 64138 %b = load <4 x i16>, ptr %b.gep139 %c = shufflevector <4 x i16> %a, <4 x i16> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>140 store <8 x i16> %c, ptr %z141 ret void142}143 144; Vector is too large to fit into a single strided load145define void @strided_constant_v4i32(ptr %x, ptr %z) {146; CHECK-LABEL: strided_constant_v4i32:147; CHECK: # %bb.0:148; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma149; CHECK-NEXT: vle32.v v8, (a0)150; CHECK-NEXT: addi a0, a0, 32151; CHECK-NEXT: vle32.v v10, (a0)152; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma153; CHECK-NEXT: vslideup.vi v8, v10, 4154; CHECK-NEXT: vse32.v v8, (a1)155; CHECK-NEXT: ret156 %a = load <4 x i32>, ptr %x157 %b.gep = getelementptr i8, ptr %x, i64 32158 %b = load <4 x i32>, ptr %b.gep159 %c = shufflevector <4 x i32> %a, <4 x i32> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>160 store <8 x i32> %c, ptr %z161 ret void162}163 164; Interestingly, can be a stride 0 load165define void @strided_constant_0(ptr %x, ptr %z) {166; CHECK-LABEL: strided_constant_0:167; CHECK: # %bb.0:168; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma169; CHECK-NEXT: vle16.v v8, (a0)170; CHECK-NEXT: vmv1r.v v9, v8171; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma172; CHECK-NEXT: vslideup.vi v9, v8, 4173; CHECK-NEXT: vse16.v v9, (a1)174; CHECK-NEXT: ret175 %a = load <4 x i16>, ptr %x176 %b = load <4 x i16>, ptr %x177 %c = shufflevector <4 x i16> %a, <4 x i16> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>178 store <8 x i16> %c, ptr %z179 ret void180}181 182; Stride isn't consistent, so shouldn't be combined183define void @strided_constant_mismatch_4xv4i16(ptr %x, ptr %z) {184; CHECK-LABEL: strided_constant_mismatch_4xv4i16:185; CHECK: # %bb.0:186; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma187; CHECK-NEXT: vle16.v v8, (a0)188; CHECK-NEXT: addi a2, a0, 6189; CHECK-NEXT: vle16.v v10, (a2)190; CHECK-NEXT: addi a2, a0, 2191; CHECK-NEXT: addi a0, a0, 8192; CHECK-NEXT: vle16.v v9, (a0)193; CHECK-NEXT: vle16.v v11, (a2)194; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma195; CHECK-NEXT: vslideup.vi v10, v9, 4196; CHECK-NEXT: vslideup.vi v8, v11, 4197; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma198; CHECK-NEXT: vslideup.vi v8, v10, 8199; CHECK-NEXT: vse16.v v8, (a1)200; CHECK-NEXT: ret201 %a = load <4 x i16>, ptr %x202 %b.gep = getelementptr i8, ptr %x, i64 2203 %b = load <4 x i16>, ptr %b.gep204 %c.gep = getelementptr i8, ptr %b.gep, i64 4205 %c = load <4 x i16>, ptr %c.gep206 %d.gep = getelementptr i8, ptr %c.gep, i64 2207 %d = load <4 x i16>, ptr %d.gep208 %e.0 = shufflevector <4 x i16> %a, <4 x i16> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>209 %e.1 = shufflevector <4 x i16> %c, <4 x i16> %d, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>210 %e.2 = shufflevector <8 x i16> %e.0, <8 x i16> %e.1, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>211 store <16 x i16> %e.2, ptr %z212 ret void213}214 215define void @strided_runtime(ptr %x, ptr %z, i64 %s) {216; CHECK-LABEL: strided_runtime:217; CHECK: # %bb.0:218; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma219; CHECK-NEXT: vlse64.v v8, (a0), a2220; CHECK-NEXT: vse64.v v8, (a1)221; CHECK-NEXT: ret222 %a = load <4 x i16>, ptr %x223 %b.gep = getelementptr i8, ptr %x, i64 %s224 %b = load <4 x i16>, ptr %b.gep225 %c = shufflevector <4 x i16> %a, <4 x i16> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>226 store <8 x i16> %c, ptr %z227 ret void228}229 230define void @strided_runtime_4xv4i16(ptr %x, ptr %z, i64 %s) {231; CHECK-LABEL: strided_runtime_4xv4i16:232; CHECK: # %bb.0:233; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma234; CHECK-NEXT: vlse64.v v8, (a0), a2235; CHECK-NEXT: vse64.v v8, (a1)236; CHECK-NEXT: ret237 %a = load <4 x i16>, ptr %x238 %b.gep = getelementptr i8, ptr %x, i64 %s239 %b = load <4 x i16>, ptr %b.gep240 %c.gep = getelementptr i8, ptr %b.gep, i64 %s241 %c = load <4 x i16>, ptr %c.gep242 %d.gep = getelementptr i8, ptr %c.gep, i64 %s243 %d = load <4 x i16>, ptr %d.gep244 %e.0 = shufflevector <4 x i16> %a, <4 x i16> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>245 %e.1 = shufflevector <4 x i16> %c, <4 x i16> %d, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>246 %e.2 = shufflevector <8 x i16> %e.0, <8 x i16> %e.1, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>247 store <16 x i16> %e.2, ptr %z248 ret void249}250 251; Stride isn't consistent, so shouldn't be combined252define void @strided_runtime_mismatch_4xv4i16(ptr %x, ptr %z, i64 %s, i64 %t) {253; RV32-LABEL: strided_runtime_mismatch_4xv4i16:254; RV32: # %bb.0:255; RV32-NEXT: vsetivli zero, 4, e16, mf2, ta, ma256; RV32-NEXT: vle16.v v8, (a0)257; RV32-NEXT: add a0, a0, a2258; RV32-NEXT: add a4, a0, a4259; RV32-NEXT: vle16.v v10, (a4)260; RV32-NEXT: add a2, a4, a2261; RV32-NEXT: vle16.v v9, (a2)262; RV32-NEXT: vle16.v v11, (a0)263; RV32-NEXT: vsetivli zero, 8, e16, m1, ta, ma264; RV32-NEXT: vslideup.vi v10, v9, 4265; RV32-NEXT: vslideup.vi v8, v11, 4266; RV32-NEXT: vsetivli zero, 16, e16, m2, ta, ma267; RV32-NEXT: vslideup.vi v8, v10, 8268; RV32-NEXT: vse16.v v8, (a1)269; RV32-NEXT: ret270;271; RV64-LABEL: strided_runtime_mismatch_4xv4i16:272; RV64: # %bb.0:273; RV64-NEXT: vsetivli zero, 4, e16, mf2, ta, ma274; RV64-NEXT: vle16.v v8, (a0)275; RV64-NEXT: add a0, a0, a2276; RV64-NEXT: add a3, a0, a3277; RV64-NEXT: vle16.v v10, (a3)278; RV64-NEXT: add a2, a3, a2279; RV64-NEXT: vle16.v v9, (a2)280; RV64-NEXT: vle16.v v11, (a0)281; RV64-NEXT: vsetivli zero, 8, e16, m1, ta, ma282; RV64-NEXT: vslideup.vi v10, v9, 4283; RV64-NEXT: vslideup.vi v8, v11, 4284; RV64-NEXT: vsetivli zero, 16, e16, m2, ta, ma285; RV64-NEXT: vslideup.vi v8, v10, 8286; RV64-NEXT: vse16.v v8, (a1)287; RV64-NEXT: ret288;289; ZVE64F-LABEL: strided_runtime_mismatch_4xv4i16:290; ZVE64F: # %bb.0:291; ZVE64F-NEXT: vsetivli zero, 4, e16, mf2, ta, ma292; ZVE64F-NEXT: vle16.v v8, (a0)293; ZVE64F-NEXT: add a0, a0, a2294; ZVE64F-NEXT: add a3, a0, a3295; ZVE64F-NEXT: vle16.v v10, (a3)296; ZVE64F-NEXT: add a2, a3, a2297; ZVE64F-NEXT: vle16.v v9, (a2)298; ZVE64F-NEXT: vle16.v v11, (a0)299; ZVE64F-NEXT: vsetivli zero, 8, e16, m1, ta, ma300; ZVE64F-NEXT: vslideup.vi v10, v9, 4301; ZVE64F-NEXT: vslideup.vi v8, v11, 4302; ZVE64F-NEXT: vsetivli zero, 16, e16, m2, ta, ma303; ZVE64F-NEXT: vslideup.vi v8, v10, 8304; ZVE64F-NEXT: vse16.v v8, (a1)305; ZVE64F-NEXT: ret306 %a = load <4 x i16>, ptr %x307 %b.gep = getelementptr i8, ptr %x, i64 %s308 %b = load <4 x i16>, ptr %b.gep309 %c.gep = getelementptr i8, ptr %b.gep, i64 %t310 %c = load <4 x i16>, ptr %c.gep311 %d.gep = getelementptr i8, ptr %c.gep, i64 %s312 %d = load <4 x i16>, ptr %d.gep313 %e.0 = shufflevector <4 x i16> %a, <4 x i16> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>314 %e.1 = shufflevector <4 x i16> %c, <4 x i16> %d, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>315 %e.2 = shufflevector <8 x i16> %e.0, <8 x i16> %e.1, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>316 store <16 x i16> %e.2, ptr %z317 ret void318}319 320define void @strided_runtime_4xv4f16(ptr %x, ptr %z, i64 %s) {321; CHECK-LABEL: strided_runtime_4xv4f16:322; CHECK: # %bb.0:323; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma324; CHECK-NEXT: vlse64.v v8, (a0), a2325; CHECK-NEXT: vse64.v v8, (a1)326; CHECK-NEXT: ret327 %a = load <4 x half>, ptr %x328 %b.gep = getelementptr i8, ptr %x, i64 %s329 %b = load <4 x half>, ptr %b.gep330 %c.gep = getelementptr i8, ptr %b.gep, i64 %s331 %c = load <4 x half>, ptr %c.gep332 %d.gep = getelementptr i8, ptr %c.gep, i64 %s333 %d = load <4 x half>, ptr %d.gep334 %e.0 = shufflevector <4 x half> %a, <4 x half> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>335 %e.1 = shufflevector <4 x half> %c, <4 x half> %d, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>336 %e.2 = shufflevector <8 x half> %e.0, <8 x half> %e.1, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>337 store <16 x half> %e.2, ptr %z338 ret void339}340 341define void @strided_runtime_4xv2f32(ptr %x, ptr %z, i64 %s) {342; CHECK-LABEL: strided_runtime_4xv2f32:343; CHECK: # %bb.0:344; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma345; CHECK-NEXT: vlse64.v v8, (a0), a2346; CHECK-NEXT: vse64.v v8, (a1)347; CHECK-NEXT: ret348 %a = load <2 x float>, ptr %x349 %b.gep = getelementptr i8, ptr %x, i64 %s350 %b = load <2 x float>, ptr %b.gep351 %c.gep = getelementptr i8, ptr %b.gep, i64 %s352 %c = load <2 x float>, ptr %c.gep353 %d.gep = getelementptr i8, ptr %c.gep, i64 %s354 %d = load <2 x float>, ptr %d.gep355 %e.0 = shufflevector <2 x float> %a, <2 x float> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 3>356 %e.1 = shufflevector <2 x float> %c, <2 x float> %d, <4 x i32> <i32 0, i32 1, i32 2, i32 3>357 %e.2 = shufflevector <4 x float> %e.0, <4 x float> %e.1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>358 store <8 x float> %e.2, ptr %z359 ret void360}361 362define void @strided_unaligned(ptr %x, ptr %z, i64 %s) {363; CHECK-NO-MISALIGN-LABEL: strided_unaligned:364; CHECK-NO-MISALIGN: # %bb.0:365; CHECK-NO-MISALIGN-NEXT: vsetivli zero, 8, e16, m1, ta, ma366; CHECK-NO-MISALIGN-NEXT: vle8.v v8, (a0)367; CHECK-NO-MISALIGN-NEXT: add a0, a0, a2368; CHECK-NO-MISALIGN-NEXT: vle8.v v9, (a0)369; CHECK-NO-MISALIGN-NEXT: vslideup.vi v8, v9, 4370; CHECK-NO-MISALIGN-NEXT: vse16.v v8, (a1)371; CHECK-NO-MISALIGN-NEXT: ret372;373; RV64-MISALIGN-LABEL: strided_unaligned:374; RV64-MISALIGN: # %bb.0:375; RV64-MISALIGN-NEXT: vsetivli zero, 2, e64, m1, ta, ma376; RV64-MISALIGN-NEXT: vlse64.v v8, (a0), a2377; RV64-MISALIGN-NEXT: vse64.v v8, (a1)378; RV64-MISALIGN-NEXT: ret379 %a = load <4 x i16>, ptr %x, align 1380 %b.gep = getelementptr i8, ptr %x, i64 %s381 %b = load <4 x i16>, ptr %b.gep, align 1382 %c = shufflevector <4 x i16> %a, <4 x i16> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>383 store <8 x i16> %c, ptr %z384 ret void385}386 387; Should use the most restrictive common alignment388define void @strided_mismatched_alignments(ptr %x, ptr %z, i64 %s) {389; CHECK-LABEL: strided_mismatched_alignments:390; CHECK: # %bb.0:391; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma392; CHECK-NEXT: vlse64.v v8, (a0), a2393; CHECK-NEXT: vse64.v v8, (a1)394; CHECK-NEXT: ret395 %a = load <4 x i16>, ptr %x, align 8396 %b.gep = getelementptr i8, ptr %x, i64 %s397 %b = load <4 x i16>, ptr %b.gep, align 16398 %c = shufflevector <4 x i16> %a, <4 x i16> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>399 store <8 x i16> %c, ptr %z400 ret void401}402 403define void @strided_ok_alignments_8(ptr %x, ptr %z, i64 %s) {404; CHECK-LABEL: strided_ok_alignments_8:405; CHECK: # %bb.0:406; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma407; CHECK-NEXT: vlse64.v v8, (a0), a2408; CHECK-NEXT: vse64.v v8, (a1)409; CHECK-NEXT: ret410 %a = load <4 x i16>, ptr %x, align 8411 %b.gep = getelementptr i8, ptr %x, i64 %s412 %b = load <4 x i16>, ptr %b.gep, align 8413 %c = shufflevector <4 x i16> %a, <4 x i16> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>414 store <8 x i16> %c, ptr %z415 ret void416}417 418define void @strided_ok_alignments_16(ptr %x, ptr %z, i64 %s) {419; CHECK-LABEL: strided_ok_alignments_16:420; CHECK: # %bb.0:421; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma422; CHECK-NEXT: vlse64.v v8, (a0), a2423; CHECK-NEXT: vse64.v v8, (a1)424; CHECK-NEXT: ret425 %a = load <4 x i16>, ptr %x, align 16426 %b.gep = getelementptr i8, ptr %x, i64 %s427 %b = load <4 x i16>, ptr %b.gep, align 16428 %c = shufflevector <4 x i16> %a, <4 x i16> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>429 store <8 x i16> %c, ptr %z430 ret void431}432 433; Shouldn't be combined because one of the loads is not simple434define void @strided_non_simple_load(ptr %x, ptr %z, i64 %s) {435; CHECK-LABEL: strided_non_simple_load:436; CHECK: # %bb.0:437; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma438; CHECK-NEXT: vle16.v v8, (a0)439; CHECK-NEXT: add a0, a0, a2440; CHECK-NEXT: vle16.v v9, (a0)441; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma442; CHECK-NEXT: vslideup.vi v8, v9, 4443; CHECK-NEXT: vse16.v v8, (a1)444; CHECK-NEXT: ret445 %a = load <4 x i16>, ptr %x446 %b.gep = getelementptr i8, ptr %x, i64 %s447 %b = load volatile <4 x i16>, ptr %b.gep448 %c = shufflevector <4 x i16> %a, <4 x i16> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>449 store <8 x i16> %c, ptr %z450 ret void451}452 453; Shouldn't be combined because one of the operands is not a load454define void @strided_non_load(ptr %x, ptr %z, <4 x i16> %b) {455; CHECK-LABEL: strided_non_load:456; CHECK: # %bb.0:457; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma458; CHECK-NEXT: vle16.v v9, (a0)459; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma460; CHECK-NEXT: vslideup.vi v9, v8, 4461; CHECK-NEXT: vse16.v v9, (a1)462; CHECK-NEXT: ret463 %a = load <4 x i16>, ptr %x464 %c = shufflevector <4 x i16> %a, <4 x i16> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>465 store <8 x i16> %c, ptr %z466 ret void467}468 469define void @strided_constant_neg_4xv2f32(ptr %x, ptr %z, i64 %s) {470; CHECK-LABEL: strided_constant_neg_4xv2f32:471; CHECK: # %bb.0:472; CHECK-NEXT: li a2, -64473; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma474; CHECK-NEXT: vlse64.v v8, (a0), a2475; CHECK-NEXT: vse64.v v8, (a1)476; CHECK-NEXT: ret477 %a = load <2 x float>, ptr %x478 %b.gep = getelementptr i8, ptr %x, i64 -64479 %b = load <2 x float>, ptr %b.gep480 %c.gep = getelementptr i8, ptr %b.gep, i64 -64481 %c = load <2 x float>, ptr %c.gep482 %d.gep = getelementptr i8, ptr %c.gep, i64 -64483 %d = load <2 x float>, ptr %d.gep484 %e.0 = shufflevector <2 x float> %a, <2 x float> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 3>485 %e.1 = shufflevector <2 x float> %c, <2 x float> %d, <4 x i32> <i32 0, i32 1, i32 2, i32 3>486 %e.2 = shufflevector <4 x float> %e.0, <4 x float> %e.1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>487 store <8 x float> %e.2, ptr %z488 ret void489}490 491; This is a strided load with a negative stride492define void @reverse_strided_constant_pos_4xv2f32(ptr %x, ptr %z, i64 %s) {493; CHECK-LABEL: reverse_strided_constant_pos_4xv2f32:494; CHECK: # %bb.0:495; CHECK-NEXT: addi a0, a0, 192496; CHECK-NEXT: li a2, -64497; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma498; CHECK-NEXT: vlse64.v v8, (a0), a2499; CHECK-NEXT: vse64.v v8, (a1)500; CHECK-NEXT: ret501 %x.1 = getelementptr i8, ptr %x, i64 64502 %x.2 = getelementptr i8, ptr %x.1, i64 64503 %x.3 = getelementptr i8, ptr %x.2, i64 64504 %a = load <2 x float>, ptr %x.3505 %b = load <2 x float>, ptr %x.2506 %c = load <2 x float>, ptr %x.1507 %d = load <2 x float>, ptr %x508 %e.0 = shufflevector <2 x float> %a, <2 x float> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 3>509 %e.1 = shufflevector <2 x float> %c, <2 x float> %d, <4 x i32> <i32 0, i32 1, i32 2, i32 3>510 %e.2 = shufflevector <4 x float> %e.0, <4 x float> %e.1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>511 store <8 x float> %e.2, ptr %z512 ret void513}514 515define void @reverse_strided_constant_neg_4xv2f32(ptr %x, ptr %z, i64 %s) {516; CHECK-LABEL: reverse_strided_constant_neg_4xv2f32:517; CHECK: # %bb.0:518; CHECK-NEXT: addi a0, a0, -192519; CHECK-NEXT: li a2, 64520; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma521; CHECK-NEXT: vlse64.v v8, (a0), a2522; CHECK-NEXT: vse64.v v8, (a1)523; CHECK-NEXT: ret524 %x.1 = getelementptr i8, ptr %x, i64 -64525 %x.2 = getelementptr i8, ptr %x.1, i64 -64526 %x.3 = getelementptr i8, ptr %x.2, i64 -64527 %a = load <2 x float>, ptr %x.3528 %b = load <2 x float>, ptr %x.2529 %c = load <2 x float>, ptr %x.1530 %d = load <2 x float>, ptr %x531 %e.0 = shufflevector <2 x float> %a, <2 x float> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 3>532 %e.1 = shufflevector <2 x float> %c, <2 x float> %d, <4 x i32> <i32 0, i32 1, i32 2, i32 3>533 %e.2 = shufflevector <4 x float> %e.0, <4 x float> %e.1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>534 store <8 x float> %e.2, ptr %z535 ret void536}537 538; This is a strided load with a negative stride539define void @reverse_strided_runtime_4xv2f32(ptr %x, ptr %z, i64 %s) {540; CHECK-LABEL: reverse_strided_runtime_4xv2f32:541; CHECK: # %bb.0:542; CHECK-NEXT: add a0, a0, a2543; CHECK-NEXT: add a3, a2, a2544; CHECK-NEXT: add a0, a0, a3545; CHECK-NEXT: neg a2, a2546; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma547; CHECK-NEXT: vlse64.v v8, (a0), a2548; CHECK-NEXT: vse64.v v8, (a1)549; CHECK-NEXT: ret550 %x.1 = getelementptr i8, ptr %x, i64 %s551 %x.2 = getelementptr i8, ptr %x.1, i64 %s552 %x.3 = getelementptr i8, ptr %x.2, i64 %s553 %a = load <2 x float>, ptr %x.3554 %b = load <2 x float>, ptr %x.2555 %c = load <2 x float>, ptr %x.1556 %d = load <2 x float>, ptr %x557 %e.0 = shufflevector <2 x float> %a, <2 x float> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 3>558 %e.1 = shufflevector <2 x float> %c, <2 x float> %d, <4 x i32> <i32 0, i32 1, i32 2, i32 3>559 %e.2 = shufflevector <4 x float> %e.0, <4 x float> %e.1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>560 store <8 x float> %e.2, ptr %z561 ret void562}563 564; The middle end sometimes produces this pattern of shuffles, where the565; intermediate shuffles are the full result vector size padded with poison566; elements.567define <16 x i8> @widen_4xv4i8_immediate_expand(ptr %p, i64 %s) {568; CHECK-LABEL: widen_4xv4i8_immediate_expand:569; CHECK: # %bb.0:570; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma571; CHECK-NEXT: vlse32.v v8, (a0), a1572; CHECK-NEXT: ret573 %a = load <4 x i8>, ptr %p574 %b.ptr = getelementptr i8, ptr %p, i64 %s575 %b = load <4 x i8>, ptr %b.ptr576 %c.ptr = getelementptr i8, ptr %b.ptr, i64 %s577 %c = load <4 x i8>, ptr %c.ptr578 %d.ptr = getelementptr i8, ptr %c.ptr, i64 %s579 %d = load <4 x i8>, ptr %d.ptr580 581 %ab = shufflevector <4 x i8> %a, <4 x i8> %b, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>582 %cx = shufflevector <4 x i8> %c, <4 x i8> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>583 %dx = shufflevector <4 x i8> %d, <4 x i8> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>584 %abcx = shufflevector <16 x i8> %ab, <16 x i8> %cx, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 16, i32 17, i32 18, i32 19, i32 poison, i32 poison, i32 poison, i32 poison>585 %abcd = shufflevector <16 x i8> %abcx, <16 x i8> %dx, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 16, i32 17, i32 18, i32 19>586 ret <16 x i8> %abcd587}588