341 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=thumbv8.1m.main-none-none-eabi -mattr=+mve.fp %s -o - | FileCheck %s3 4define arm_aapcs_vfpcc <4 x i32> @zext_scaled_i16_i32(ptr %base, ptr %offptr) {5; CHECK-LABEL: zext_scaled_i16_i32:6; CHECK: @ %bb.0: @ %entry7; CHECK-NEXT: vldrw.u32 q1, [r1]8; CHECK-NEXT: vldrh.u32 q0, [r0, q1, uxtw #1]9; CHECK-NEXT: bx lr10entry:11 %offs = load <4 x i32>, ptr %offptr, align 412 %ptrs = getelementptr inbounds i16, ptr %base, <4 x i32> %offs13 %gather = call <4 x i16> @llvm.masked.gather.v4i16.v4p0(<4 x ptr> %ptrs, i32 2, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i16> undef)14 %gather.zext = zext <4 x i16> %gather to <4 x i32>15 ret <4 x i32> %gather.zext16}17 18define arm_aapcs_vfpcc <4 x i32> @sext_scaled_i16_i32(ptr %base, ptr %offptr) {19; CHECK-LABEL: sext_scaled_i16_i32:20; CHECK: @ %bb.0: @ %entry21; CHECK-NEXT: vldrw.u32 q1, [r1]22; CHECK-NEXT: vldrh.s32 q0, [r0, q1, uxtw #1]23; CHECK-NEXT: bx lr24entry:25 %offs = load <4 x i32>, ptr %offptr, align 426 %ptrs = getelementptr inbounds i16, ptr %base, <4 x i32> %offs27 %gather = call <4 x i16> @llvm.masked.gather.v4i16.v4p0(<4 x ptr> %ptrs, i32 2, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i16> undef)28 %gather.sext = sext <4 x i16> %gather to <4 x i32>29 ret <4 x i32> %gather.sext30}31 32define arm_aapcs_vfpcc <4 x i32> @scaled_i32_i32(ptr %base, ptr %offptr) {33; CHECK-LABEL: scaled_i32_i32:34; CHECK: @ %bb.0: @ %entry35; CHECK-NEXT: vldrw.u32 q1, [r1]36; CHECK-NEXT: vldrw.u32 q0, [r0, q1, uxtw #2]37; CHECK-NEXT: bx lr38entry:39 %offs = load <4 x i32>, ptr %offptr, align 440 %ptrs = getelementptr inbounds i32, ptr %base, <4 x i32> %offs41 %gather = call <4 x i32> @llvm.masked.gather.v4i32.v4p0(<4 x ptr> %ptrs, i32 4, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i32> undef)42 ret <4 x i32> %gather43}44 45; TODO: scaled_f16_i3246 47define arm_aapcs_vfpcc <4 x float> @scaled_f32_i32(ptr %base, ptr %offptr) {48; CHECK-LABEL: scaled_f32_i32:49; CHECK: @ %bb.0: @ %entry50; CHECK-NEXT: vldrw.u32 q1, [r1]51; CHECK-NEXT: vldrw.u32 q0, [r0, q1, uxtw #2]52; CHECK-NEXT: bx lr53entry:54 %offs = load <4 x i32>, ptr %offptr, align 455 %i32_ptrs = getelementptr inbounds i32, ptr %base, <4 x i32> %offs56 %ptrs = bitcast <4 x ptr> %i32_ptrs to <4 x ptr>57 %gather = call <4 x float> @llvm.masked.gather.v4f32.v4p0(<4 x ptr> %ptrs, i32 4, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x float> undef)58 ret <4 x float> %gather59}60 61define arm_aapcs_vfpcc <4 x i32> @unsigned_scaled_b_i32_i16(ptr %base, ptr %offptr) {62; CHECK-LABEL: unsigned_scaled_b_i32_i16:63; CHECK: @ %bb.0: @ %entry64; CHECK-NEXT: vldrh.u32 q1, [r1]65; CHECK-NEXT: vldrw.u32 q0, [r0, q1, uxtw #2]66; CHECK-NEXT: bx lr67entry:68 %offs = load <4 x i16>, ptr %offptr, align 269 %offs.zext = zext <4 x i16> %offs to <4 x i32>70 %ptrs = getelementptr inbounds i32, ptr %base, <4 x i32> %offs.zext71 %gather = call <4 x i32> @llvm.masked.gather.v4i32.v4p0(<4 x ptr> %ptrs, i32 4, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i32> undef)72 ret <4 x i32> %gather73}74 75define arm_aapcs_vfpcc <4 x i32> @signed_scaled_i32_i16(ptr %base, ptr %offptr) {76; CHECK-LABEL: signed_scaled_i32_i16:77; CHECK: @ %bb.0: @ %entry78; CHECK-NEXT: vldrh.s32 q1, [r1]79; CHECK-NEXT: vldrw.u32 q0, [r0, q1, uxtw #2]80; CHECK-NEXT: bx lr81entry:82 %offs = load <4 x i16>, ptr %offptr, align 283 %offs.sext = sext <4 x i16> %offs to <4 x i32>84 %ptrs = getelementptr inbounds i32, ptr %base, <4 x i32> %offs.sext85 %gather = call <4 x i32> @llvm.masked.gather.v4i32.v4p0(<4 x ptr> %ptrs, i32 4, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i32> undef)86 ret <4 x i32> %gather87}88 89define arm_aapcs_vfpcc <4 x float> @a_unsigned_scaled_f32_i16(ptr %base, ptr %offptr) {90; CHECK-LABEL: a_unsigned_scaled_f32_i16:91; CHECK: @ %bb.0: @ %entry92; CHECK-NEXT: vldrh.u32 q1, [r1]93; CHECK-NEXT: vldrw.u32 q0, [r0, q1, uxtw #2]94; CHECK-NEXT: bx lr95entry:96 %offs = load <4 x i16>, ptr %offptr, align 297 %offs.zext = zext <4 x i16> %offs to <4 x i32>98 %i32_ptrs = getelementptr inbounds i32, ptr %base, <4 x i32> %offs.zext99 %ptrs = bitcast <4 x ptr> %i32_ptrs to <4 x ptr>100 %gather = call <4 x float> @llvm.masked.gather.v4f32.v4p0(<4 x ptr> %ptrs, i32 4, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x float> undef)101 ret <4 x float> %gather102}103 104define arm_aapcs_vfpcc <4 x float> @b_signed_scaled_f32_i16(ptr %base, ptr %offptr) {105; CHECK-LABEL: b_signed_scaled_f32_i16:106; CHECK: @ %bb.0: @ %entry107; CHECK-NEXT: vldrh.s32 q1, [r1]108; CHECK-NEXT: vldrw.u32 q0, [r0, q1, uxtw #2]109; CHECK-NEXT: bx lr110entry:111 %offs = load <4 x i16>, ptr %offptr, align 2112 %offs.sext = sext <4 x i16> %offs to <4 x i32>113 %i32_ptrs = getelementptr inbounds i32, ptr %base, <4 x i32> %offs.sext114 %ptrs = bitcast <4 x ptr> %i32_ptrs to <4 x ptr>115 %gather = call <4 x float> @llvm.masked.gather.v4f32.v4p0(<4 x ptr> %ptrs, i32 4, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x float> undef)116 ret <4 x float> %gather117}118 119define arm_aapcs_vfpcc <4 x i32> @zext_signed_scaled_i16_i16(ptr %base, ptr %offptr) {120; CHECK-LABEL: zext_signed_scaled_i16_i16:121; CHECK: @ %bb.0: @ %entry122; CHECK-NEXT: vldrh.s32 q1, [r1]123; CHECK-NEXT: vldrh.u32 q0, [r0, q1, uxtw #1]124; CHECK-NEXT: bx lr125entry:126 %offs = load <4 x i16>, ptr %offptr, align 2127 %offs.sext = sext <4 x i16> %offs to <4 x i32>128 %ptrs = getelementptr inbounds i16, ptr %base, <4 x i32> %offs.sext129 %gather = call <4 x i16> @llvm.masked.gather.v4i16.v4p0(<4 x ptr> %ptrs, i32 2, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i16> undef)130 %gather.zext = zext <4 x i16> %gather to <4 x i32>131 ret <4 x i32> %gather.zext132}133 134define arm_aapcs_vfpcc <4 x i32> @sext_signed_scaled_i16_i16(ptr %base, ptr %offptr) {135; CHECK-LABEL: sext_signed_scaled_i16_i16:136; CHECK: @ %bb.0: @ %entry137; CHECK-NEXT: vldrh.s32 q1, [r1]138; CHECK-NEXT: vldrh.s32 q0, [r0, q1, uxtw #1]139; CHECK-NEXT: bx lr140entry:141 %offs = load <4 x i16>, ptr %offptr, align 2142 %offs.sext = sext <4 x i16> %offs to <4 x i32>143 %ptrs = getelementptr inbounds i16, ptr %base, <4 x i32> %offs.sext144 %gather = call <4 x i16> @llvm.masked.gather.v4i16.v4p0(<4 x ptr> %ptrs, i32 2, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i16> undef)145 %gather.sext = sext <4 x i16> %gather to <4 x i32>146 ret <4 x i32> %gather.sext147}148 149define arm_aapcs_vfpcc <4 x i32> @zext_unsigned_scaled_i16_i16(ptr %base, ptr %offptr) {150; CHECK-LABEL: zext_unsigned_scaled_i16_i16:151; CHECK: @ %bb.0: @ %entry152; CHECK-NEXT: vldrh.u32 q1, [r1]153; CHECK-NEXT: vldrh.u32 q0, [r0, q1, uxtw #1]154; CHECK-NEXT: bx lr155entry:156 %offs = load <4 x i16>, ptr %offptr, align 2157 %offs.zext = zext <4 x i16> %offs to <4 x i32>158 %ptrs = getelementptr inbounds i16, ptr %base, <4 x i32> %offs.zext159 %gather = call <4 x i16> @llvm.masked.gather.v4i16.v4p0(<4 x ptr> %ptrs, i32 2, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i16> undef)160 %gather.zext = zext <4 x i16> %gather to <4 x i32>161 ret <4 x i32> %gather.zext162}163 164define arm_aapcs_vfpcc <4 x i32> @sext_unsigned_scaled_i16_i16(ptr %base, ptr %offptr) {165; CHECK-LABEL: sext_unsigned_scaled_i16_i16:166; CHECK: @ %bb.0: @ %entry167; CHECK-NEXT: vldrh.u32 q1, [r1]168; CHECK-NEXT: vldrh.s32 q0, [r0, q1, uxtw #1]169; CHECK-NEXT: bx lr170entry:171 %offs = load <4 x i16>, ptr %offptr, align 2172 %offs.zext = zext <4 x i16> %offs to <4 x i32>173 %ptrs = getelementptr inbounds i16, ptr %base, <4 x i32> %offs.zext174 %gather = call <4 x i16> @llvm.masked.gather.v4i16.v4p0(<4 x ptr> %ptrs, i32 2, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i16> undef)175 %gather.sext = sext <4 x i16> %gather to <4 x i32>176 ret <4 x i32> %gather.sext177}178 179define arm_aapcs_vfpcc <4 x i32> @unsigned_scaled_b_i32_i8(ptr %base, ptr %offptr) {180; CHECK-LABEL: unsigned_scaled_b_i32_i8:181; CHECK: @ %bb.0: @ %entry182; CHECK-NEXT: vldrb.u32 q1, [r1]183; CHECK-NEXT: vldrw.u32 q0, [r0, q1, uxtw #2]184; CHECK-NEXT: bx lr185entry:186 %offs = load <4 x i8>, ptr %offptr, align 1187 %offs.zext = zext <4 x i8> %offs to <4 x i32>188 %ptrs = getelementptr inbounds i32, ptr %base, <4 x i32> %offs.zext189 %gather = call <4 x i32> @llvm.masked.gather.v4i32.v4p0(<4 x ptr> %ptrs, i32 4, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i32> undef)190 ret <4 x i32> %gather191}192 193define arm_aapcs_vfpcc <4 x i32> @signed_scaled_i32_i8(ptr %base, ptr %offptr) {194; CHECK-LABEL: signed_scaled_i32_i8:195; CHECK: @ %bb.0: @ %entry196; CHECK-NEXT: vldrb.s32 q1, [r1]197; CHECK-NEXT: vldrw.u32 q0, [r0, q1, uxtw #2]198; CHECK-NEXT: bx lr199entry:200 %offs = load <4 x i8>, ptr %offptr, align 1201 %offs.sext = sext <4 x i8> %offs to <4 x i32>202 %ptrs = getelementptr inbounds i32, ptr %base, <4 x i32> %offs.sext203 %gather = call <4 x i32> @llvm.masked.gather.v4i32.v4p0(<4 x ptr> %ptrs, i32 4, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i32> undef)204 ret <4 x i32> %gather205}206 207define arm_aapcs_vfpcc <4 x float> @a_unsigned_scaled_f32_i8(ptr %base, ptr %offptr) {208; CHECK-LABEL: a_unsigned_scaled_f32_i8:209; CHECK: @ %bb.0: @ %entry210; CHECK-NEXT: vldrb.u32 q1, [r1]211; CHECK-NEXT: vldrw.u32 q0, [r0, q1, uxtw #2]212; CHECK-NEXT: bx lr213entry:214 %offs = load <4 x i8>, ptr %offptr, align 1215 %offs.zext = zext <4 x i8> %offs to <4 x i32>216 %i32_ptrs = getelementptr inbounds i32, ptr %base, <4 x i32> %offs.zext217 %ptrs = bitcast <4 x ptr> %i32_ptrs to <4 x ptr>218 %gather = call <4 x float> @llvm.masked.gather.v4f32.v4p0(<4 x ptr> %ptrs, i32 4, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x float> undef)219 ret <4 x float> %gather220}221 222define arm_aapcs_vfpcc <4 x float> @b_signed_scaled_f32_i8(ptr %base, ptr %offptr) {223; CHECK-LABEL: b_signed_scaled_f32_i8:224; CHECK: @ %bb.0: @ %entry225; CHECK-NEXT: vldrb.s32 q1, [r1]226; CHECK-NEXT: vldrw.u32 q0, [r0, q1, uxtw #2]227; CHECK-NEXT: bx lr228entry:229 %offs = load <4 x i8>, ptr %offptr, align 1230 %offs.sext = sext <4 x i8> %offs to <4 x i32>231 %i32_ptrs = getelementptr inbounds i32, ptr %base, <4 x i32> %offs.sext232 %ptrs = bitcast <4 x ptr> %i32_ptrs to <4 x ptr>233 %gather = call <4 x float> @llvm.masked.gather.v4f32.v4p0(<4 x ptr> %ptrs, i32 4, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x float> undef)234 ret <4 x float> %gather235}236 237define arm_aapcs_vfpcc <4 x i32> @zext_signed_scaled_i16_i8(ptr %base, ptr %offptr) {238; CHECK-LABEL: zext_signed_scaled_i16_i8:239; CHECK: @ %bb.0: @ %entry240; CHECK-NEXT: vldrb.s32 q1, [r1]241; CHECK-NEXT: vldrh.u32 q0, [r0, q1, uxtw #1]242; CHECK-NEXT: bx lr243entry:244 %offs = load <4 x i8>, ptr %offptr, align 1245 %offs.sext = sext <4 x i8> %offs to <4 x i32>246 %ptrs = getelementptr inbounds i16, ptr %base, <4 x i32> %offs.sext247 %gather = call <4 x i16> @llvm.masked.gather.v4i16.v4p0(<4 x ptr> %ptrs, i32 2, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i16> undef)248 %gather.zext = zext <4 x i16> %gather to <4 x i32>249 ret <4 x i32> %gather.zext250}251 252define arm_aapcs_vfpcc <4 x i32> @sext_signed_scaled_i16_i8(ptr %base, ptr %offptr) {253; CHECK-LABEL: sext_signed_scaled_i16_i8:254; CHECK: @ %bb.0: @ %entry255; CHECK-NEXT: vldrb.s32 q1, [r1]256; CHECK-NEXT: vldrh.s32 q0, [r0, q1, uxtw #1]257; CHECK-NEXT: bx lr258entry:259 %offs = load <4 x i8>, ptr %offptr, align 1260 %offs.sext = sext <4 x i8> %offs to <4 x i32>261 %ptrs = getelementptr inbounds i16, ptr %base, <4 x i32> %offs.sext262 %gather = call <4 x i16> @llvm.masked.gather.v4i16.v4p0(<4 x ptr> %ptrs, i32 2, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i16> undef)263 %gather.sext = sext <4 x i16> %gather to <4 x i32>264 ret <4 x i32> %gather.sext265}266 267define arm_aapcs_vfpcc <4 x i32> @zext_unsigned_scaled_i16_i8(ptr %base, ptr %offptr) {268; CHECK-LABEL: zext_unsigned_scaled_i16_i8:269; CHECK: @ %bb.0: @ %entry270; CHECK-NEXT: vldrb.u32 q1, [r1]271; CHECK-NEXT: vldrh.u32 q0, [r0, q1, uxtw #1]272; CHECK-NEXT: bx lr273entry:274 %offs = load <4 x i8>, ptr %offptr, align 1275 %offs.zext = zext <4 x i8> %offs to <4 x i32>276 %ptrs = getelementptr inbounds i16, ptr %base, <4 x i32> %offs.zext277 %gather = call <4 x i16> @llvm.masked.gather.v4i16.v4p0(<4 x ptr> %ptrs, i32 2, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i16> undef)278 %gather.zext = zext <4 x i16> %gather to <4 x i32>279 ret <4 x i32> %gather.zext280}281 282define arm_aapcs_vfpcc <4 x i32> @sext_unsigned_scaled_i16_i8(ptr %base, ptr %offptr) {283; CHECK-LABEL: sext_unsigned_scaled_i16_i8:284; CHECK: @ %bb.0: @ %entry285; CHECK-NEXT: vldrb.u32 q1, [r1]286; CHECK-NEXT: vldrh.s32 q0, [r0, q1, uxtw #1]287; CHECK-NEXT: bx lr288entry:289 %offs = load <4 x i8>, ptr %offptr, align 1290 %offs.zext = zext <4 x i8> %offs to <4 x i32>291 %ptrs = getelementptr inbounds i16, ptr %base, <4 x i32> %offs.zext292 %gather = call <4 x i16> @llvm.masked.gather.v4i16.v4p0(<4 x ptr> %ptrs, i32 2, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i16> undef)293 %gather.sext = sext <4 x i16> %gather to <4 x i32>294 ret <4 x i32> %gather.sext295}296 297define arm_aapcs_vfpcc <4 x i32> @scaled_i32_i32_2gep(ptr %base, ptr %offptr) {298; CHECK-LABEL: scaled_i32_i32_2gep:299; CHECK: @ %bb.0: @ %entry300; CHECK-NEXT: vldrw.u32 q0, [r1]301; CHECK-NEXT: movs r2, #20302; CHECK-NEXT: vshl.i32 q0, q0, #2303; CHECK-NEXT: vadd.i32 q0, q0, r0304; CHECK-NEXT: vadd.i32 q1, q0, r2305; CHECK-NEXT: vldrw.u32 q0, [q1]306; CHECK-NEXT: bx lr307entry:308 %offs = load <4 x i32>, ptr %offptr, align 4309 %ptrs = getelementptr inbounds i32, ptr %base, <4 x i32> %offs310 %ptrs2 = getelementptr inbounds i32, <4 x ptr> %ptrs, i32 5311 %gather = call <4 x i32> @llvm.masked.gather.v4i32.v4p0(<4 x ptr> %ptrs2, i32 4, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i32> undef)312 ret <4 x i32> %gather313}314 315define arm_aapcs_vfpcc <4 x i32> @scaled_i32_i32_2gep2(ptr %base) {316; CHECK-LABEL: scaled_i32_i32_2gep2:317; CHECK: @ %bb.0: @ %entry318; CHECK-NEXT: adr r1, .LCPI21_0319; CHECK-NEXT: vldrw.u32 q1, [r1]320; CHECK-NEXT: vldrw.u32 q0, [r0, q1]321; CHECK-NEXT: bx lr322; CHECK-NEXT: .p2align 4323; CHECK-NEXT: @ %bb.1:324; CHECK-NEXT: .LCPI21_0:325; CHECK-NEXT: .long 20 @ 0x14326; CHECK-NEXT: .long 32 @ 0x20327; CHECK-NEXT: .long 44 @ 0x2c328; CHECK-NEXT: .long 56 @ 0x38329entry:330 %ptrs = getelementptr inbounds i32, ptr %base, <4 x i32> <i32 0, i32 3, i32 6, i32 9>331 %ptrs2 = getelementptr inbounds i32, <4 x ptr> %ptrs, i32 5332 %gather = call <4 x i32> @llvm.masked.gather.v4i32.v4p0(<4 x ptr> %ptrs2, i32 4, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i32> undef)333 ret <4 x i32> %gather334}335 336declare <4 x i8> @llvm.masked.gather.v4i8.v4p0(<4 x ptr>, i32, <4 x i1>, <4 x i8>)337declare <4 x i16> @llvm.masked.gather.v4i16.v4p0(<4 x ptr>, i32, <4 x i1>, <4 x i16>)338declare <4 x i32> @llvm.masked.gather.v4i32.v4p0(<4 x ptr>, i32, <4 x i1>, <4 x i32>)339declare <4 x half> @llvm.masked.gather.v4f16.v4p0(<4 x ptr>, i32, <4 x i1>, <4 x half>)340declare <4 x float> @llvm.masked.gather.v4f32.v4p0(<4 x ptr>, i32, <4 x i1>, <4 x float>)341