461 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 -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK3 4define arm_aapcs_vfpcc i32 @mul_v2i32(<2 x i32> %x) {5; CHECK-LABEL: mul_v2i32:6; CHECK: @ %bb.0: @ %entry7; CHECK-NEXT: vmov r0, s28; CHECK-NEXT: vmov r1, s09; CHECK-NEXT: muls r0, r1, r010; CHECK-NEXT: bx lr11entry:12 %z = call i32 @llvm.vector.reduce.mul.v2i32(<2 x i32> %x)13 ret i32 %z14}15 16define arm_aapcs_vfpcc i32 @mul_v4i32(<4 x i32> %x) {17; CHECK-LABEL: mul_v4i32:18; CHECK: @ %bb.0: @ %entry19; CHECK-NEXT: vmov r0, r1, d120; CHECK-NEXT: muls r0, r1, r021; CHECK-NEXT: vmov r1, r2, d022; CHECK-NEXT: muls r1, r2, r123; CHECK-NEXT: muls r0, r1, r024; CHECK-NEXT: bx lr25entry:26 %z = call i32 @llvm.vector.reduce.mul.v4i32(<4 x i32> %x)27 ret i32 %z28}29 30define arm_aapcs_vfpcc i32 @mul_v8i32(<8 x i32> %x) {31; CHECK-LABEL: mul_v8i32:32; CHECK: @ %bb.0: @ %entry33; CHECK-NEXT: vmul.i32 q0, q0, q134; CHECK-NEXT: vmov r0, r1, d135; CHECK-NEXT: muls r0, r1, r036; CHECK-NEXT: vmov r1, r2, d037; CHECK-NEXT: muls r1, r2, r138; CHECK-NEXT: muls r0, r1, r039; CHECK-NEXT: bx lr40entry:41 %z = call i32 @llvm.vector.reduce.mul.v8i32(<8 x i32> %x)42 ret i32 %z43}44 45define arm_aapcs_vfpcc i16 @mul_v4i16(<4 x i16> %x) {46; CHECK-LABEL: mul_v4i16:47; CHECK: @ %bb.0: @ %entry48; CHECK-NEXT: vmov r0, r1, d149; CHECK-NEXT: muls r0, r1, r050; CHECK-NEXT: vmov r1, r2, d051; CHECK-NEXT: muls r1, r2, r152; CHECK-NEXT: muls r0, r1, r053; CHECK-NEXT: bx lr54entry:55 %z = call i16 @llvm.vector.reduce.mul.v4i16(<4 x i16> %x)56 ret i16 %z57}58 59define arm_aapcs_vfpcc i16 @mul_v8i16(<8 x i16> %x) {60; CHECK-LABEL: mul_v8i16:61; CHECK: @ %bb.0: @ %entry62; CHECK-NEXT: vrev32.16 q1, q063; CHECK-NEXT: vmul.i16 q0, q0, q164; CHECK-NEXT: vmov.u16 r0, q0[6]65; CHECK-NEXT: vmov.u16 r1, q0[4]66; CHECK-NEXT: muls r0, r1, r067; CHECK-NEXT: vmov.u16 r1, q0[2]68; CHECK-NEXT: vmov.u16 r2, q0[0]69; CHECK-NEXT: muls r1, r2, r170; CHECK-NEXT: muls r0, r1, r071; CHECK-NEXT: bx lr72entry:73 %z = call i16 @llvm.vector.reduce.mul.v8i16(<8 x i16> %x)74 ret i16 %z75}76 77define arm_aapcs_vfpcc i16 @mul_v16i16(<16 x i16> %x) {78; CHECK-LABEL: mul_v16i16:79; CHECK: @ %bb.0: @ %entry80; CHECK-NEXT: vmul.i16 q0, q0, q181; CHECK-NEXT: vrev32.16 q1, q082; CHECK-NEXT: vmul.i16 q0, q0, q183; CHECK-NEXT: vmov.u16 r0, q0[6]84; CHECK-NEXT: vmov.u16 r1, q0[4]85; CHECK-NEXT: muls r0, r1, r086; CHECK-NEXT: vmov.u16 r1, q0[2]87; CHECK-NEXT: vmov.u16 r2, q0[0]88; CHECK-NEXT: muls r1, r2, r189; CHECK-NEXT: muls r0, r1, r090; CHECK-NEXT: bx lr91entry:92 %z = call i16 @llvm.vector.reduce.mul.v16i16(<16 x i16> %x)93 ret i16 %z94}95 96define arm_aapcs_vfpcc i8 @mul_v8i8(<8 x i8> %x) {97; CHECK-LABEL: mul_v8i8:98; CHECK: @ %bb.0: @ %entry99; CHECK-NEXT: vrev32.16 q1, q0100; CHECK-NEXT: vmul.i16 q0, q0, q1101; CHECK-NEXT: vmov.u16 r0, q0[6]102; CHECK-NEXT: vmov.u16 r1, q0[4]103; CHECK-NEXT: muls r0, r1, r0104; CHECK-NEXT: vmov.u16 r1, q0[2]105; CHECK-NEXT: vmov.u16 r2, q0[0]106; CHECK-NEXT: muls r1, r2, r1107; CHECK-NEXT: muls r0, r1, r0108; CHECK-NEXT: bx lr109entry:110 %z = call i8 @llvm.vector.reduce.mul.v8i8(<8 x i8> %x)111 ret i8 %z112}113 114define arm_aapcs_vfpcc i8 @mul_v16i8(<16 x i8> %x) {115; CHECK-LABEL: mul_v16i8:116; CHECK: @ %bb.0: @ %entry117; CHECK-NEXT: vrev16.8 q1, q0118; CHECK-NEXT: vmul.i8 q0, q0, q1119; CHECK-NEXT: vrev32.8 q1, q0120; CHECK-NEXT: vmul.i8 q0, q0, q1121; CHECK-NEXT: vmov.u8 r0, q0[12]122; CHECK-NEXT: vmov.u8 r1, q0[8]123; CHECK-NEXT: muls r0, r1, r0124; CHECK-NEXT: vmov.u8 r1, q0[4]125; CHECK-NEXT: vmov.u8 r2, q0[0]126; CHECK-NEXT: muls r1, r2, r1127; CHECK-NEXT: muls r0, r1, r0128; CHECK-NEXT: bx lr129entry:130 %z = call i8 @llvm.vector.reduce.mul.v16i8(<16 x i8> %x)131 ret i8 %z132}133 134define arm_aapcs_vfpcc i8 @mul_v32i8(<32 x i8> %x) {135; CHECK-LABEL: mul_v32i8:136; CHECK: @ %bb.0: @ %entry137; CHECK-NEXT: vmul.i8 q0, q0, q1138; CHECK-NEXT: vrev16.8 q1, q0139; CHECK-NEXT: vmul.i8 q0, q0, q1140; CHECK-NEXT: vrev32.8 q1, q0141; CHECK-NEXT: vmul.i8 q0, q0, q1142; CHECK-NEXT: vmov.u8 r0, q0[12]143; CHECK-NEXT: vmov.u8 r1, q0[8]144; CHECK-NEXT: muls r0, r1, r0145; CHECK-NEXT: vmov.u8 r1, q0[4]146; CHECK-NEXT: vmov.u8 r2, q0[0]147; CHECK-NEXT: muls r1, r2, r1148; CHECK-NEXT: muls r0, r1, r0149; CHECK-NEXT: bx lr150entry:151 %z = call i8 @llvm.vector.reduce.mul.v32i8(<32 x i8> %x)152 ret i8 %z153}154 155define arm_aapcs_vfpcc i64 @mul_v1i64(<1 x i64> %x) {156; CHECK-LABEL: mul_v1i64:157; CHECK: @ %bb.0: @ %entry158; CHECK-NEXT: bx lr159entry:160 %z = call i64 @llvm.vector.reduce.mul.v1i64(<1 x i64> %x)161 ret i64 %z162}163 164define arm_aapcs_vfpcc i64 @mul_v2i64(<2 x i64> %x) {165; CHECK-LABEL: mul_v2i64:166; CHECK: @ %bb.0: @ %entry167; CHECK-NEXT: .save {r7, lr}168; CHECK-NEXT: push {r7, lr}169; CHECK-NEXT: vmov r1, r12, d1170; CHECK-NEXT: vmov r3, lr, d0171; CHECK-NEXT: umull r0, r2, r3, r1172; CHECK-NEXT: mla r2, r3, r12, r2173; CHECK-NEXT: mla r1, lr, r1, r2174; CHECK-NEXT: pop {r7, pc}175entry:176 %z = call i64 @llvm.vector.reduce.mul.v2i64(<2 x i64> %x)177 ret i64 %z178}179 180define arm_aapcs_vfpcc i64 @mul_v4i64(<4 x i64> %x) {181; CHECK-LABEL: mul_v4i64:182; CHECK: @ %bb.0: @ %entry183; CHECK-NEXT: .save {r4, r5, r6, r7, r8, r9, r10, r11, lr}184; CHECK-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11, lr}185; CHECK-NEXT: vmov r1, r12, d1186; CHECK-NEXT: vmov r3, lr, d0187; CHECK-NEXT: vmov r5, r9, d2188; CHECK-NEXT: vmov r6, r11, d3189; CHECK-NEXT: umull r2, r8, r3, r1190; CHECK-NEXT: mla r3, r3, r12, r8191; CHECK-NEXT: umull r7, r10, r2, r5192; CHECK-NEXT: mla r1, lr, r1, r3193; CHECK-NEXT: mla r2, r2, r9, r10194; CHECK-NEXT: umull r0, r4, r7, r6195; CHECK-NEXT: mla r1, r1, r5, r2196; CHECK-NEXT: mla r4, r7, r11, r4197; CHECK-NEXT: mla r1, r1, r6, r4198; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11, pc}199entry:200 %z = call i64 @llvm.vector.reduce.mul.v4i64(<4 x i64> %x)201 ret i64 %z202}203 204define arm_aapcs_vfpcc i32 @mul_v2i32_acc(<2 x i32> %x, i32 %y) {205; CHECK-LABEL: mul_v2i32_acc:206; CHECK: @ %bb.0: @ %entry207; CHECK-NEXT: vmov r1, s2208; CHECK-NEXT: vmov r2, s0209; CHECK-NEXT: muls r1, r2, r1210; CHECK-NEXT: muls r0, r1, r0211; CHECK-NEXT: bx lr212entry:213 %z = call i32 @llvm.vector.reduce.mul.v2i32(<2 x i32> %x)214 %r = mul i32 %y, %z215 ret i32 %r216}217 218define arm_aapcs_vfpcc i32 @mul_v4i32_acc(<4 x i32> %x, i32 %y) {219; CHECK-LABEL: mul_v4i32_acc:220; CHECK: @ %bb.0: @ %entry221; CHECK-NEXT: vmov r1, r2, d1222; CHECK-NEXT: muls r1, r2, r1223; CHECK-NEXT: vmov r2, r3, d0224; CHECK-NEXT: muls r2, r3, r2225; CHECK-NEXT: muls r1, r2, r1226; CHECK-NEXT: muls r0, r1, r0227; CHECK-NEXT: bx lr228entry:229 %z = call i32 @llvm.vector.reduce.mul.v4i32(<4 x i32> %x)230 %r = mul i32 %y, %z231 ret i32 %r232}233 234define arm_aapcs_vfpcc i32 @mul_v8i32_acc(<8 x i32> %x, i32 %y) {235; CHECK-LABEL: mul_v8i32_acc:236; CHECK: @ %bb.0: @ %entry237; CHECK-NEXT: vmul.i32 q0, q0, q1238; CHECK-NEXT: vmov r1, r2, d1239; CHECK-NEXT: muls r1, r2, r1240; CHECK-NEXT: vmov r2, r3, d0241; CHECK-NEXT: muls r2, r3, r2242; CHECK-NEXT: muls r1, r2, r1243; CHECK-NEXT: muls r0, r1, r0244; CHECK-NEXT: bx lr245entry:246 %z = call i32 @llvm.vector.reduce.mul.v8i32(<8 x i32> %x)247 %r = mul i32 %y, %z248 ret i32 %r249}250 251define arm_aapcs_vfpcc i16 @mul_v4i16_acc(<4 x i16> %x, i16 %y) {252; CHECK-LABEL: mul_v4i16_acc:253; CHECK: @ %bb.0: @ %entry254; CHECK-NEXT: vmov r1, r2, d1255; CHECK-NEXT: muls r1, r2, r1256; CHECK-NEXT: vmov r2, r3, d0257; CHECK-NEXT: muls r2, r3, r2258; CHECK-NEXT: muls r1, r2, r1259; CHECK-NEXT: muls r0, r1, r0260; CHECK-NEXT: bx lr261entry:262 %z = call i16 @llvm.vector.reduce.mul.v4i16(<4 x i16> %x)263 %r = mul i16 %y, %z264 ret i16 %r265}266 267define arm_aapcs_vfpcc i16 @mul_v8i16_acc(<8 x i16> %x, i16 %y) {268; CHECK-LABEL: mul_v8i16_acc:269; CHECK: @ %bb.0: @ %entry270; CHECK-NEXT: vrev32.16 q1, q0271; CHECK-NEXT: vmul.i16 q0, q0, q1272; CHECK-NEXT: vmov.u16 r1, q0[6]273; CHECK-NEXT: vmov.u16 r2, q0[4]274; CHECK-NEXT: muls r1, r2, r1275; CHECK-NEXT: vmov.u16 r2, q0[2]276; CHECK-NEXT: vmov.u16 r3, q0[0]277; CHECK-NEXT: muls r2, r3, r2278; CHECK-NEXT: muls r1, r2, r1279; CHECK-NEXT: muls r0, r1, r0280; CHECK-NEXT: bx lr281entry:282 %z = call i16 @llvm.vector.reduce.mul.v8i16(<8 x i16> %x)283 %r = mul i16 %y, %z284 ret i16 %r285}286 287define arm_aapcs_vfpcc i16 @mul_v16i16_acc(<16 x i16> %x, i16 %y) {288; CHECK-LABEL: mul_v16i16_acc:289; CHECK: @ %bb.0: @ %entry290; CHECK-NEXT: vmul.i16 q0, q0, q1291; CHECK-NEXT: vrev32.16 q1, q0292; CHECK-NEXT: vmul.i16 q0, q0, q1293; CHECK-NEXT: vmov.u16 r1, q0[6]294; CHECK-NEXT: vmov.u16 r2, q0[4]295; CHECK-NEXT: muls r1, r2, r1296; CHECK-NEXT: vmov.u16 r2, q0[2]297; CHECK-NEXT: vmov.u16 r3, q0[0]298; CHECK-NEXT: muls r2, r3, r2299; CHECK-NEXT: muls r1, r2, r1300; CHECK-NEXT: muls r0, r1, r0301; CHECK-NEXT: bx lr302entry:303 %z = call i16 @llvm.vector.reduce.mul.v16i16(<16 x i16> %x)304 %r = mul i16 %y, %z305 ret i16 %r306}307 308define arm_aapcs_vfpcc i8 @mul_v8i8_acc(<8 x i8> %x, i8 %y) {309; CHECK-LABEL: mul_v8i8_acc:310; CHECK: @ %bb.0: @ %entry311; CHECK-NEXT: vrev32.16 q1, q0312; CHECK-NEXT: vmul.i16 q0, q0, q1313; CHECK-NEXT: vmov.u16 r1, q0[6]314; CHECK-NEXT: vmov.u16 r2, q0[4]315; CHECK-NEXT: muls r1, r2, r1316; CHECK-NEXT: vmov.u16 r2, q0[2]317; CHECK-NEXT: vmov.u16 r3, q0[0]318; CHECK-NEXT: muls r2, r3, r2319; CHECK-NEXT: muls r1, r2, r1320; CHECK-NEXT: muls r0, r1, r0321; CHECK-NEXT: bx lr322entry:323 %z = call i8 @llvm.vector.reduce.mul.v8i8(<8 x i8> %x)324 %r = mul i8 %y, %z325 ret i8 %r326}327 328define arm_aapcs_vfpcc i8 @mul_v16i8_acc(<16 x i8> %x, i8 %y) {329; CHECK-LABEL: mul_v16i8_acc:330; CHECK: @ %bb.0: @ %entry331; CHECK-NEXT: vrev16.8 q1, q0332; CHECK-NEXT: vmul.i8 q0, q0, q1333; CHECK-NEXT: vrev32.8 q1, q0334; CHECK-NEXT: vmul.i8 q0, q0, q1335; CHECK-NEXT: vmov.u8 r1, q0[12]336; CHECK-NEXT: vmov.u8 r2, q0[8]337; CHECK-NEXT: muls r1, r2, r1338; CHECK-NEXT: vmov.u8 r2, q0[4]339; CHECK-NEXT: vmov.u8 r3, q0[0]340; CHECK-NEXT: muls r2, r3, r2341; CHECK-NEXT: muls r1, r2, r1342; CHECK-NEXT: muls r0, r1, r0343; CHECK-NEXT: bx lr344entry:345 %z = call i8 @llvm.vector.reduce.mul.v16i8(<16 x i8> %x)346 %r = mul i8 %y, %z347 ret i8 %r348}349 350define arm_aapcs_vfpcc i8 @mul_v32i8_acc(<32 x i8> %x, i8 %y) {351; CHECK-LABEL: mul_v32i8_acc:352; CHECK: @ %bb.0: @ %entry353; CHECK-NEXT: vmul.i8 q0, q0, q1354; CHECK-NEXT: vrev16.8 q1, q0355; CHECK-NEXT: vmul.i8 q0, q0, q1356; CHECK-NEXT: vrev32.8 q1, q0357; CHECK-NEXT: vmul.i8 q0, q0, q1358; CHECK-NEXT: vmov.u8 r1, q0[12]359; CHECK-NEXT: vmov.u8 r2, q0[8]360; CHECK-NEXT: muls r1, r2, r1361; CHECK-NEXT: vmov.u8 r2, q0[4]362; CHECK-NEXT: vmov.u8 r3, q0[0]363; CHECK-NEXT: muls r2, r3, r2364; CHECK-NEXT: muls r1, r2, r1365; CHECK-NEXT: muls r0, r1, r0366; CHECK-NEXT: bx lr367entry:368 %z = call i8 @llvm.vector.reduce.mul.v32i8(<32 x i8> %x)369 %r = mul i8 %y, %z370 ret i8 %r371}372 373define arm_aapcs_vfpcc i64 @mul_v1i64_acc(<1 x i64> %x, i64 %y) {374; CHECK-LABEL: mul_v1i64_acc:375; CHECK: @ %bb.0: @ %entry376; CHECK-NEXT: .save {r7, lr}377; CHECK-NEXT: push {r7, lr}378; CHECK-NEXT: umull r12, lr, r2, r0379; CHECK-NEXT: mla r1, r2, r1, lr380; CHECK-NEXT: mla r1, r3, r0, r1381; CHECK-NEXT: mov r0, r12382; CHECK-NEXT: pop {r7, pc}383entry:384 %z = call i64 @llvm.vector.reduce.mul.v1i64(<1 x i64> %x)385 %r = mul i64 %y, %z386 ret i64 %r387}388 389define arm_aapcs_vfpcc i64 @mul_v2i64_acc(<2 x i64> %x, i64 %y) {390; CHECK-LABEL: mul_v2i64_acc:391; CHECK: @ %bb.0: @ %entry392; CHECK-NEXT: .save {r4, r5, r7, lr}393; CHECK-NEXT: push {r4, r5, r7, lr}394; CHECK-NEXT: vmov r2, r12, d1395; CHECK-NEXT: vmov r3, lr, d0396; CHECK-NEXT: umull r4, r5, r3, r2397; CHECK-NEXT: mla r3, r3, r12, r5398; CHECK-NEXT: mla r3, lr, r2, r3399; CHECK-NEXT: umull r2, r5, r0, r4400; CHECK-NEXT: mla r0, r0, r3, r5401; CHECK-NEXT: mla r1, r1, r4, r0402; CHECK-NEXT: mov r0, r2403; CHECK-NEXT: pop {r4, r5, r7, pc}404entry:405 %z = call i64 @llvm.vector.reduce.mul.v2i64(<2 x i64> %x)406 %r = mul i64 %y, %z407 ret i64 %r408}409 410define arm_aapcs_vfpcc i64 @mul_v4i64_acc(<4 x i64> %x, i64 %y) {411; CHECK-LABEL: mul_v4i64_acc:412; CHECK: @ %bb.0: @ %entry413; CHECK-NEXT: .save {r4, r5, r6, r7, r8, r9, r10, r11, lr}414; CHECK-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11, lr}415; CHECK-NEXT: .pad #12416; CHECK-NEXT: sub sp, #12417; CHECK-NEXT: mov lr, r0418; CHECK-NEXT: vmov r2, r0, d1419; CHECK-NEXT: vmov r6, r9, d2420; CHECK-NEXT: str r1, [sp, #8] @ 4-byte Spill421; CHECK-NEXT: vmov r7, r11, d3422; CHECK-NEXT: str r0, [sp, #4] @ 4-byte Spill423; CHECK-NEXT: vmov r3, r0, d0424; CHECK-NEXT: ldr r1, [sp, #4] @ 4-byte Reload425; CHECK-NEXT: str r0, [sp] @ 4-byte Spill426; CHECK-NEXT: umull r4, r8, r3, r2427; CHECK-NEXT: mla r3, r3, r1, r8428; CHECK-NEXT: ldr r1, [sp] @ 4-byte Reload429; CHECK-NEXT: umull r5, r10, r4, r6430; CHECK-NEXT: mla r2, r1, r2, r3431; CHECK-NEXT: mla r4, r4, r9, r10432; CHECK-NEXT: umull r0, r12, r5, r7433; CHECK-NEXT: mla r2, r2, r6, r4434; CHECK-NEXT: mla r5, r5, r11, r12435; CHECK-NEXT: mla r3, r2, r7, r5436; CHECK-NEXT: umull r2, r7, lr, r0437; CHECK-NEXT: mla r1, lr, r3, r7438; CHECK-NEXT: ldr r3, [sp, #8] @ 4-byte Reload439; CHECK-NEXT: mla r1, r3, r0, r1440; CHECK-NEXT: mov r0, r2441; CHECK-NEXT: add sp, #12442; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11, pc}443entry:444 %z = call i64 @llvm.vector.reduce.mul.v4i64(<4 x i64> %x)445 %r = mul i64 %y, %z446 ret i64 %r447}448 449declare i16 @llvm.vector.reduce.mul.v16i16(<16 x i16>)450declare i16 @llvm.vector.reduce.mul.v4i16(<4 x i16>)451declare i16 @llvm.vector.reduce.mul.v8i16(<8 x i16>)452declare i32 @llvm.vector.reduce.mul.v2i32(<2 x i32>)453declare i32 @llvm.vector.reduce.mul.v4i32(<4 x i32>)454declare i32 @llvm.vector.reduce.mul.v8i32(<8 x i32>)455declare i64 @llvm.vector.reduce.mul.v1i64(<1 x i64>)456declare i64 @llvm.vector.reduce.mul.v2i64(<2 x i64>)457declare i64 @llvm.vector.reduce.mul.v4i64(<4 x i64>)458declare i8 @llvm.vector.reduce.mul.v16i8(<16 x i8>)459declare i8 @llvm.vector.reduce.mul.v32i8(<32 x i8>)460declare i8 @llvm.vector.reduce.mul.v8i8(<8 x i8>)461