958 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=arm-eabi -float-abi=soft -mattr=+neon | FileCheck %s --check-prefixes=CHECK,DEFAULT3; RUN: llc < %s -mtriple=arm-eabi -float-abi=soft -mattr=+neon -regalloc=basic | FileCheck %s --check-prefixes=CHECK,BASIC4 5;Check the (default) alignment value.6define <8 x i8> @vld1lanei8(ptr %A, ptr %B) nounwind {7; CHECK-LABEL: vld1lanei8:8; CHECK: @ %bb.0:9; CHECK-NEXT: vldr d16, [r1]10; CHECK-NEXT: vld1.8 {d16[3]}, [r0]11; CHECK-NEXT: vmov r0, r1, d1612; CHECK-NEXT: mov pc, lr13 %tmp1 = load <8 x i8>, ptr %B14 %tmp2 = load i8, ptr %A, align 815 %tmp3 = insertelement <8 x i8> %tmp1, i8 %tmp2, i32 316 ret <8 x i8> %tmp317}18 19;Check the alignment value. Max for this instruction is 16 bits:20define <4 x i16> @vld1lanei16(ptr %A, ptr %B) nounwind {21; CHECK-LABEL: vld1lanei16:22; CHECK: @ %bb.0:23; CHECK-NEXT: vldr d16, [r1]24; CHECK-NEXT: vld1.16 {d16[2]}, [r0:16]25; CHECK-NEXT: vmov r0, r1, d1626; CHECK-NEXT: mov pc, lr27 %tmp1 = load <4 x i16>, ptr %B28 %tmp2 = load i16, ptr %A, align 829 %tmp3 = insertelement <4 x i16> %tmp1, i16 %tmp2, i32 230 ret <4 x i16> %tmp331}32 33;Check the alignment value. Max for this instruction is 32 bits:34define <2 x i32> @vld1lanei32(ptr %A, ptr %B) nounwind {35; CHECK-LABEL: vld1lanei32:36; CHECK: @ %bb.0:37; CHECK-NEXT: vldr d16, [r1]38; CHECK-NEXT: vld1.32 {d16[1]}, [r0:32]39; CHECK-NEXT: vmov r0, r1, d1640; CHECK-NEXT: mov pc, lr41 %tmp1 = load <2 x i32>, ptr %B42 %tmp2 = load i32, ptr %A, align 843 %tmp3 = insertelement <2 x i32> %tmp1, i32 %tmp2, i32 144 ret <2 x i32> %tmp345}46 47;Check the alignment value. Legal values are none or :32.48define <2 x i32> @vld1lanei32a32(ptr %A, ptr %B) nounwind {49; CHECK-LABEL: vld1lanei32a32:50; CHECK: @ %bb.0:51; CHECK-NEXT: vldr d16, [r1]52; CHECK-NEXT: vld1.32 {d16[1]}, [r0:32]53; CHECK-NEXT: vmov r0, r1, d1654; CHECK-NEXT: mov pc, lr55 %tmp1 = load <2 x i32>, ptr %B56 %tmp2 = load i32, ptr %A, align 457 %tmp3 = insertelement <2 x i32> %tmp1, i32 %tmp2, i32 158 ret <2 x i32> %tmp359}60 61define <2 x float> @vld1lanef(ptr %A, ptr %B) nounwind {62; CHECK-LABEL: vld1lanef:63; CHECK: @ %bb.0:64; CHECK-NEXT: vldr d16, [r1]65; CHECK-NEXT: vld1.32 {d16[1]}, [r0:32]66; CHECK-NEXT: vmov r0, r1, d1667; CHECK-NEXT: mov pc, lr68 %tmp1 = load <2 x float>, ptr %B69 %tmp2 = load float, ptr %A, align 470 %tmp3 = insertelement <2 x float> %tmp1, float %tmp2, i32 171 ret <2 x float> %tmp372}73 74define <16 x i8> @vld1laneQi8(ptr %A, ptr %B) nounwind {75; CHECK-LABEL: vld1laneQi8:76; CHECK: @ %bb.0:77; CHECK-NEXT: vld1.64 {d16, d17}, [r1]78; CHECK-NEXT: vld1.8 {d17[1]}, [r0]79; CHECK-NEXT: vmov r0, r1, d1680; CHECK-NEXT: vmov r2, r3, d1781; CHECK-NEXT: mov pc, lr82 %tmp1 = load <16 x i8>, ptr %B83 %tmp2 = load i8, ptr %A, align 884 %tmp3 = insertelement <16 x i8> %tmp1, i8 %tmp2, i32 985 ret <16 x i8> %tmp386}87 88define <8 x i16> @vld1laneQi16(ptr %A, ptr %B) nounwind {89; CHECK-LABEL: vld1laneQi16:90; CHECK: @ %bb.0:91; CHECK-NEXT: vld1.64 {d16, d17}, [r1]92; CHECK-NEXT: vld1.16 {d17[1]}, [r0:16]93; CHECK-NEXT: vmov r0, r1, d1694; CHECK-NEXT: vmov r2, r3, d1795; CHECK-NEXT: mov pc, lr96 %tmp1 = load <8 x i16>, ptr %B97 %tmp2 = load i16, ptr %A, align 898 %tmp3 = insertelement <8 x i16> %tmp1, i16 %tmp2, i32 599 ret <8 x i16> %tmp3100}101 102define <4 x i32> @vld1laneQi32(ptr %A, ptr %B) nounwind {103; CHECK-LABEL: vld1laneQi32:104; CHECK: @ %bb.0:105; CHECK-NEXT: vld1.64 {d16, d17}, [r1]106; CHECK-NEXT: vld1.32 {d17[1]}, [r0:32]107; CHECK-NEXT: vmov r0, r1, d16108; CHECK-NEXT: vmov r2, r3, d17109; CHECK-NEXT: mov pc, lr110 %tmp1 = load <4 x i32>, ptr %B111 %tmp2 = load i32, ptr %A, align 8112 %tmp3 = insertelement <4 x i32> %tmp1, i32 %tmp2, i32 3113 ret <4 x i32> %tmp3114}115 116define <4 x float> @vld1laneQf(ptr %A, ptr %B) nounwind {117; CHECK-LABEL: vld1laneQf:118; CHECK: @ %bb.0:119; CHECK-NEXT: vld1.64 {d16, d17}, [r1]120; CHECK-NEXT: vld1.32 {d16[0]}, [r0:32]121; CHECK-NEXT: vmov r2, r3, d17122; CHECK-NEXT: vmov r0, r1, d16123; CHECK-NEXT: mov pc, lr124 %tmp1 = load <4 x float>, ptr %B125 %tmp2 = load float, ptr %A126 %tmp3 = insertelement <4 x float> %tmp1, float %tmp2, i32 0127 ret <4 x float> %tmp3128}129 130%struct.__neon_int8x8x2_t = type { <8 x i8>, <8 x i8> }131%struct.__neon_int16x4x2_t = type { <4 x i16>, <4 x i16> }132%struct.__neon_int32x2x2_t = type { <2 x i32>, <2 x i32> }133%struct.__neon_float32x2x2_t = type { <2 x float>, <2 x float> }134 135%struct.__neon_int16x8x2_t = type { <8 x i16>, <8 x i16> }136%struct.__neon_int32x4x2_t = type { <4 x i32>, <4 x i32> }137%struct.__neon_float32x4x2_t = type { <4 x float>, <4 x float> }138 139;Check the alignment value. Max for this instruction is 16 bits:140define <8 x i8> @vld2lanei8(ptr %A, ptr %B) nounwind {141; CHECK-LABEL: vld2lanei8:142; CHECK: @ %bb.0:143; CHECK-NEXT: vldr d16, [r1]144; CHECK-NEXT: vorr d17, d16, d16145; CHECK-NEXT: vld2.8 {d16[1], d17[1]}, [r0:16]146; CHECK-NEXT: vadd.i8 d16, d16, d17147; CHECK-NEXT: vmov r0, r1, d16148; CHECK-NEXT: mov pc, lr149 %tmp1 = load <8 x i8>, ptr %B150 %tmp2 = call %struct.__neon_int8x8x2_t @llvm.arm.neon.vld2lane.v8i8.p0(ptr %A, <8 x i8> %tmp1, <8 x i8> %tmp1, i32 1, i32 4)151 %tmp3 = extractvalue %struct.__neon_int8x8x2_t %tmp2, 0152 %tmp4 = extractvalue %struct.__neon_int8x8x2_t %tmp2, 1153 %tmp5 = add <8 x i8> %tmp3, %tmp4154 ret <8 x i8> %tmp5155}156 157;Check the alignment value. Max for this instruction is 32 bits:158define <4 x i16> @vld2lanei16(ptr %A, ptr %B) nounwind {159; CHECK-LABEL: vld2lanei16:160; CHECK: @ %bb.0:161; CHECK-NEXT: vldr d16, [r1]162; CHECK-NEXT: vorr d17, d16, d16163; CHECK-NEXT: vld2.16 {d16[1], d17[1]}, [r0:32]164; CHECK-NEXT: vadd.i16 d16, d16, d17165; CHECK-NEXT: vmov r0, r1, d16166; CHECK-NEXT: mov pc, lr167 %tmp1 = load <4 x i16>, ptr %B168 %tmp2 = call %struct.__neon_int16x4x2_t @llvm.arm.neon.vld2lane.v4i16.p0(ptr %A, <4 x i16> %tmp1, <4 x i16> %tmp1, i32 1, i32 8)169 %tmp3 = extractvalue %struct.__neon_int16x4x2_t %tmp2, 0170 %tmp4 = extractvalue %struct.__neon_int16x4x2_t %tmp2, 1171 %tmp5 = add <4 x i16> %tmp3, %tmp4172 ret <4 x i16> %tmp5173}174 175define <2 x i32> @vld2lanei32(ptr %A, ptr %B) nounwind {176; CHECK-LABEL: vld2lanei32:177; CHECK: @ %bb.0:178; CHECK-NEXT: vldr d16, [r1]179; CHECK-NEXT: vorr d17, d16, d16180; CHECK-NEXT: vld2.32 {d16[1], d17[1]}, [r0]181; CHECK-NEXT: vadd.i32 d16, d16, d17182; CHECK-NEXT: vmov r0, r1, d16183; CHECK-NEXT: mov pc, lr184 %tmp1 = load <2 x i32>, ptr %B185 %tmp2 = call %struct.__neon_int32x2x2_t @llvm.arm.neon.vld2lane.v2i32.p0(ptr %A, <2 x i32> %tmp1, <2 x i32> %tmp1, i32 1, i32 1)186 %tmp3 = extractvalue %struct.__neon_int32x2x2_t %tmp2, 0187 %tmp4 = extractvalue %struct.__neon_int32x2x2_t %tmp2, 1188 %tmp5 = add <2 x i32> %tmp3, %tmp4189 ret <2 x i32> %tmp5190}191 192;Check for a post-increment updating load.193define <2 x i32> @vld2lanei32_update(ptr %ptr, ptr %B) nounwind {194; DEFAULT-LABEL: vld2lanei32_update:195; DEFAULT: @ %bb.0:196; DEFAULT-NEXT: vldr d16, [r1]197; DEFAULT-NEXT: ldr r3, [r0]198; DEFAULT-NEXT: vorr d17, d16, d16199; DEFAULT-NEXT: vld2.32 {d16[1], d17[1]}, [r3]!200; DEFAULT-NEXT: vadd.i32 d16, d16, d17201; DEFAULT-NEXT: str r3, [r0]202; DEFAULT-NEXT: vmov r2, r1, d16203; DEFAULT-NEXT: mov r0, r2204; DEFAULT-NEXT: mov pc, lr205;206; BASIC-LABEL: vld2lanei32_update:207; BASIC: @ %bb.0:208; BASIC-NEXT: mov r2, r1209; BASIC-NEXT: mov r1, r0210; BASIC-NEXT: vldr d16, [r2]211; BASIC-NEXT: ldr r0, [r0]212; BASIC-NEXT: vorr d17, d16, d16213; BASIC-NEXT: vld2.32 {d16[1], d17[1]}, [r0]!214; BASIC-NEXT: vadd.i32 d16, d16, d17215; BASIC-NEXT: str r0, [r1]216; BASIC-NEXT: vmov r2, r3, d16217; BASIC-NEXT: mov r0, r2218; BASIC-NEXT: mov r1, r3219; BASIC-NEXT: mov pc, lr220 %A = load ptr, ptr %ptr221 %tmp1 = load <2 x i32>, ptr %B222 %tmp2 = call %struct.__neon_int32x2x2_t @llvm.arm.neon.vld2lane.v2i32.p0(ptr %A, <2 x i32> %tmp1, <2 x i32> %tmp1, i32 1, i32 1)223 %tmp3 = extractvalue %struct.__neon_int32x2x2_t %tmp2, 0224 %tmp4 = extractvalue %struct.__neon_int32x2x2_t %tmp2, 1225 %tmp5 = add <2 x i32> %tmp3, %tmp4226 %tmp6 = getelementptr i32, ptr %A, i32 2227 store ptr %tmp6, ptr %ptr228 ret <2 x i32> %tmp5229}230 231define <2 x i32> @vld2lanei32_odd_update(ptr %ptr, ptr %B) nounwind {232; DEFAULT-LABEL: vld2lanei32_odd_update:233; DEFAULT: @ %bb.0:234; DEFAULT-NEXT: vldr d16, [r1]235; DEFAULT-NEXT: mov r1, #12236; DEFAULT-NEXT: ldr r3, [r0]237; DEFAULT-NEXT: vorr d17, d16, d16238; DEFAULT-NEXT: vld2.32 {d16[1], d17[1]}, [r3], r1239; DEFAULT-NEXT: vadd.i32 d16, d16, d17240; DEFAULT-NEXT: str r3, [r0]241; DEFAULT-NEXT: vmov r2, r1, d16242; DEFAULT-NEXT: mov r0, r2243; DEFAULT-NEXT: mov pc, lr244;245; BASIC-LABEL: vld2lanei32_odd_update:246; BASIC: @ %bb.0:247; BASIC-NEXT: mov r2, r1248; BASIC-NEXT: mov r1, r0249; BASIC-NEXT: vldr d16, [r2]250; BASIC-NEXT: mov r2, #12251; BASIC-NEXT: ldr r0, [r0]252; BASIC-NEXT: vorr d17, d16, d16253; BASIC-NEXT: vld2.32 {d16[1], d17[1]}, [r0], r2254; BASIC-NEXT: vadd.i32 d16, d16, d17255; BASIC-NEXT: str r0, [r1]256; BASIC-NEXT: vmov r2, r3, d16257; BASIC-NEXT: mov r0, r2258; BASIC-NEXT: mov r1, r3259; BASIC-NEXT: mov pc, lr260 %A = load ptr, ptr %ptr261 %tmp1 = load <2 x i32>, ptr %B262 %tmp2 = call %struct.__neon_int32x2x2_t @llvm.arm.neon.vld2lane.v2i32.p0(ptr %A, <2 x i32> %tmp1, <2 x i32> %tmp1, i32 1, i32 1)263 %tmp3 = extractvalue %struct.__neon_int32x2x2_t %tmp2, 0264 %tmp4 = extractvalue %struct.__neon_int32x2x2_t %tmp2, 1265 %tmp5 = add <2 x i32> %tmp3, %tmp4266 %tmp6 = getelementptr i32, ptr %A, i32 3267 store ptr %tmp6, ptr %ptr268 ret <2 x i32> %tmp5269}270 271define <2 x float> @vld2lanef(ptr %A, ptr %B) nounwind {272; CHECK-LABEL: vld2lanef:273; CHECK: @ %bb.0:274; CHECK-NEXT: vldr d16, [r1]275; CHECK-NEXT: vorr d17, d16, d16276; CHECK-NEXT: vld2.32 {d16[1], d17[1]}, [r0]277; CHECK-NEXT: vadd.f32 d16, d16, d17278; CHECK-NEXT: vmov r0, r1, d16279; CHECK-NEXT: mov pc, lr280 %tmp1 = load <2 x float>, ptr %B281 %tmp2 = call %struct.__neon_float32x2x2_t @llvm.arm.neon.vld2lane.v2f32.p0(ptr %A, <2 x float> %tmp1, <2 x float> %tmp1, i32 1, i32 1)282 %tmp3 = extractvalue %struct.__neon_float32x2x2_t %tmp2, 0283 %tmp4 = extractvalue %struct.__neon_float32x2x2_t %tmp2, 1284 %tmp5 = fadd <2 x float> %tmp3, %tmp4285 ret <2 x float> %tmp5286}287 288;Check the (default) alignment.289define <8 x i16> @vld2laneQi16(ptr %A, ptr %B) nounwind {290; CHECK-LABEL: vld2laneQi16:291; CHECK: @ %bb.0:292; CHECK-NEXT: vld1.64 {d16, d17}, [r1]293; CHECK-NEXT: vorr q9, q8, q8294; CHECK-NEXT: vld2.16 {d17[1], d19[1]}, [r0]295; CHECK-NEXT: vadd.i16 q8, q8, q9296; CHECK-NEXT: vmov r0, r1, d16297; CHECK-NEXT: vmov r2, r3, d17298; CHECK-NEXT: mov pc, lr299 %tmp1 = load <8 x i16>, ptr %B300 %tmp2 = call %struct.__neon_int16x8x2_t @llvm.arm.neon.vld2lane.v8i16.p0(ptr %A, <8 x i16> %tmp1, <8 x i16> %tmp1, i32 5, i32 1)301 %tmp3 = extractvalue %struct.__neon_int16x8x2_t %tmp2, 0302 %tmp4 = extractvalue %struct.__neon_int16x8x2_t %tmp2, 1303 %tmp5 = add <8 x i16> %tmp3, %tmp4304 ret <8 x i16> %tmp5305}306 307;Check the alignment value. Max for this instruction is 64 bits:308define <4 x i32> @vld2laneQi32(ptr %A, ptr %B) nounwind {309; CHECK-LABEL: vld2laneQi32:310; CHECK: @ %bb.0:311; CHECK-NEXT: vld1.64 {d16, d17}, [r1]312; CHECK-NEXT: vorr q9, q8, q8313; CHECK-NEXT: vld2.32 {d17[0], d19[0]}, [r0:64]314; CHECK-NEXT: vadd.i32 q8, q8, q9315; CHECK-NEXT: vmov r0, r1, d16316; CHECK-NEXT: vmov r2, r3, d17317; CHECK-NEXT: mov pc, lr318 %tmp1 = load <4 x i32>, ptr %B319 %tmp2 = call %struct.__neon_int32x4x2_t @llvm.arm.neon.vld2lane.v4i32.p0(ptr %A, <4 x i32> %tmp1, <4 x i32> %tmp1, i32 2, i32 16)320 %tmp3 = extractvalue %struct.__neon_int32x4x2_t %tmp2, 0321 %tmp4 = extractvalue %struct.__neon_int32x4x2_t %tmp2, 1322 %tmp5 = add <4 x i32> %tmp3, %tmp4323 ret <4 x i32> %tmp5324}325 326define <4 x float> @vld2laneQf(ptr %A, ptr %B) nounwind {327; CHECK-LABEL: vld2laneQf:328; CHECK: @ %bb.0:329; CHECK-NEXT: vld1.64 {d16, d17}, [r1]330; CHECK-NEXT: vorr q9, q8, q8331; CHECK-NEXT: vld2.32 {d16[1], d18[1]}, [r0]332; CHECK-NEXT: vadd.f32 q8, q8, q9333; CHECK-NEXT: vmov r0, r1, d16334; CHECK-NEXT: vmov r2, r3, d17335; CHECK-NEXT: mov pc, lr336 %tmp1 = load <4 x float>, ptr %B337 %tmp2 = call %struct.__neon_float32x4x2_t @llvm.arm.neon.vld2lane.v4f32.p0(ptr %A, <4 x float> %tmp1, <4 x float> %tmp1, i32 1, i32 1)338 %tmp3 = extractvalue %struct.__neon_float32x4x2_t %tmp2, 0339 %tmp4 = extractvalue %struct.__neon_float32x4x2_t %tmp2, 1340 %tmp5 = fadd <4 x float> %tmp3, %tmp4341 ret <4 x float> %tmp5342}343 344declare %struct.__neon_int8x8x2_t @llvm.arm.neon.vld2lane.v8i8.p0(ptr, <8 x i8>, <8 x i8>, i32, i32) nounwind readonly345declare %struct.__neon_int16x4x2_t @llvm.arm.neon.vld2lane.v4i16.p0(ptr, <4 x i16>, <4 x i16>, i32, i32) nounwind readonly346declare %struct.__neon_int32x2x2_t @llvm.arm.neon.vld2lane.v2i32.p0(ptr, <2 x i32>, <2 x i32>, i32, i32) nounwind readonly347declare %struct.__neon_float32x2x2_t @llvm.arm.neon.vld2lane.v2f32.p0(ptr, <2 x float>, <2 x float>, i32, i32) nounwind readonly348 349declare %struct.__neon_int16x8x2_t @llvm.arm.neon.vld2lane.v8i16.p0(ptr, <8 x i16>, <8 x i16>, i32, i32) nounwind readonly350declare %struct.__neon_int32x4x2_t @llvm.arm.neon.vld2lane.v4i32.p0(ptr, <4 x i32>, <4 x i32>, i32, i32) nounwind readonly351declare %struct.__neon_float32x4x2_t @llvm.arm.neon.vld2lane.v4f32.p0(ptr, <4 x float>, <4 x float>, i32, i32) nounwind readonly352 353%struct.__neon_int8x8x3_t = type { <8 x i8>, <8 x i8>, <8 x i8> }354%struct.__neon_int16x4x3_t = type { <4 x i16>, <4 x i16>, <4 x i16> }355%struct.__neon_int32x2x3_t = type { <2 x i32>, <2 x i32>, <2 x i32> }356%struct.__neon_float32x2x3_t = type { <2 x float>, <2 x float>, <2 x float> }357 358%struct.__neon_int16x8x3_t = type { <8 x i16>, <8 x i16>, <8 x i16> }359%struct.__neon_int32x4x3_t = type { <4 x i32>, <4 x i32>, <4 x i32> }360%struct.__neon_float32x4x3_t = type { <4 x float>, <4 x float>, <4 x float> }361 362define <8 x i8> @vld3lanei8(ptr %A, ptr %B) nounwind {363; DEFAULT-LABEL: vld3lanei8:364; DEFAULT: @ %bb.0:365; DEFAULT-NEXT: vldr d16, [r1]366; DEFAULT-NEXT: vorr d17, d16, d16367; DEFAULT-NEXT: vorr d18, d16, d16368; DEFAULT-NEXT: vld3.8 {d16[1], d17[1], d18[1]}, [r0]369; DEFAULT-NEXT: vadd.i8 d20, d16, d17370; DEFAULT-NEXT: vadd.i8 d16, d18, d20371; DEFAULT-NEXT: vmov r0, r1, d16372; DEFAULT-NEXT: mov pc, lr373;374; BASIC-LABEL: vld3lanei8:375; BASIC: @ %bb.0:376; BASIC-NEXT: vldr d18, [r1]377; BASIC-NEXT: vorr d19, d18, d18378; BASIC-NEXT: vorr d20, d18, d18379; BASIC-NEXT: vld3.8 {d18[1], d19[1], d20[1]}, [r0]380; BASIC-NEXT: vadd.i8 d16, d18, d19381; BASIC-NEXT: vadd.i8 d16, d20, d16382; BASIC-NEXT: vmov r0, r1, d16383; BASIC-NEXT: mov pc, lr384 %tmp1 = load <8 x i8>, ptr %B385 %tmp2 = call %struct.__neon_int8x8x3_t @llvm.arm.neon.vld3lane.v8i8.p0(ptr %A, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, i32 1, i32 1)386 %tmp3 = extractvalue %struct.__neon_int8x8x3_t %tmp2, 0387 %tmp4 = extractvalue %struct.__neon_int8x8x3_t %tmp2, 1388 %tmp5 = extractvalue %struct.__neon_int8x8x3_t %tmp2, 2389 %tmp6 = add <8 x i8> %tmp3, %tmp4390 %tmp7 = add <8 x i8> %tmp5, %tmp6391 ret <8 x i8> %tmp7392}393 394;Check the (default) alignment value. VLD3 does not support alignment.395define <4 x i16> @vld3lanei16(ptr %A, ptr %B) nounwind {396; DEFAULT-LABEL: vld3lanei16:397; DEFAULT: @ %bb.0:398; DEFAULT-NEXT: vldr d16, [r1]399; DEFAULT-NEXT: vorr d17, d16, d16400; DEFAULT-NEXT: vorr d18, d16, d16401; DEFAULT-NEXT: vld3.16 {d16[1], d17[1], d18[1]}, [r0]402; DEFAULT-NEXT: vadd.i16 d20, d16, d17403; DEFAULT-NEXT: vadd.i16 d16, d18, d20404; DEFAULT-NEXT: vmov r0, r1, d16405; DEFAULT-NEXT: mov pc, lr406;407; BASIC-LABEL: vld3lanei16:408; BASIC: @ %bb.0:409; BASIC-NEXT: vldr d18, [r1]410; BASIC-NEXT: vorr d19, d18, d18411; BASIC-NEXT: vorr d20, d18, d18412; BASIC-NEXT: vld3.16 {d18[1], d19[1], d20[1]}, [r0]413; BASIC-NEXT: vadd.i16 d16, d18, d19414; BASIC-NEXT: vadd.i16 d16, d20, d16415; BASIC-NEXT: vmov r0, r1, d16416; BASIC-NEXT: mov pc, lr417 %tmp1 = load <4 x i16>, ptr %B418 %tmp2 = call %struct.__neon_int16x4x3_t @llvm.arm.neon.vld3lane.v4i16.p0(ptr %A, <4 x i16> %tmp1, <4 x i16> %tmp1, <4 x i16> %tmp1, i32 1, i32 8)419 %tmp3 = extractvalue %struct.__neon_int16x4x3_t %tmp2, 0420 %tmp4 = extractvalue %struct.__neon_int16x4x3_t %tmp2, 1421 %tmp5 = extractvalue %struct.__neon_int16x4x3_t %tmp2, 2422 %tmp6 = add <4 x i16> %tmp3, %tmp4423 %tmp7 = add <4 x i16> %tmp5, %tmp6424 ret <4 x i16> %tmp7425}426 427define <2 x i32> @vld3lanei32(ptr %A, ptr %B) nounwind {428; DEFAULT-LABEL: vld3lanei32:429; DEFAULT: @ %bb.0:430; DEFAULT-NEXT: vldr d16, [r1]431; DEFAULT-NEXT: vorr d17, d16, d16432; DEFAULT-NEXT: vorr d18, d16, d16433; DEFAULT-NEXT: vld3.32 {d16[1], d17[1], d18[1]}, [r0]434; DEFAULT-NEXT: vadd.i32 d20, d16, d17435; DEFAULT-NEXT: vadd.i32 d16, d18, d20436; DEFAULT-NEXT: vmov r0, r1, d16437; DEFAULT-NEXT: mov pc, lr438;439; BASIC-LABEL: vld3lanei32:440; BASIC: @ %bb.0:441; BASIC-NEXT: vldr d18, [r1]442; BASIC-NEXT: vorr d19, d18, d18443; BASIC-NEXT: vorr d20, d18, d18444; BASIC-NEXT: vld3.32 {d18[1], d19[1], d20[1]}, [r0]445; BASIC-NEXT: vadd.i32 d16, d18, d19446; BASIC-NEXT: vadd.i32 d16, d20, d16447; BASIC-NEXT: vmov r0, r1, d16448; BASIC-NEXT: mov pc, lr449 %tmp1 = load <2 x i32>, ptr %B450 %tmp2 = call %struct.__neon_int32x2x3_t @llvm.arm.neon.vld3lane.v2i32.p0(ptr %A, <2 x i32> %tmp1, <2 x i32> %tmp1, <2 x i32> %tmp1, i32 1, i32 1)451 %tmp3 = extractvalue %struct.__neon_int32x2x3_t %tmp2, 0452 %tmp4 = extractvalue %struct.__neon_int32x2x3_t %tmp2, 1453 %tmp5 = extractvalue %struct.__neon_int32x2x3_t %tmp2, 2454 %tmp6 = add <2 x i32> %tmp3, %tmp4455 %tmp7 = add <2 x i32> %tmp5, %tmp6456 ret <2 x i32> %tmp7457}458 459define <2 x float> @vld3lanef(ptr %A, ptr %B) nounwind {460; DEFAULT-LABEL: vld3lanef:461; DEFAULT: @ %bb.0:462; DEFAULT-NEXT: vldr d16, [r1]463; DEFAULT-NEXT: vorr d17, d16, d16464; DEFAULT-NEXT: vorr d18, d16, d16465; DEFAULT-NEXT: vld3.32 {d16[1], d17[1], d18[1]}, [r0]466; DEFAULT-NEXT: vadd.f32 d20, d16, d17467; DEFAULT-NEXT: vadd.f32 d16, d18, d20468; DEFAULT-NEXT: vmov r0, r1, d16469; DEFAULT-NEXT: mov pc, lr470;471; BASIC-LABEL: vld3lanef:472; BASIC: @ %bb.0:473; BASIC-NEXT: vldr d18, [r1]474; BASIC-NEXT: vorr d19, d18, d18475; BASIC-NEXT: vorr d20, d18, d18476; BASIC-NEXT: vld3.32 {d18[1], d19[1], d20[1]}, [r0]477; BASIC-NEXT: vadd.f32 d16, d18, d19478; BASIC-NEXT: vadd.f32 d16, d20, d16479; BASIC-NEXT: vmov r0, r1, d16480; BASIC-NEXT: mov pc, lr481 %tmp1 = load <2 x float>, ptr %B482 %tmp2 = call %struct.__neon_float32x2x3_t @llvm.arm.neon.vld3lane.v2f32.p0(ptr %A, <2 x float> %tmp1, <2 x float> %tmp1, <2 x float> %tmp1, i32 1, i32 1)483 %tmp3 = extractvalue %struct.__neon_float32x2x3_t %tmp2, 0484 %tmp4 = extractvalue %struct.__neon_float32x2x3_t %tmp2, 1485 %tmp5 = extractvalue %struct.__neon_float32x2x3_t %tmp2, 2486 %tmp6 = fadd <2 x float> %tmp3, %tmp4487 %tmp7 = fadd <2 x float> %tmp5, %tmp6488 ret <2 x float> %tmp7489}490 491;Check the (default) alignment value. VLD3 does not support alignment.492define <8 x i16> @vld3laneQi16(ptr %A, ptr %B) nounwind {493; DEFAULT-LABEL: vld3laneQi16:494; DEFAULT: @ %bb.0:495; DEFAULT-NEXT: vld1.64 {d16, d17}, [r1]496; DEFAULT-NEXT: vorr q9, q8, q8497; DEFAULT-NEXT: vorr q10, q8, q8498; DEFAULT-NEXT: vld3.16 {d16[1], d18[1], d20[1]}, [r0]499; DEFAULT-NEXT: vadd.i16 q12, q8, q9500; DEFAULT-NEXT: vadd.i16 q8, q10, q12501; DEFAULT-NEXT: vmov r0, r1, d16502; DEFAULT-NEXT: vmov r2, r3, d17503; DEFAULT-NEXT: mov pc, lr504;505; BASIC-LABEL: vld3laneQi16:506; BASIC: @ %bb.0:507; BASIC-NEXT: vld1.64 {d18, d19}, [r1]508; BASIC-NEXT: vorr q10, q9, q9509; BASIC-NEXT: vorr q11, q9, q9510; BASIC-NEXT: vld3.16 {d18[1], d20[1], d22[1]}, [r0]511; BASIC-NEXT: vadd.i16 q8, q9, q10512; BASIC-NEXT: vadd.i16 q8, q11, q8513; BASIC-NEXT: vmov r0, r1, d16514; BASIC-NEXT: vmov r2, r3, d17515; BASIC-NEXT: mov pc, lr516 %tmp1 = load <8 x i16>, ptr %B517 %tmp2 = call %struct.__neon_int16x8x3_t @llvm.arm.neon.vld3lane.v8i16.p0(ptr %A, <8 x i16> %tmp1, <8 x i16> %tmp1, <8 x i16> %tmp1, i32 1, i32 8)518 %tmp3 = extractvalue %struct.__neon_int16x8x3_t %tmp2, 0519 %tmp4 = extractvalue %struct.__neon_int16x8x3_t %tmp2, 1520 %tmp5 = extractvalue %struct.__neon_int16x8x3_t %tmp2, 2521 %tmp6 = add <8 x i16> %tmp3, %tmp4522 %tmp7 = add <8 x i16> %tmp5, %tmp6523 ret <8 x i16> %tmp7524}525 526;Check for a post-increment updating load with register increment.527define <8 x i16> @vld3laneQi16_update(ptr %ptr, ptr %B, i32 %inc) nounwind {528; DEFAULT-LABEL: vld3laneQi16_update:529; DEFAULT: @ %bb.0:530; DEFAULT-NEXT: .save {r11, lr}531; DEFAULT-NEXT: push {r11, lr}532; DEFAULT-NEXT: vld1.64 {d16, d17}, [r1]533; DEFAULT-NEXT: lsl r1, r2, #1534; DEFAULT-NEXT: vorr q9, q8, q8535; DEFAULT-NEXT: ldr lr, [r0]536; DEFAULT-NEXT: vorr q10, q8, q8537; DEFAULT-NEXT: vld3.16 {d16[1], d18[1], d20[1]}, [lr], r1538; DEFAULT-NEXT: vadd.i16 q12, q8, q9539; DEFAULT-NEXT: vadd.i16 q8, q10, q12540; DEFAULT-NEXT: str lr, [r0]541; DEFAULT-NEXT: vmov r12, r1, d16542; DEFAULT-NEXT: vmov r2, r3, d17543; DEFAULT-NEXT: mov r0, r12544; DEFAULT-NEXT: pop {r11, lr}545; DEFAULT-NEXT: mov pc, lr546;547; BASIC-LABEL: vld3laneQi16_update:548; BASIC: @ %bb.0:549; BASIC-NEXT: .save {r11, lr}550; BASIC-NEXT: push {r11, lr}551; BASIC-NEXT: vld1.64 {d18, d19}, [r1]552; BASIC-NEXT: mov r3, r0553; BASIC-NEXT: vorr q10, q9, q9554; BASIC-NEXT: lsl r1, r2, #1555; BASIC-NEXT: ldr r0, [r0]556; BASIC-NEXT: vorr q11, q9, q9557; BASIC-NEXT: vld3.16 {d18[1], d20[1], d22[1]}, [r0], r1558; BASIC-NEXT: vadd.i16 q8, q9, q10559; BASIC-NEXT: vadd.i16 q8, q11, q8560; BASIC-NEXT: str r0, [r3]561; BASIC-NEXT: vmov r1, lr, d16562; BASIC-NEXT: vmov r2, r12, d17563; BASIC-NEXT: mov r0, r1564; BASIC-NEXT: mov r1, lr565; BASIC-NEXT: mov r3, r12566; BASIC-NEXT: pop {r11, lr}567; BASIC-NEXT: mov pc, lr568 %A = load ptr, ptr %ptr569 %tmp1 = load <8 x i16>, ptr %B570 %tmp2 = call %struct.__neon_int16x8x3_t @llvm.arm.neon.vld3lane.v8i16.p0(ptr %A, <8 x i16> %tmp1, <8 x i16> %tmp1, <8 x i16> %tmp1, i32 1, i32 8)571 %tmp3 = extractvalue %struct.__neon_int16x8x3_t %tmp2, 0572 %tmp4 = extractvalue %struct.__neon_int16x8x3_t %tmp2, 1573 %tmp5 = extractvalue %struct.__neon_int16x8x3_t %tmp2, 2574 %tmp6 = add <8 x i16> %tmp3, %tmp4575 %tmp7 = add <8 x i16> %tmp5, %tmp6576 %tmp8 = getelementptr i16, ptr %A, i32 %inc577 store ptr %tmp8, ptr %ptr578 ret <8 x i16> %tmp7579}580 581define <4 x i32> @vld3laneQi32(ptr %A, ptr %B) nounwind {582; DEFAULT-LABEL: vld3laneQi32:583; DEFAULT: @ %bb.0:584; DEFAULT-NEXT: vld1.64 {d16, d17}, [r1]585; DEFAULT-NEXT: vorr q9, q8, q8586; DEFAULT-NEXT: vorr q10, q8, q8587; DEFAULT-NEXT: vld3.32 {d17[1], d19[1], d21[1]}, [r0]588; DEFAULT-NEXT: vadd.i32 q12, q8, q9589; DEFAULT-NEXT: vadd.i32 q8, q10, q12590; DEFAULT-NEXT: vmov r0, r1, d16591; DEFAULT-NEXT: vmov r2, r3, d17592; DEFAULT-NEXT: mov pc, lr593;594; BASIC-LABEL: vld3laneQi32:595; BASIC: @ %bb.0:596; BASIC-NEXT: vld1.64 {d18, d19}, [r1]597; BASIC-NEXT: vorr q10, q9, q9598; BASIC-NEXT: vorr q11, q9, q9599; BASIC-NEXT: vld3.32 {d19[1], d21[1], d23[1]}, [r0]600; BASIC-NEXT: vadd.i32 q8, q9, q10601; BASIC-NEXT: vadd.i32 q8, q11, q8602; BASIC-NEXT: vmov r0, r1, d16603; BASIC-NEXT: vmov r2, r3, d17604; BASIC-NEXT: mov pc, lr605 %tmp1 = load <4 x i32>, ptr %B606 %tmp2 = call %struct.__neon_int32x4x3_t @llvm.arm.neon.vld3lane.v4i32.p0(ptr %A, <4 x i32> %tmp1, <4 x i32> %tmp1, <4 x i32> %tmp1, i32 3, i32 1)607 %tmp3 = extractvalue %struct.__neon_int32x4x3_t %tmp2, 0608 %tmp4 = extractvalue %struct.__neon_int32x4x3_t %tmp2, 1609 %tmp5 = extractvalue %struct.__neon_int32x4x3_t %tmp2, 2610 %tmp6 = add <4 x i32> %tmp3, %tmp4611 %tmp7 = add <4 x i32> %tmp5, %tmp6612 ret <4 x i32> %tmp7613}614 615define <4 x float> @vld3laneQf(ptr %A, ptr %B) nounwind {616; DEFAULT-LABEL: vld3laneQf:617; DEFAULT: @ %bb.0:618; DEFAULT-NEXT: vld1.64 {d16, d17}, [r1]619; DEFAULT-NEXT: vorr q9, q8, q8620; DEFAULT-NEXT: vorr q10, q8, q8621; DEFAULT-NEXT: vld3.32 {d16[1], d18[1], d20[1]}, [r0]622; DEFAULT-NEXT: vadd.f32 q12, q8, q9623; DEFAULT-NEXT: vadd.f32 q8, q10, q12624; DEFAULT-NEXT: vmov r0, r1, d16625; DEFAULT-NEXT: vmov r2, r3, d17626; DEFAULT-NEXT: mov pc, lr627;628; BASIC-LABEL: vld3laneQf:629; BASIC: @ %bb.0:630; BASIC-NEXT: vld1.64 {d18, d19}, [r1]631; BASIC-NEXT: vorr q10, q9, q9632; BASIC-NEXT: vorr q11, q9, q9633; BASIC-NEXT: vld3.32 {d18[1], d20[1], d22[1]}, [r0]634; BASIC-NEXT: vadd.f32 q8, q9, q10635; BASIC-NEXT: vadd.f32 q8, q11, q8636; BASIC-NEXT: vmov r0, r1, d16637; BASIC-NEXT: vmov r2, r3, d17638; BASIC-NEXT: mov pc, lr639 %tmp1 = load <4 x float>, ptr %B640 %tmp2 = call %struct.__neon_float32x4x3_t @llvm.arm.neon.vld3lane.v4f32.p0(ptr %A, <4 x float> %tmp1, <4 x float> %tmp1, <4 x float> %tmp1, i32 1, i32 1)641 %tmp3 = extractvalue %struct.__neon_float32x4x3_t %tmp2, 0642 %tmp4 = extractvalue %struct.__neon_float32x4x3_t %tmp2, 1643 %tmp5 = extractvalue %struct.__neon_float32x4x3_t %tmp2, 2644 %tmp6 = fadd <4 x float> %tmp3, %tmp4645 %tmp7 = fadd <4 x float> %tmp5, %tmp6646 ret <4 x float> %tmp7647}648 649declare %struct.__neon_int8x8x3_t @llvm.arm.neon.vld3lane.v8i8.p0(ptr, <8 x i8>, <8 x i8>, <8 x i8>, i32, i32) nounwind readonly650declare %struct.__neon_int16x4x3_t @llvm.arm.neon.vld3lane.v4i16.p0(ptr, <4 x i16>, <4 x i16>, <4 x i16>, i32, i32) nounwind readonly651declare %struct.__neon_int32x2x3_t @llvm.arm.neon.vld3lane.v2i32.p0(ptr, <2 x i32>, <2 x i32>, <2 x i32>, i32, i32) nounwind readonly652declare %struct.__neon_float32x2x3_t @llvm.arm.neon.vld3lane.v2f32.p0(ptr, <2 x float>, <2 x float>, <2 x float>, i32, i32) nounwind readonly653 654declare %struct.__neon_int16x8x3_t @llvm.arm.neon.vld3lane.v8i16.p0(ptr, <8 x i16>, <8 x i16>, <8 x i16>, i32, i32) nounwind readonly655declare %struct.__neon_int32x4x3_t @llvm.arm.neon.vld3lane.v4i32.p0(ptr, <4 x i32>, <4 x i32>, <4 x i32>, i32, i32) nounwind readonly656declare %struct.__neon_float32x4x3_t @llvm.arm.neon.vld3lane.v4f32.p0(ptr, <4 x float>, <4 x float>, <4 x float>, i32, i32) nounwind readonly657 658%struct.__neon_int8x8x4_t = type { <8 x i8>, <8 x i8>, <8 x i8>, <8 x i8> }659%struct.__neon_int16x4x4_t = type { <4 x i16>, <4 x i16>, <4 x i16>, <4 x i16> }660%struct.__neon_int32x2x4_t = type { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> }661%struct.__neon_float32x2x4_t = type { <2 x float>, <2 x float>, <2 x float>, <2 x float> }662 663%struct.__neon_int16x8x4_t = type { <8 x i16>, <8 x i16>, <8 x i16>, <8 x i16> }664%struct.__neon_int32x4x4_t = type { <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32> }665%struct.__neon_float32x4x4_t = type { <4 x float>, <4 x float>, <4 x float>, <4 x float> }666 667;Check the alignment value. Max for this instruction is 32 bits:668define <8 x i8> @vld4lanei8(ptr %A, ptr %B) nounwind {669; CHECK-LABEL: vld4lanei8:670; CHECK: @ %bb.0:671; CHECK-NEXT: vldr d16, [r1]672; CHECK-NEXT: vorr d17, d16, d16673; CHECK-NEXT: vorr d18, d16, d16674; CHECK-NEXT: vorr d19, d16, d16675; CHECK-NEXT: vld4.8 {d16[1], d17[1], d18[1], d19[1]}, [r0:32]676; CHECK-NEXT: vadd.i8 d16, d16, d17677; CHECK-NEXT: vadd.i8 d20, d18, d19678; CHECK-NEXT: vadd.i8 d16, d16, d20679; CHECK-NEXT: vmov r0, r1, d16680; CHECK-NEXT: mov pc, lr681 %tmp1 = load <8 x i8>, ptr %B682 %tmp2 = call %struct.__neon_int8x8x4_t @llvm.arm.neon.vld4lane.v8i8.p0(ptr %A, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, i32 1, i32 8)683 %tmp3 = extractvalue %struct.__neon_int8x8x4_t %tmp2, 0684 %tmp4 = extractvalue %struct.__neon_int8x8x4_t %tmp2, 1685 %tmp5 = extractvalue %struct.__neon_int8x8x4_t %tmp2, 2686 %tmp6 = extractvalue %struct.__neon_int8x8x4_t %tmp2, 3687 %tmp7 = add <8 x i8> %tmp3, %tmp4688 %tmp8 = add <8 x i8> %tmp5, %tmp6689 %tmp9 = add <8 x i8> %tmp7, %tmp8690 ret <8 x i8> %tmp9691}692 693;Check for a post-increment updating load.694define <8 x i8> @vld4lanei8_update(ptr %ptr, ptr %B) nounwind {695; DEFAULT-LABEL: vld4lanei8_update:696; DEFAULT: @ %bb.0:697; DEFAULT-NEXT: vldr d16, [r1]698; DEFAULT-NEXT: vorr d17, d16, d16699; DEFAULT-NEXT: ldr r3, [r0]700; DEFAULT-NEXT: vorr d18, d16, d16701; DEFAULT-NEXT: vorr d19, d16, d16702; DEFAULT-NEXT: vld4.8 {d16[1], d17[1], d18[1], d19[1]}, [r3:32]!703; DEFAULT-NEXT: vadd.i8 d16, d16, d17704; DEFAULT-NEXT: vadd.i8 d20, d18, d19705; DEFAULT-NEXT: str r3, [r0]706; DEFAULT-NEXT: vadd.i8 d16, d16, d20707; DEFAULT-NEXT: vmov r2, r1, d16708; DEFAULT-NEXT: mov r0, r2709; DEFAULT-NEXT: mov pc, lr710;711; BASIC-LABEL: vld4lanei8_update:712; BASIC: @ %bb.0:713; BASIC-NEXT: vldr d16, [r1]714; BASIC-NEXT: mov r3, r0715; BASIC-NEXT: vorr d17, d16, d16716; BASIC-NEXT: ldr r0, [r0]717; BASIC-NEXT: vorr d18, d16, d16718; BASIC-NEXT: vorr d19, d16, d16719; BASIC-NEXT: vld4.8 {d16[1], d17[1], d18[1], d19[1]}, [r0:32]!720; BASIC-NEXT: vadd.i8 d16, d16, d17721; BASIC-NEXT: vadd.i8 d20, d18, d19722; BASIC-NEXT: str r0, [r3]723; BASIC-NEXT: vadd.i8 d16, d16, d20724; BASIC-NEXT: vmov r1, r2, d16725; BASIC-NEXT: mov r0, r1726; BASIC-NEXT: mov r1, r2727; BASIC-NEXT: mov pc, lr728 %A = load ptr, ptr %ptr729 %tmp1 = load <8 x i8>, ptr %B730 %tmp2 = call %struct.__neon_int8x8x4_t @llvm.arm.neon.vld4lane.v8i8.p0(ptr %A, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, i32 1, i32 8)731 %tmp3 = extractvalue %struct.__neon_int8x8x4_t %tmp2, 0732 %tmp4 = extractvalue %struct.__neon_int8x8x4_t %tmp2, 1733 %tmp5 = extractvalue %struct.__neon_int8x8x4_t %tmp2, 2734 %tmp6 = extractvalue %struct.__neon_int8x8x4_t %tmp2, 3735 %tmp7 = add <8 x i8> %tmp3, %tmp4736 %tmp8 = add <8 x i8> %tmp5, %tmp6737 %tmp9 = add <8 x i8> %tmp7, %tmp8738 %tmp10 = getelementptr i8, ptr %A, i32 4739 store ptr %tmp10, ptr %ptr740 ret <8 x i8> %tmp9741}742 743;Check that a power-of-two alignment smaller than the total size of the memory744;being loaded is ignored.745define <4 x i16> @vld4lanei16(ptr %A, ptr %B) nounwind {746; CHECK-LABEL: vld4lanei16:747; CHECK: @ %bb.0:748; CHECK-NEXT: vldr d16, [r1]749; CHECK-NEXT: vorr d17, d16, d16750; CHECK-NEXT: vorr d18, d16, d16751; CHECK-NEXT: vorr d19, d16, d16752; CHECK-NEXT: vld4.16 {d16[1], d17[1], d18[1], d19[1]}, [r0]753; CHECK-NEXT: vadd.i16 d16, d16, d17754; CHECK-NEXT: vadd.i16 d20, d18, d19755; CHECK-NEXT: vadd.i16 d16, d16, d20756; CHECK-NEXT: vmov r0, r1, d16757; CHECK-NEXT: mov pc, lr758 %tmp1 = load <4 x i16>, ptr %B759 %tmp2 = call %struct.__neon_int16x4x4_t @llvm.arm.neon.vld4lane.v4i16.p0(ptr %A, <4 x i16> %tmp1, <4 x i16> %tmp1, <4 x i16> %tmp1, <4 x i16> %tmp1, i32 1, i32 4)760 %tmp3 = extractvalue %struct.__neon_int16x4x4_t %tmp2, 0761 %tmp4 = extractvalue %struct.__neon_int16x4x4_t %tmp2, 1762 %tmp5 = extractvalue %struct.__neon_int16x4x4_t %tmp2, 2763 %tmp6 = extractvalue %struct.__neon_int16x4x4_t %tmp2, 3764 %tmp7 = add <4 x i16> %tmp3, %tmp4765 %tmp8 = add <4 x i16> %tmp5, %tmp6766 %tmp9 = add <4 x i16> %tmp7, %tmp8767 ret <4 x i16> %tmp9768}769 770;Check the alignment value. An 8-byte alignment is allowed here even though771;it is smaller than the total size of the memory being loaded.772define <2 x i32> @vld4lanei32(ptr %A, ptr %B) nounwind {773; CHECK-LABEL: vld4lanei32:774; CHECK: @ %bb.0:775; CHECK-NEXT: vldr d16, [r1]776; CHECK-NEXT: vorr d17, d16, d16777; CHECK-NEXT: vorr d18, d16, d16778; CHECK-NEXT: vorr d19, d16, d16779; CHECK-NEXT: vld4.32 {d16[1], d17[1], d18[1], d19[1]}, [r0:64]780; CHECK-NEXT: vadd.i32 d16, d16, d17781; CHECK-NEXT: vadd.i32 d20, d18, d19782; CHECK-NEXT: vadd.i32 d16, d16, d20783; CHECK-NEXT: vmov r0, r1, d16784; CHECK-NEXT: mov pc, lr785 %tmp1 = load <2 x i32>, ptr %B786 %tmp2 = call %struct.__neon_int32x2x4_t @llvm.arm.neon.vld4lane.v2i32.p0(ptr %A, <2 x i32> %tmp1, <2 x i32> %tmp1, <2 x i32> %tmp1, <2 x i32> %tmp1, i32 1, i32 8)787 %tmp3 = extractvalue %struct.__neon_int32x2x4_t %tmp2, 0788 %tmp4 = extractvalue %struct.__neon_int32x2x4_t %tmp2, 1789 %tmp5 = extractvalue %struct.__neon_int32x2x4_t %tmp2, 2790 %tmp6 = extractvalue %struct.__neon_int32x2x4_t %tmp2, 3791 %tmp7 = add <2 x i32> %tmp3, %tmp4792 %tmp8 = add <2 x i32> %tmp5, %tmp6793 %tmp9 = add <2 x i32> %tmp7, %tmp8794 ret <2 x i32> %tmp9795}796 797define <2 x float> @vld4lanef(ptr %A, ptr %B) nounwind {798; CHECK-LABEL: vld4lanef:799; CHECK: @ %bb.0:800; CHECK-NEXT: vldr d16, [r1]801; CHECK-NEXT: vorr d17, d16, d16802; CHECK-NEXT: vorr d18, d16, d16803; CHECK-NEXT: vorr d19, d16, d16804; CHECK-NEXT: vld4.32 {d16[1], d17[1], d18[1], d19[1]}, [r0]805; CHECK-NEXT: vadd.f32 d16, d16, d17806; CHECK-NEXT: vadd.f32 d20, d18, d19807; CHECK-NEXT: vadd.f32 d16, d16, d20808; CHECK-NEXT: vmov r0, r1, d16809; CHECK-NEXT: mov pc, lr810 %tmp1 = load <2 x float>, ptr %B811 %tmp2 = call %struct.__neon_float32x2x4_t @llvm.arm.neon.vld4lane.v2f32.p0(ptr %A, <2 x float> %tmp1, <2 x float> %tmp1, <2 x float> %tmp1, <2 x float> %tmp1, i32 1, i32 1)812 %tmp3 = extractvalue %struct.__neon_float32x2x4_t %tmp2, 0813 %tmp4 = extractvalue %struct.__neon_float32x2x4_t %tmp2, 1814 %tmp5 = extractvalue %struct.__neon_float32x2x4_t %tmp2, 2815 %tmp6 = extractvalue %struct.__neon_float32x2x4_t %tmp2, 3816 %tmp7 = fadd <2 x float> %tmp3, %tmp4817 %tmp8 = fadd <2 x float> %tmp5, %tmp6818 %tmp9 = fadd <2 x float> %tmp7, %tmp8819 ret <2 x float> %tmp9820}821 822;Check the alignment value. Max for this instruction is 64 bits:823define <8 x i16> @vld4laneQi16(ptr %A, ptr %B) nounwind {824; CHECK-LABEL: vld4laneQi16:825; CHECK: @ %bb.0:826; CHECK-NEXT: vld1.64 {d16, d17}, [r1]827; CHECK-NEXT: vorr q9, q8, q8828; CHECK-NEXT: vorr q10, q8, q8829; CHECK-NEXT: vorr q11, q8, q8830; CHECK-NEXT: vld4.16 {d16[1], d18[1], d20[1], d22[1]}, [r0:64]831; CHECK-NEXT: vadd.i16 q8, q8, q9832; CHECK-NEXT: vadd.i16 q12, q10, q11833; CHECK-NEXT: vadd.i16 q8, q8, q12834; CHECK-NEXT: vmov r0, r1, d16835; CHECK-NEXT: vmov r2, r3, d17836; CHECK-NEXT: mov pc, lr837 %tmp1 = load <8 x i16>, ptr %B838 %tmp2 = call %struct.__neon_int16x8x4_t @llvm.arm.neon.vld4lane.v8i16.p0(ptr %A, <8 x i16> %tmp1, <8 x i16> %tmp1, <8 x i16> %tmp1, <8 x i16> %tmp1, i32 1, i32 16)839 %tmp3 = extractvalue %struct.__neon_int16x8x4_t %tmp2, 0840 %tmp4 = extractvalue %struct.__neon_int16x8x4_t %tmp2, 1841 %tmp5 = extractvalue %struct.__neon_int16x8x4_t %tmp2, 2842 %tmp6 = extractvalue %struct.__neon_int16x8x4_t %tmp2, 3843 %tmp7 = add <8 x i16> %tmp3, %tmp4844 %tmp8 = add <8 x i16> %tmp5, %tmp6845 %tmp9 = add <8 x i16> %tmp7, %tmp8846 ret <8 x i16> %tmp9847}848 849;Check the (default) alignment.850define <4 x i32> @vld4laneQi32(ptr %A, ptr %B) nounwind {851; CHECK-LABEL: vld4laneQi32:852; CHECK: @ %bb.0:853; CHECK-NEXT: vld1.64 {d16, d17}, [r1]854; CHECK-NEXT: vorr q9, q8, q8855; CHECK-NEXT: vorr q10, q8, q8856; CHECK-NEXT: vorr q11, q8, q8857; CHECK-NEXT: vld4.32 {d17[0], d19[0], d21[0], d23[0]}, [r0]858; CHECK-NEXT: vadd.i32 q8, q8, q9859; CHECK-NEXT: vadd.i32 q12, q10, q11860; CHECK-NEXT: vadd.i32 q8, q8, q12861; CHECK-NEXT: vmov r0, r1, d16862; CHECK-NEXT: vmov r2, r3, d17863; CHECK-NEXT: mov pc, lr864 %tmp1 = load <4 x i32>, ptr %B865 %tmp2 = call %struct.__neon_int32x4x4_t @llvm.arm.neon.vld4lane.v4i32.p0(ptr %A, <4 x i32> %tmp1, <4 x i32> %tmp1, <4 x i32> %tmp1, <4 x i32> %tmp1, i32 2, i32 1)866 %tmp3 = extractvalue %struct.__neon_int32x4x4_t %tmp2, 0867 %tmp4 = extractvalue %struct.__neon_int32x4x4_t %tmp2, 1868 %tmp5 = extractvalue %struct.__neon_int32x4x4_t %tmp2, 2869 %tmp6 = extractvalue %struct.__neon_int32x4x4_t %tmp2, 3870 %tmp7 = add <4 x i32> %tmp3, %tmp4871 %tmp8 = add <4 x i32> %tmp5, %tmp6872 %tmp9 = add <4 x i32> %tmp7, %tmp8873 ret <4 x i32> %tmp9874}875 876define <4 x float> @vld4laneQf(ptr %A, ptr %B) nounwind {877; CHECK-LABEL: vld4laneQf:878; CHECK: @ %bb.0:879; CHECK-NEXT: vld1.64 {d16, d17}, [r1]880; CHECK-NEXT: vorr q9, q8, q8881; CHECK-NEXT: vorr q10, q8, q8882; CHECK-NEXT: vorr q11, q8, q8883; CHECK-NEXT: vld4.32 {d16[1], d18[1], d20[1], d22[1]}, [r0]884; CHECK-NEXT: vadd.f32 q8, q8, q9885; CHECK-NEXT: vadd.f32 q12, q10, q11886; CHECK-NEXT: vadd.f32 q8, q8, q12887; CHECK-NEXT: vmov r0, r1, d16888; CHECK-NEXT: vmov r2, r3, d17889; CHECK-NEXT: mov pc, lr890 %tmp1 = load <4 x float>, ptr %B891 %tmp2 = call %struct.__neon_float32x4x4_t @llvm.arm.neon.vld4lane.v4f32.p0(ptr %A, <4 x float> %tmp1, <4 x float> %tmp1, <4 x float> %tmp1, <4 x float> %tmp1, i32 1, i32 1)892 %tmp3 = extractvalue %struct.__neon_float32x4x4_t %tmp2, 0893 %tmp4 = extractvalue %struct.__neon_float32x4x4_t %tmp2, 1894 %tmp5 = extractvalue %struct.__neon_float32x4x4_t %tmp2, 2895 %tmp6 = extractvalue %struct.__neon_float32x4x4_t %tmp2, 3896 %tmp7 = fadd <4 x float> %tmp3, %tmp4897 %tmp8 = fadd <4 x float> %tmp5, %tmp6898 %tmp9 = fadd <4 x float> %tmp7, %tmp8899 ret <4 x float> %tmp9900}901 902declare %struct.__neon_int8x8x4_t @llvm.arm.neon.vld4lane.v8i8.p0(ptr, <8 x i8>, <8 x i8>, <8 x i8>, <8 x i8>, i32, i32) nounwind readonly903declare %struct.__neon_int16x4x4_t @llvm.arm.neon.vld4lane.v4i16.p0(ptr, <4 x i16>, <4 x i16>, <4 x i16>, <4 x i16>, i32, i32) nounwind readonly904declare %struct.__neon_int32x2x4_t @llvm.arm.neon.vld4lane.v2i32.p0(ptr, <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32>, i32, i32) nounwind readonly905declare %struct.__neon_float32x2x4_t @llvm.arm.neon.vld4lane.v2f32.p0(ptr, <2 x float>, <2 x float>, <2 x float>, <2 x float>, i32, i32) nounwind readonly906 907declare %struct.__neon_int16x8x4_t @llvm.arm.neon.vld4lane.v8i16.p0(ptr, <8 x i16>, <8 x i16>, <8 x i16>, <8 x i16>, i32, i32) nounwind readonly908declare %struct.__neon_int32x4x4_t @llvm.arm.neon.vld4lane.v4i32.p0(ptr, <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32>, i32, i32) nounwind readonly909declare %struct.__neon_float32x4x4_t @llvm.arm.neon.vld4lane.v4f32.p0(ptr, <4 x float>, <4 x float>, <4 x float>, <4 x float>, i32, i32) nounwind readonly910 911; Radar 8776599: If one of the operands to a QQQQ REG_SEQUENCE is a register912; in the QPR_VFP2 regclass, it needs to be copied to a QPR regclass because913; we don't currently have a QQQQ_VFP2 super-regclass. (The "0" for the low914; part of %ins67 is supposed to be loaded by a VLDRS instruction in this test.)915define <8 x i16> @test_qqqq_regsequence_subreg([6 x i64] %b) nounwind {916; DEFAULT-LABEL: test_qqqq_regsequence_subreg:917; DEFAULT: @ %bb.0:918; DEFAULT-NEXT: add r0, sp, #24919; DEFAULT-NEXT: vld1.32 {d21[0]}, [r0:32]920; DEFAULT-NEXT: add r0, sp, #28921; DEFAULT-NEXT: vmov.i32 d20, #0x0922; DEFAULT-NEXT: vld1.32 {d21[1]}, [r0:32]923; DEFAULT-NEXT: vld3.16 {d16[1], d18[1], d20[1]}, [r0]924; DEFAULT-NEXT: vadd.i16 q12, q8, q9925; DEFAULT-NEXT: vadd.i16 q8, q10, q12926; DEFAULT-NEXT: vmov r0, r1, d16927; DEFAULT-NEXT: vmov r2, r3, d17928; DEFAULT-NEXT: mov pc, lr929;930; BASIC-LABEL: test_qqqq_regsequence_subreg:931; BASIC: @ %bb.0:932; BASIC-NEXT: add r0, sp, #24933; BASIC-NEXT: vld1.32 {d23[0]}, [r0:32]934; BASIC-NEXT: add r0, sp, #28935; BASIC-NEXT: vmov.i32 d22, #0x0936; BASIC-NEXT: vld1.32 {d23[1]}, [r0:32]937; BASIC-NEXT: vld3.16 {d18[1], d20[1], d22[1]}, [r0]938; BASIC-NEXT: vadd.i16 q8, q9, q10939; BASIC-NEXT: vadd.i16 q8, q11, q8940; BASIC-NEXT: vmov r0, r1, d16941; BASIC-NEXT: vmov r2, r3, d17942; BASIC-NEXT: mov pc, lr943 %tmp63 = extractvalue [6 x i64] %b, 5944 %tmp64 = zext i64 %tmp63 to i128945 %tmp65 = shl i128 %tmp64, 64946 %ins67 = or i128 %tmp65, 0947 %tmp78 = bitcast i128 %ins67 to <8 x i16>948 %vld3_lane = tail call %struct.__neon_int16x8x3_t @llvm.arm.neon.vld3lane.v8i16.p0(ptr undef, <8 x i16> undef, <8 x i16> undef, <8 x i16> %tmp78, i32 1, i32 2)949 %tmp3 = extractvalue %struct.__neon_int16x8x3_t %vld3_lane, 0950 %tmp4 = extractvalue %struct.__neon_int16x8x3_t %vld3_lane, 1951 %tmp5 = extractvalue %struct.__neon_int16x8x3_t %vld3_lane, 2952 %tmp6 = add <8 x i16> %tmp3, %tmp4953 %tmp7 = add <8 x i16> %tmp5, %tmp6954 ret <8 x i16> %tmp7955}956 957declare void @llvm.trap() nounwind958