1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s --mattr=+complxnum,+neon -o - | FileCheck %s 3 4target triple = "aarch64" 5 6; a * b + c 7define <4 x double> @mull_add(<4 x double> %a, <4 x double> %b, <4 x double> %c) { 8; CHECK-LABEL: mull_add: 9; CHECK: // %bb.0: // %entry 10; CHECK-NEXT: zip2 v4.2d, v2.2d, v3.2d 11; CHECK-NEXT: zip2 v5.2d, v0.2d, v1.2d 12; CHECK-NEXT: zip1 v0.2d, v0.2d, v1.2d 13; CHECK-NEXT: zip1 v2.2d, v2.2d, v3.2d 14; CHECK-NEXT: fmul v1.2d, v5.2d, v4.2d 15; CHECK-NEXT: fmul v3.2d, v0.2d, v4.2d 16; CHECK-NEXT: fneg v1.2d, v1.2d 17; CHECK-NEXT: fmla v3.2d, v2.2d, v5.2d 18; CHECK-NEXT: fmla v1.2d, v2.2d, v0.2d 19; CHECK-NEXT: fadd v1.2d, v2.2d, v1.2d 20; CHECK-NEXT: fadd v2.2d, v3.2d, v4.2d 21; CHECK-NEXT: zip1 v0.2d, v1.2d, v2.2d 22; CHECK-NEXT: zip2 v1.2d, v1.2d, v2.2d 23; CHECK-NEXT: ret 24entry: 25 %strided.vec = shufflevector <4 x double> %a, <4 x double> poison, <2 x i32> <i32 0, i32 2> 26 %strided.vec28 = shufflevector <4 x double> %a, <4 x double> poison, <2 x i32> <i32 1, i32 3> 27 %strided.vec30 = shufflevector <4 x double> %b, <4 x double> poison, <2 x i32> <i32 0, i32 2> 28 %strided.vec31 = shufflevector <4 x double> %b, <4 x double> poison, <2 x i32> <i32 1, i32 3> 29 %0 = fmul contract <2 x double> %strided.vec, %strided.vec31 30 %1 = fmul contract <2 x double> %strided.vec28, %strided.vec30 31 %2 = fadd contract <2 x double> %1, %0 32 %3 = fmul contract <2 x double> %strided.vec, %strided.vec30 33 %4 = fmul contract <2 x double> %strided.vec28, %strided.vec31 34 %5 = fsub contract <2 x double> %3, %4 35 %strided.vec33 = shufflevector <4 x double> %b, <4 x double> poison, <2 x i32> <i32 0, i32 2> 36 %strided.vec34 = shufflevector <4 x double> %b, <4 x double> poison, <2 x i32> <i32 1, i32 3> 37 %6 = fadd contract <2 x double> %strided.vec33, %5 38 %7 = fadd contract <2 x double> %2, %strided.vec34 39 %interleaved.vec = shufflevector <2 x double> %6, <2 x double> %7, <4 x i32> <i32 0, i32 2, i32 1, i32 3> 40 ret <4 x double> %interleaved.vec 41} 42 43; a * b + c * d 44define <4 x double> @mul_add_mull(<4 x double> %a, <4 x double> %b, <4 x double> %c, <4 x double> %d) { 45; CHECK-LABEL: mul_add_mull: 46; CHECK: // %bb.0: // %entry 47; CHECK-NEXT: movi v16.2d, #0000000000000000 48; CHECK-NEXT: movi v17.2d, #0000000000000000 49; CHECK-NEXT: movi v18.2d, #0000000000000000 50; CHECK-NEXT: movi v19.2d, #0000000000000000 51; CHECK-NEXT: fcmla v16.2d, v2.2d, v0.2d, #0 52; CHECK-NEXT: fcmla v18.2d, v3.2d, v1.2d, #0 53; CHECK-NEXT: fcmla v17.2d, v7.2d, v5.2d, #0 54; CHECK-NEXT: fcmla v19.2d, v6.2d, v4.2d, #0 55; CHECK-NEXT: fcmla v16.2d, v2.2d, v0.2d, #90 56; CHECK-NEXT: fcmla v18.2d, v3.2d, v1.2d, #90 57; CHECK-NEXT: fcmla v17.2d, v7.2d, v5.2d, #90 58; CHECK-NEXT: fcmla v19.2d, v6.2d, v4.2d, #90 59; CHECK-NEXT: fadd v1.2d, v18.2d, v17.2d 60; CHECK-NEXT: fadd v0.2d, v16.2d, v19.2d 61; CHECK-NEXT: ret 62entry: 63 %strided.vec = shufflevector <4 x double> %a, <4 x double> poison, <2 x i32> <i32 0, i32 2> 64 %strided.vec51 = shufflevector <4 x double> %a, <4 x double> poison, <2 x i32> <i32 1, i32 3> 65 %strided.vec53 = shufflevector <4 x double> %b, <4 x double> poison, <2 x i32> <i32 0, i32 2> 66 %strided.vec54 = shufflevector <4 x double> %b, <4 x double> poison, <2 x i32> <i32 1, i32 3> 67 %0 = fmul contract <2 x double> %strided.vec, %strided.vec54 68 %1 = fmul contract <2 x double> %strided.vec51, %strided.vec53 69 %2 = fadd contract <2 x double> %1, %0 70 %3 = fmul contract <2 x double> %strided.vec, %strided.vec53 71 %4 = fmul contract <2 x double> %strided.vec51, %strided.vec54 72 %5 = fsub contract <2 x double> %3, %4 73 %strided.vec56 = shufflevector <4 x double> %c, <4 x double> poison, <2 x i32> <i32 0, i32 2> 74 %strided.vec57 = shufflevector <4 x double> %c, <4 x double> poison, <2 x i32> <i32 1, i32 3> 75 %strided.vec59 = shufflevector <4 x double> %d, <4 x double> poison, <2 x i32> <i32 0, i32 2> 76 %strided.vec60 = shufflevector <4 x double> %d, <4 x double> poison, <2 x i32> <i32 1, i32 3> 77 %6 = fmul contract <2 x double> %strided.vec56, %strided.vec60 78 %7 = fmul contract <2 x double> %strided.vec57, %strided.vec59 79 %8 = fadd contract <2 x double> %7, %6 80 %9 = fmul contract <2 x double> %strided.vec56, %strided.vec59 81 %10 = fmul contract <2 x double> %strided.vec57, %strided.vec60 82 %11 = fsub contract <2 x double> %9, %10 83 %12 = fadd contract <2 x double> %5, %11 84 %13 = fadd contract <2 x double> %2, %8 85 %interleaved.vec = shufflevector <2 x double> %12, <2 x double> %13, <4 x i32> <i32 0, i32 2, i32 1, i32 3> 86 ret <4 x double> %interleaved.vec 87} 88 89; a * b - c * d 90define <4 x double> @mul_sub_mull(<4 x double> %a, <4 x double> %b, <4 x double> %c, <4 x double> %d) { 91; CHECK-LABEL: mul_sub_mull: 92; CHECK: // %bb.0: // %entry 93; CHECK-NEXT: movi v16.2d, #0000000000000000 94; CHECK-NEXT: movi v17.2d, #0000000000000000 95; CHECK-NEXT: movi v18.2d, #0000000000000000 96; CHECK-NEXT: movi v19.2d, #0000000000000000 97; CHECK-NEXT: fcmla v16.2d, v2.2d, v0.2d, #0 98; CHECK-NEXT: fcmla v18.2d, v3.2d, v1.2d, #0 99; CHECK-NEXT: fcmla v17.2d, v7.2d, v5.2d, #0 100; CHECK-NEXT: fcmla v19.2d, v6.2d, v4.2d, #0 101; CHECK-NEXT: fcmla v16.2d, v2.2d, v0.2d, #90 102; CHECK-NEXT: fcmla v18.2d, v3.2d, v1.2d, #90 103; CHECK-NEXT: fcmla v17.2d, v7.2d, v5.2d, #90 104; CHECK-NEXT: fcmla v19.2d, v6.2d, v4.2d, #90 105; CHECK-NEXT: fsub v1.2d, v18.2d, v17.2d 106; CHECK-NEXT: fsub v0.2d, v16.2d, v19.2d 107; CHECK-NEXT: ret 108entry: 109 %strided.vec = shufflevector <4 x double> %a, <4 x double> poison, <2 x i32> <i32 0, i32 2> 110 %strided.vec51 = shufflevector <4 x double> %a, <4 x double> poison, <2 x i32> <i32 1, i32 3> 111 %strided.vec53 = shufflevector <4 x double> %b, <4 x double> poison, <2 x i32> <i32 0, i32 2> 112 %strided.vec54 = shufflevector <4 x double> %b, <4 x double> poison, <2 x i32> <i32 1, i32 3> 113 %0 = fmul contract <2 x double> %strided.vec, %strided.vec54 114 %1 = fmul contract <2 x double> %strided.vec51, %strided.vec53 115 %2 = fadd contract <2 x double> %1, %0 116 %3 = fmul contract <2 x double> %strided.vec, %strided.vec53 117 %4 = fmul contract <2 x double> %strided.vec51, %strided.vec54 118 %5 = fsub contract <2 x double> %3, %4 119 %strided.vec56 = shufflevector <4 x double> %c, <4 x double> poison, <2 x i32> <i32 0, i32 2> 120 %strided.vec57 = shufflevector <4 x double> %c, <4 x double> poison, <2 x i32> <i32 1, i32 3> 121 %strided.vec59 = shufflevector <4 x double> %d, <4 x double> poison, <2 x i32> <i32 0, i32 2> 122 %strided.vec60 = shufflevector <4 x double> %d, <4 x double> poison, <2 x i32> <i32 1, i32 3> 123 %6 = fmul contract <2 x double> %strided.vec56, %strided.vec60 124 %7 = fmul contract <2 x double> %strided.vec57, %strided.vec59 125 %8 = fadd contract <2 x double> %7, %6 126 %9 = fmul contract <2 x double> %strided.vec56, %strided.vec59 127 %10 = fmul contract <2 x double> %strided.vec57, %strided.vec60 128 %11 = fsub contract <2 x double> %9, %10 129 %12 = fsub contract <2 x double> %5, %11 130 %13 = fsub contract <2 x double> %2, %8 131 %interleaved.vec = shufflevector <2 x double> %12, <2 x double> %13, <4 x i32> <i32 0, i32 2, i32 1, i32 3> 132 ret <4 x double> %interleaved.vec 133} 134 135; a * b + conj(c) * d 136define <4 x double> @mul_conj_mull(<4 x double> %a, <4 x double> %b, <4 x double> %c, <4 x double> %d) { 137; CHECK-LABEL: mul_conj_mull: 138; CHECK: // %bb.0: // %entry 139; CHECK-NEXT: movi v16.2d, #0000000000000000 140; CHECK-NEXT: movi v17.2d, #0000000000000000 141; CHECK-NEXT: movi v18.2d, #0000000000000000 142; CHECK-NEXT: movi v19.2d, #0000000000000000 143; CHECK-NEXT: fcmla v16.2d, v2.2d, v0.2d, #0 144; CHECK-NEXT: fcmla v18.2d, v3.2d, v1.2d, #0 145; CHECK-NEXT: fcmla v17.2d, v5.2d, v7.2d, #0 146; CHECK-NEXT: fcmla v19.2d, v4.2d, v6.2d, #0 147; CHECK-NEXT: fcmla v16.2d, v2.2d, v0.2d, #90 148; CHECK-NEXT: fcmla v18.2d, v3.2d, v1.2d, #90 149; CHECK-NEXT: fcmla v17.2d, v5.2d, v7.2d, #270 150; CHECK-NEXT: fcmla v19.2d, v4.2d, v6.2d, #270 151; CHECK-NEXT: fadd v1.2d, v18.2d, v17.2d 152; CHECK-NEXT: fadd v0.2d, v16.2d, v19.2d 153; CHECK-NEXT: ret 154entry: 155 %strided.vec = shufflevector <4 x double> %a, <4 x double> poison, <2 x i32> <i32 0, i32 2> 156 %strided.vec59 = shufflevector <4 x double> %a, <4 x double> poison, <2 x i32> <i32 1, i32 3> 157 %strided.vec61 = shufflevector <4 x double> %b, <4 x double> poison, <2 x i32> <i32 0, i32 2> 158 %strided.vec62 = shufflevector <4 x double> %b, <4 x double> poison, <2 x i32> <i32 1, i32 3> 159 %0 = fmul contract <2 x double> %strided.vec, %strided.vec62 160 %1 = fmul contract <2 x double> %strided.vec59, %strided.vec61 161 %2 = fadd contract <2 x double> %1, %0 162 %3 = fmul contract <2 x double> %strided.vec, %strided.vec61 163 %4 = fmul contract <2 x double> %strided.vec59, %strided.vec62 164 %5 = fsub contract <2 x double> %3, %4 165 %strided.vec64 = shufflevector <4 x double> %c, <4 x double> poison, <2 x i32> <i32 0, i32 2> 166 %strided.vec65 = shufflevector <4 x double> %c, <4 x double> poison, <2 x i32> <i32 1, i32 3> 167 %strided.vec67 = shufflevector <4 x double> %d, <4 x double> poison, <2 x i32> <i32 0, i32 2> 168 %strided.vec68 = shufflevector <4 x double> %d, <4 x double> poison, <2 x i32> <i32 1, i32 3> 169 %6 = fmul contract <2 x double> %strided.vec64, %strided.vec68 170 %7 = fmul contract <2 x double> %strided.vec65, %strided.vec67 171 %8 = fsub contract <2 x double> %6, %7 172 %9 = fmul contract <2 x double> %strided.vec64, %strided.vec67 173 %10 = fmul contract <2 x double> %strided.vec65, %strided.vec68 174 %11 = fadd contract <2 x double> %9, %10 175 %12 = fadd contract <2 x double> %5, %11 176 %13 = fadd contract <2 x double> %2, %8 177 %interleaved.vec = shufflevector <2 x double> %12, <2 x double> %13, <4 x i32> <i32 0, i32 2, i32 1, i32 3> 178 ret <4 x double> %interleaved.vec 179} 180 181; a + b + 1i * c * d 182define <4 x double> @mul_add_rot_mull(<4 x double> %a, <4 x double> %b, <4 x double> %c, <4 x double> %d) { 183; CHECK-LABEL: mul_add_rot_mull: 184; CHECK: // %bb.0: // %entry 185; CHECK-NEXT: movi v16.2d, #0xffffffffffffffff 186; CHECK-NEXT: zip2 v17.2d, v4.2d, v5.2d 187; CHECK-NEXT: movi v18.2d, #0000000000000000 188; CHECK-NEXT: zip1 v4.2d, v4.2d, v5.2d 189; CHECK-NEXT: zip2 v19.2d, v0.2d, v1.2d 190; CHECK-NEXT: zip2 v20.2d, v2.2d, v3.2d 191; CHECK-NEXT: zip1 v0.2d, v0.2d, v1.2d 192; CHECK-NEXT: zip1 v2.2d, v2.2d, v3.2d 193; CHECK-NEXT: fneg v16.2d, v16.2d 194; CHECK-NEXT: fmul v1.2d, v19.2d, v20.2d 195; CHECK-NEXT: fmul v3.2d, v0.2d, v20.2d 196; CHECK-NEXT: mov v5.16b, v16.16b 197; CHECK-NEXT: bsl v16.16b, v18.16b, v4.16b 198; CHECK-NEXT: fneg v1.2d, v1.2d 199; CHECK-NEXT: fmla v3.2d, v2.2d, v19.2d 200; CHECK-NEXT: bsl v5.16b, v18.16b, v17.16b 201; CHECK-NEXT: fsub v16.2d, v16.2d, v17.2d 202; CHECK-NEXT: fmla v1.2d, v2.2d, v0.2d 203; CHECK-NEXT: fadd v4.2d, v4.2d, v5.2d 204; CHECK-NEXT: zip2 v5.2d, v6.2d, v7.2d 205; CHECK-NEXT: zip1 v6.2d, v6.2d, v7.2d 206; CHECK-NEXT: fmul v17.2d, v4.2d, v5.2d 207; CHECK-NEXT: fmul v5.2d, v16.2d, v5.2d 208; CHECK-NEXT: fneg v7.2d, v17.2d 209; CHECK-NEXT: fmla v5.2d, v4.2d, v6.2d 210; CHECK-NEXT: fmla v7.2d, v6.2d, v16.2d 211; CHECK-NEXT: fadd v2.2d, v3.2d, v5.2d 212; CHECK-NEXT: fadd v1.2d, v1.2d, v7.2d 213; CHECK-NEXT: zip1 v0.2d, v1.2d, v2.2d 214; CHECK-NEXT: zip2 v1.2d, v1.2d, v2.2d 215; CHECK-NEXT: ret 216entry: 217 %strided.vec = shufflevector <4 x double> %a, <4 x double> poison, <2 x i32> <i32 0, i32 2> 218 %strided.vec77 = shufflevector <4 x double> %a, <4 x double> poison, <2 x i32> <i32 1, i32 3> 219 %strided.vec79 = shufflevector <4 x double> %b, <4 x double> poison, <2 x i32> <i32 0, i32 2> 220 %strided.vec80 = shufflevector <4 x double> %b, <4 x double> poison, <2 x i32> <i32 1, i32 3> 221 %0 = fmul contract <2 x double> %strided.vec, %strided.vec80 222 %1 = fmul contract <2 x double> %strided.vec77, %strided.vec79 223 %2 = fadd contract <2 x double> %1, %0 224 %3 = fmul contract <2 x double> %strided.vec, %strided.vec79 225 %4 = fmul contract <2 x double> %strided.vec77, %strided.vec80 226 %5 = fsub contract <2 x double> %3, %4 227 %strided.vec82 = shufflevector <4 x double> %c, <4 x double> poison, <2 x i32> <i32 0, i32 2> 228 %strided.vec83 = shufflevector <4 x double> %c, <4 x double> poison, <2 x i32> <i32 1, i32 3> 229 %6 = tail call contract <2 x double> @llvm.copysign.v2f64(<2 x double> zeroinitializer, <2 x double> %strided.vec83) 230 %7 = fadd contract <2 x double> %strided.vec82, %6 231 %8 = tail call contract <2 x double> @llvm.copysign.v2f64(<2 x double> zeroinitializer, <2 x double> %strided.vec82) 232 %9 = fsub contract <2 x double> %8, %strided.vec83 233 %strided.vec85 = shufflevector <4 x double> %d, <4 x double> poison, <2 x i32> <i32 0, i32 2> 234 %strided.vec86 = shufflevector <4 x double> %d, <4 x double> poison, <2 x i32> <i32 1, i32 3> 235 %10 = fmul contract <2 x double> %9, %strided.vec86 236 %11 = fmul contract <2 x double> %strided.vec85, %7 237 %12 = fadd contract <2 x double> %11, %10 238 %13 = fmul contract <2 x double> %9, %strided.vec85 239 %14 = fmul contract <2 x double> %7, %strided.vec86 240 %15 = fsub contract <2 x double> %13, %14 241 %16 = fadd contract <2 x double> %5, %15 242 %17 = fadd contract <2 x double> %2, %12 243 %interleaved.vec = shufflevector <2 x double> %16, <2 x double> %17, <4 x i32> <i32 0, i32 2, i32 1, i32 3> 244 ret <4 x double> %interleaved.vec 245} 246 247declare <2 x double> @llvm.copysign.v2f64(<2 x double>, <2 x double>) 248