306 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s --mattr=+mve.fp,+fp64 -o - | FileCheck %s3 4target triple = "thumbv8.1m.main-none-none-eabi"5 6; Expected to transform7define arm_aapcs_vfpcc <4 x float> @simple_mul(<4 x float> %a, <4 x float> %b) {8; CHECK-LABEL: simple_mul:9; CHECK: @ %bb.0: @ %entry10; CHECK-NEXT: vcmul.f32 q2, q0, q1, #011; CHECK-NEXT: vcmla.f32 q2, q0, q1, #9012; CHECK-NEXT: vmov q0, q213; CHECK-NEXT: bx lr14entry:15 %strided.vec = shufflevector <4 x float> %a, <4 x float> poison, <2 x i32> <i32 0, i32 2>16 %strided.vec17 = shufflevector <4 x float> %a, <4 x float> poison, <2 x i32> <i32 1, i32 3>17 %strided.vec19 = shufflevector <4 x float> %b, <4 x float> poison, <2 x i32> <i32 0, i32 2>18 %strided.vec20 = shufflevector <4 x float> %b, <4 x float> poison, <2 x i32> <i32 1, i32 3>19 %0 = fmul fast <2 x float> %strided.vec20, %strided.vec20 %1 = fmul fast <2 x float> %strided.vec19, %strided.vec1721 %2 = fadd fast <2 x float> %1, %022 %3 = fmul fast <2 x float> %strided.vec19, %strided.vec23 %4 = fmul fast <2 x float> %strided.vec17, %strided.vec2024 %5 = fsub fast <2 x float> %3, %425 %interleaved.vec = shufflevector <2 x float> %5, <2 x float> %2, <4 x i32> <i32 0, i32 2, i32 1, i32 3>26 ret <4 x float> %interleaved.vec27}28 29; Expected to not transform30define arm_aapcs_vfpcc <4 x float> @simple_mul_no_contract(<4 x float> %a, <4 x float> %b) {31; CHECK-LABEL: simple_mul_no_contract:32; CHECK: @ %bb.0: @ %entry33; CHECK-NEXT: .vsave {d8, d9, d10, d11}34; CHECK-NEXT: vpush {d8, d9, d10, d11}35; CHECK-NEXT: vmov.f32 s8, s536; CHECK-NEXT: vmov.f32 s12, s137; CHECK-NEXT: vmov.f32 s9, s738; CHECK-NEXT: vmov.f32 s13, s339; CHECK-NEXT: vmov.f32 s1, s240; CHECK-NEXT: vmul.f32 q4, q3, q241; CHECK-NEXT: vmov.f32 s5, s642; CHECK-NEXT: vmul.f32 q2, q2, q043; CHECK-NEXT: vmul.f32 q5, q1, q044; CHECK-NEXT: vfma.f32 q2, q1, q345; CHECK-NEXT: vsub.f32 q4, q5, q446; CHECK-NEXT: vmov.f32 s1, s847; CHECK-NEXT: vmov.f32 s0, s1648; CHECK-NEXT: vmov.f32 s2, s1749; CHECK-NEXT: vmov.f32 s3, s950; CHECK-NEXT: vpop {d8, d9, d10, d11}51; CHECK-NEXT: bx lr52entry:53 %strided.vec = shufflevector <4 x float> %a, <4 x float> poison, <2 x i32> <i32 0, i32 2>54 %strided.vec17 = shufflevector <4 x float> %a, <4 x float> poison, <2 x i32> <i32 1, i32 3>55 %strided.vec19 = shufflevector <4 x float> %b, <4 x float> poison, <2 x i32> <i32 0, i32 2>56 %strided.vec20 = shufflevector <4 x float> %b, <4 x float> poison, <2 x i32> <i32 1, i32 3>57 %0 = fmul fast <2 x float> %strided.vec20, %strided.vec58 %1 = fmul fast <2 x float> %strided.vec19, %strided.vec1759 %2 = fadd fast <2 x float> %1, %060 %3 = fmul fast <2 x float> %strided.vec19, %strided.vec61 %4 = fmul fast <2 x float> %strided.vec17, %strided.vec2062 %5 = fsub <2 x float> %3, %463 %interleaved.vec = shufflevector <2 x float> %5, <2 x float> %2, <4 x i32> <i32 0, i32 2, i32 1, i32 3>64 ret <4 x float> %interleaved.vec65}66 67; Expected to transform68define arm_aapcs_vfpcc <4 x float> @three_way_mul(<4 x float> %a, <4 x float> %b, <4 x float> %c) {69; CHECK-LABEL: three_way_mul:70; CHECK: @ %bb.0: @ %entry71; CHECK-NEXT: vcmul.f32 q3, q1, q0, #072; CHECK-NEXT: vcmla.f32 q3, q1, q0, #9073; CHECK-NEXT: vcmul.f32 q0, q2, q3, #074; CHECK-NEXT: vcmla.f32 q0, q2, q3, #9075; CHECK-NEXT: bx lr76entry:77 %strided.vec = shufflevector <4 x float> %a, <4 x float> poison, <2 x i32> <i32 0, i32 2>78 %strided.vec39 = shufflevector <4 x float> %a, <4 x float> poison, <2 x i32> <i32 1, i32 3>79 %strided.vec41 = shufflevector <4 x float> %b, <4 x float> poison, <2 x i32> <i32 0, i32 2>80 %strided.vec42 = shufflevector <4 x float> %b, <4 x float> poison, <2 x i32> <i32 1, i32 3>81 %strided.vec44 = shufflevector <4 x float> %c, <4 x float> poison, <2 x i32> <i32 0, i32 2>82 %strided.vec45 = shufflevector <4 x float> %c, <4 x float> poison, <2 x i32> <i32 1, i32 3>83 %0 = fmul fast <2 x float> %strided.vec41, %strided.vec84 %1 = fmul fast <2 x float> %strided.vec42, %strided.vec3985 %2 = fsub fast <2 x float> %0, %186 %3 = fmul fast <2 x float> %2, %strided.vec4587 %4 = fmul fast <2 x float> %strided.vec42, %strided.vec88 %5 = fmul fast <2 x float> %strided.vec39, %strided.vec4189 %6 = fadd fast <2 x float> %4, %590 %7 = fmul fast <2 x float> %6, %strided.vec4491 %8 = fadd fast <2 x float> %3, %792 %9 = fmul fast <2 x float> %2, %strided.vec4493 %10 = fmul fast <2 x float> %6, %strided.vec4594 %11 = fsub fast <2 x float> %9, %1095 %interleaved.vec = shufflevector <2 x float> %11, <2 x float> %8, <4 x i32> <i32 0, i32 2, i32 1, i32 3>96 ret <4 x float> %interleaved.vec97}98 99; Expected to transform100define arm_aapcs_vfpcc <4 x float> @simple_add_90(<4 x float> %a, <4 x float> %b) {101; CHECK-LABEL: simple_add_90:102; CHECK: @ %bb.0: @ %entry103; CHECK-NEXT: vcadd.f32 q2, q1, q0, #90104; CHECK-NEXT: vmov q0, q2105; CHECK-NEXT: bx lr106entry:107 %strided.vec = shufflevector <4 x float> %a, <4 x float> poison, <2 x i32> <i32 0, i32 2>108 %strided.vec17 = shufflevector <4 x float> %a, <4 x float> poison, <2 x i32> <i32 1, i32 3>109 %strided.vec19 = shufflevector <4 x float> %b, <4 x float> poison, <2 x i32> <i32 0, i32 2>110 %strided.vec20 = shufflevector <4 x float> %b, <4 x float> poison, <2 x i32> <i32 1, i32 3>111 %0 = fsub fast <2 x float> %strided.vec19, %strided.vec17112 %1 = fadd fast <2 x float> %strided.vec20, %strided.vec113 %interleaved.vec = shufflevector <2 x float> %0, <2 x float> %1, <4 x i32> <i32 0, i32 2, i32 1, i32 3>114 ret <4 x float> %interleaved.vec115}116 117; Expected to not transform, fadd commutativity is not yet implemented118define arm_aapcs_vfpcc <4 x float> @simple_add_270_false(<4 x float> %a, <4 x float> %b) {119; CHECK-LABEL: simple_add_270_false:120; CHECK: @ %bb.0: @ %entry121; CHECK-NEXT: vcadd.f32 q2, q0, q1, #270122; CHECK-NEXT: vmov q0, q2123; CHECK-NEXT: bx lr124entry:125 %strided.vec = shufflevector <4 x float> %a, <4 x float> poison, <2 x i32> <i32 0, i32 2>126 %strided.vec17 = shufflevector <4 x float> %a, <4 x float> poison, <2 x i32> <i32 1, i32 3>127 %strided.vec19 = shufflevector <4 x float> %b, <4 x float> poison, <2 x i32> <i32 0, i32 2>128 %strided.vec20 = shufflevector <4 x float> %b, <4 x float> poison, <2 x i32> <i32 1, i32 3>129 %0 = fadd fast <2 x float> %strided.vec20, %strided.vec130 %1 = fsub fast <2 x float> %strided.vec17, %strided.vec19131 %interleaved.vec = shufflevector <2 x float> %0, <2 x float> %1, <4 x i32> <i32 0, i32 2, i32 1, i32 3>132 ret <4 x float> %interleaved.vec133}134 135; Expected to transform136define arm_aapcs_vfpcc <4 x float> @simple_add_270_true(<4 x float> %a, <4 x float> %b) {137; CHECK-LABEL: simple_add_270_true:138; CHECK: @ %bb.0: @ %entry139; CHECK-NEXT: vcadd.f32 q2, q0, q1, #270140; CHECK-NEXT: vmov q0, q2141; CHECK-NEXT: bx lr142entry:143 %strided.vec = shufflevector <4 x float> %a, <4 x float> poison, <2 x i32> <i32 0, i32 2>144 %strided.vec17 = shufflevector <4 x float> %a, <4 x float> poison, <2 x i32> <i32 1, i32 3>145 %strided.vec19 = shufflevector <4 x float> %b, <4 x float> poison, <2 x i32> <i32 0, i32 2>146 %strided.vec20 = shufflevector <4 x float> %b, <4 x float> poison, <2 x i32> <i32 1, i32 3>147 %0 = fadd fast <2 x float> %strided.vec, %strided.vec20148 %1 = fsub fast <2 x float> %strided.vec17, %strided.vec19149 %interleaved.vec = shufflevector <2 x float> %0, <2 x float> %1, <4 x i32> <i32 0, i32 2, i32 1, i32 3>150 ret <4 x float> %interleaved.vec151}152 153; Expected to not transform154define arm_aapcs_vfpcc <4 x float> @add_external_use(<4 x float> %a, <4 x float> %b) {155; CHECK-LABEL: add_external_use:156; CHECK: @ %bb.0: @ %entry157; CHECK-NEXT: vmov.f32 s8, s4158; CHECK-NEXT: vmov.f32 s12, s1159; CHECK-NEXT: vmov.f32 s4, s5160; CHECK-NEXT: vmov.f32 s9, s6161; CHECK-NEXT: vmov.f32 s13, s3162; CHECK-NEXT: vmov.f32 s5, s7163; CHECK-NEXT: vadd.f32 q2, q3, q2164; CHECK-NEXT: vmov.f32 s1, s2165; CHECK-NEXT: vsub.f32 q1, q0, q1166; CHECK-NEXT: vmov.f32 s1, s8167; CHECK-NEXT: vmov.f32 s0, s4168; CHECK-NEXT: vmov.f32 s2, s5169; CHECK-NEXT: vmov.f32 s3, s9170; CHECK-NEXT: bx lr171entry:172 %a.real = shufflevector <4 x float> %a, <4 x float> poison, <2 x i32> <i32 0, i32 2>173 %a.imag = shufflevector <4 x float> %a, <4 x float> poison, <2 x i32> <i32 1, i32 3>174 %b.real = shufflevector <4 x float> %b, <4 x float> poison, <2 x i32> <i32 0, i32 2>175 %b.imag = shufflevector <4 x float> %b, <4 x float> poison, <2 x i32> <i32 1, i32 3>176 %0 = fsub fast <2 x float> %a.real, %b.imag177 %1 = fadd fast <2 x float> %a.imag, %b.real178 %interleaved.vec = shufflevector <2 x float> %0, <2 x float> %1, <4 x i32> <i32 0, i32 2, i32 1, i32 3>179 %dup = shufflevector <2 x float> %0, <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 0, i32 1>180 %interleaved.vec2 = shufflevector <4 x float> %interleaved.vec, <4 x float> %dup, <4 x i32> <i32 0, i32 1, i32 2, i32 3>181 ret <4 x float> %interleaved.vec2182}183 184define arm_aapcs_vfpcc <4 x float> @mul_mul_with_fneg(<4 x float> %a, <4 x float> %b) {185; CHECK-LABEL: mul_mul_with_fneg:186; CHECK: @ %bb.0: @ %entry187; CHECK-NEXT: vcmul.f32 q2, q1, q0, #270188; CHECK-NEXT: vcmla.f32 q2, q1, q0, #180189; CHECK-NEXT: vmov q0, q2190; CHECK-NEXT: bx lr191entry:192 %a.real = shufflevector <4 x float> %a, <4 x float> poison, <2 x i32> <i32 0, i32 2>193 %a.imag = shufflevector <4 x float> %a, <4 x float> poison, <2 x i32> <i32 1, i32 3>194 %b.real = shufflevector <4 x float> %b, <4 x float> poison, <2 x i32> <i32 0, i32 2>195 %b.imag = shufflevector <4 x float> %b, <4 x float> poison, <2 x i32> <i32 1, i32 3>196 %0 = fneg fast <2 x float> %a.imag197 %1 = fmul fast <2 x float> %b.real, %0198 %2 = fmul fast <2 x float> %a.real, %b.imag199 %3 = fsub fast <2 x float> %1, %2200 %4 = fmul fast <2 x float> %b.imag, %a.imag201 %5 = fmul fast <2 x float> %a.real, %b.real202 %6 = fsub fast <2 x float> %4, %5203 %interleaved.vec = shufflevector <2 x float> %6, <2 x float> %3, <4 x i32> <i32 0, i32 2, i32 1, i32 3>204 ret <4 x float> %interleaved.vec205}206 207; Expected to not transform208define arm_aapcs_vfpcc <12 x float> @abp90c12(<12 x float> %a, <12 x float> %b, <12 x float> %c) {209; CHECK-LABEL: abp90c12:210; CHECK: @ %bb.0: @ %entry211; CHECK-NEXT: .vsave {d8, d9, d10, d11, d12, d13, d14, d15}212; CHECK-NEXT: vpush {d8, d9, d10, d11, d12, d13, d14, d15}213; CHECK-NEXT: .pad #64214; CHECK-NEXT: sub sp, #64215; CHECK-NEXT: vmov.f32 s21, s11216; CHECK-NEXT: vldr s31, [sp, #140]217; CHECK-NEXT: vmov.f32 s20, s9218; CHECK-NEXT: vldr s30, [sp, #132]219; CHECK-NEXT: vstrw.32 q5, [sp, #32] @ 16-byte Spill220; CHECK-NEXT: vmov.f32 s28, s13221; CHECK-NEXT: vmov.f32 s23, s6222; CHECK-NEXT: vldr s19, [sp, #136]223; CHECK-NEXT: vmov.f32 s6, s5224; CHECK-NEXT: vldr s18, [sp, #128]225; CHECK-NEXT: vmov.f32 s22, s4226; CHECK-NEXT: vldr s27, [sp, #184]227; CHECK-NEXT: vmov.f32 s29, s15228; CHECK-NEXT: vldr s26, [sp, #176]229; CHECK-NEXT: vmov.f32 s5, s3230; CHECK-NEXT: vldr s25, [sp, #168]231; CHECK-NEXT: vmov.f32 s4, s1232; CHECK-NEXT: vldr s24, [sp, #160]233; CHECK-NEXT: vmov.f32 s16, s12234; CHECK-NEXT: vldr s11, [sp, #188]235; CHECK-NEXT: vmov.f32 s17, s14236; CHECK-NEXT: vldr s9, [sp, #172]237; CHECK-NEXT: vmov.f32 s21, s2238; CHECK-NEXT: vmov.f32 s20, s0239; CHECK-NEXT: vmul.f32 q0, q7, q1240; CHECK-NEXT: vmul.f32 q1, q4, q1241; CHECK-NEXT: vneg.f32 q0, q0242; CHECK-NEXT: vstrw.32 q0, [sp, #16] @ 16-byte Spill243; CHECK-NEXT: vfma.f32 q1, q7, q5244; CHECK-NEXT: vsub.f32 q7, q6, q1245; CHECK-NEXT: vldrw.u32 q1, [sp, #16] @ 16-byte Reload246; CHECK-NEXT: vmov.f32 s13, s10247; CHECK-NEXT: vldr s10, [sp, #180]248; CHECK-NEXT: vmov.f32 s12, s8249; CHECK-NEXT: vfma.f32 q1, q4, q5250; CHECK-NEXT: vstrw.32 q3, [sp, #48] @ 16-byte Spill251; CHECK-NEXT: vldr s8, [sp, #164]252; CHECK-NEXT: vldr s13, [sp, #156]253; CHECK-NEXT: vldrw.u32 q5, [sp, #32] @ 16-byte Reload254; CHECK-NEXT: vldr s12, [sp, #148]255; CHECK-NEXT: vadd.f32 q1, q2, q1256; CHECK-NEXT: vldr s1, [sp, #152]257; CHECK-NEXT: vmul.f32 q2, q3, q5258; CHECK-NEXT: vstrw.32 q3, [sp] @ 16-byte Spill259; CHECK-NEXT: vldr s0, [sp, #144]260; CHECK-NEXT: vldrw.u32 q3, [sp, #48] @ 16-byte Reload261; CHECK-NEXT: vneg.f32 q2, q2262; CHECK-NEXT: vldr s25, [sp, #200]263; CHECK-NEXT: vfma.f32 q2, q0, q3264; CHECK-NEXT: vmul.f32 q0, q0, q5265; CHECK-NEXT: vldrw.u32 q5, [sp] @ 16-byte Reload266; CHECK-NEXT: vldr s24, [sp, #192]267; CHECK-NEXT: vldr s17, [sp, #204]268; CHECK-NEXT: vldr s16, [sp, #196]269; CHECK-NEXT: vfma.f32 q0, q5, q3270; CHECK-NEXT: vsub.f32 q3, q6, q0271; CHECK-NEXT: vmov.f32 s1, s4272; CHECK-NEXT: vadd.f32 q4, q4, q2273; CHECK-NEXT: vmov.f32 s3, s5274; CHECK-NEXT: vmov.f32 s5, s6275; CHECK-NEXT: vmov.f32 s0, s28276; CHECK-NEXT: vmov.f32 s2, s29277; CHECK-NEXT: vmov.f32 s4, s30278; CHECK-NEXT: vmov.f32 s6, s31279; CHECK-NEXT: vmov.f32 s8, s12280; CHECK-NEXT: vmov.f32 s9, s16281; CHECK-NEXT: vmov.f32 s10, s13282; CHECK-NEXT: vmov.f32 s11, s17283; CHECK-NEXT: add sp, #64284; CHECK-NEXT: vpop {d8, d9, d10, d11, d12, d13, d14, d15}285; CHECK-NEXT: bx lr286entry:287 %ar = shufflevector <12 x float> %a, <12 x float> poison, <6 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10>288 %ai = shufflevector <12 x float> %a, <12 x float> poison, <6 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11>289 %br = shufflevector <12 x float> %b, <12 x float> poison, <6 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10>290 %bi = shufflevector <12 x float> %b, <12 x float> poison, <6 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11>291 %cr = shufflevector <12 x float> %c, <12 x float> poison, <6 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10>292 %ci = shufflevector <12 x float> %c, <12 x float> poison, <6 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11>293 294 %i6 = fmul fast <6 x float> %br, %ar295 %i7 = fmul fast <6 x float> %bi, %ai296 %xr = fsub fast <6 x float> %i6, %i7297 %i9 = fmul fast <6 x float> %bi, %ar298 %i10 = fmul fast <6 x float> %br, %ai299 %xi = fadd fast <6 x float> %i9, %i10300 301 %zr = fsub fast <6 x float> %cr, %xi302 %zi = fadd fast <6 x float> %ci, %xr303 %interleaved.vec = shufflevector <6 x float> %zr, <6 x float> %zi, <12 x i32> <i32 0, i32 6, i32 1, i32 7, i32 2, i32 8, i32 3, i32 9, i32 4, i32 10, i32 5, i32 11>304 ret <12 x float> %interleaved.vec305}306