1 ; RUN: llc -asm-verbose=false < %s -march=arm64 -aarch64-neon-syntax=apple | FileCheck %s 2 3 4 define <8 x i16> @smull8h(<8 x i8>* %A, <8 x i8>* %B) nounwind { 5 ;CHECK-LABEL: smull8h: 6 ;CHECK: smull.8h 7 %tmp1 = load <8 x i8>, <8 x i8>* %A 8 %tmp2 = load <8 x i8>, <8 x i8>* %B 9 %tmp3 = call <8 x i16> @llvm.aarch64.neon.smull.v8i16(<8 x i8> %tmp1, <8 x i8> %tmp2) 10 ret <8 x i16> %tmp3 11 } 12 13 define <4 x i32> @smull4s(<4 x i16>* %A, <4 x i16>* %B) nounwind { 14 ;CHECK-LABEL: smull4s: 15 ;CHECK: smull.4s 16 %tmp1 = load <4 x i16>, <4 x i16>* %A 17 %tmp2 = load <4 x i16>, <4 x i16>* %B 18 %tmp3 = call <4 x i32> @llvm.aarch64.neon.smull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp2) 19 ret <4 x i32> %tmp3 20 } 21 22 define <2 x i64> @smull2d(<2 x i32>* %A, <2 x i32>* %B) nounwind { 23 ;CHECK-LABEL: smull2d: 24 ;CHECK: smull.2d 25 %tmp1 = load <2 x i32>, <2 x i32>* %A 26 %tmp2 = load <2 x i32>, <2 x i32>* %B 27 %tmp3 = call <2 x i64> @llvm.aarch64.neon.smull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp2) 28 ret <2 x i64> %tmp3 29 } 30 31 declare <8 x i16> @llvm.aarch64.neon.smull.v8i16(<8 x i8>, <8 x i8>) nounwind readnone 32 declare <4 x i32> @llvm.aarch64.neon.smull.v4i32(<4 x i16>, <4 x i16>) nounwind readnone 33 declare <2 x i64> @llvm.aarch64.neon.smull.v2i64(<2 x i32>, <2 x i32>) nounwind readnone 34 35 define <8 x i16> @umull8h(<8 x i8>* %A, <8 x i8>* %B) nounwind { 36 ;CHECK-LABEL: umull8h: 37 ;CHECK: umull.8h 38 %tmp1 = load <8 x i8>, <8 x i8>* %A 39 %tmp2 = load <8 x i8>, <8 x i8>* %B 40 %tmp3 = call <8 x i16> @llvm.aarch64.neon.umull.v8i16(<8 x i8> %tmp1, <8 x i8> %tmp2) 41 ret <8 x i16> %tmp3 42 } 43 44 define <4 x i32> @umull4s(<4 x i16>* %A, <4 x i16>* %B) nounwind { 45 ;CHECK-LABEL: umull4s: 46 ;CHECK: umull.4s 47 %tmp1 = load <4 x i16>, <4 x i16>* %A 48 %tmp2 = load <4 x i16>, <4 x i16>* %B 49 %tmp3 = call <4 x i32> @llvm.aarch64.neon.umull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp2) 50 ret <4 x i32> %tmp3 51 } 52 53 define <2 x i64> @umull2d(<2 x i32>* %A, <2 x i32>* %B) nounwind { 54 ;CHECK-LABEL: umull2d: 55 ;CHECK: umull.2d 56 %tmp1 = load <2 x i32>, <2 x i32>* %A 57 %tmp2 = load <2 x i32>, <2 x i32>* %B 58 %tmp3 = call <2 x i64> @llvm.aarch64.neon.umull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp2) 59 ret <2 x i64> %tmp3 60 } 61 62 declare <8 x i16> @llvm.aarch64.neon.umull.v8i16(<8 x i8>, <8 x i8>) nounwind readnone 63 declare <4 x i32> @llvm.aarch64.neon.umull.v4i32(<4 x i16>, <4 x i16>) nounwind readnone 64 declare <2 x i64> @llvm.aarch64.neon.umull.v2i64(<2 x i32>, <2 x i32>) nounwind readnone 65 66 define <4 x i32> @sqdmull4s(<4 x i16>* %A, <4 x i16>* %B) nounwind { 67 ;CHECK-LABEL: sqdmull4s: 68 ;CHECK: sqdmull.4s 69 %tmp1 = load <4 x i16>, <4 x i16>* %A 70 %tmp2 = load <4 x i16>, <4 x i16>* %B 71 %tmp3 = call <4 x i32> @llvm.aarch64.neon.sqdmull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp2) 72 ret <4 x i32> %tmp3 73 } 74 75 define <2 x i64> @sqdmull2d(<2 x i32>* %A, <2 x i32>* %B) nounwind { 76 ;CHECK-LABEL: sqdmull2d: 77 ;CHECK: sqdmull.2d 78 %tmp1 = load <2 x i32>, <2 x i32>* %A 79 %tmp2 = load <2 x i32>, <2 x i32>* %B 80 %tmp3 = call <2 x i64> @llvm.aarch64.neon.sqdmull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp2) 81 ret <2 x i64> %tmp3 82 } 83 84 define <4 x i32> @sqdmull2_4s(<8 x i16>* %A, <8 x i16>* %B) nounwind { 85 ;CHECK-LABEL: sqdmull2_4s: 86 ;CHECK: sqdmull2.4s 87 %load1 = load <8 x i16>, <8 x i16>* %A 88 %load2 = load <8 x i16>, <8 x i16>* %B 89 %tmp1 = shufflevector <8 x i16> %load1, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7> 90 %tmp2 = shufflevector <8 x i16> %load2, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7> 91 %tmp3 = call <4 x i32> @llvm.aarch64.neon.sqdmull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp2) 92 ret <4 x i32> %tmp3 93 } 94 95 define <2 x i64> @sqdmull2_2d(<4 x i32>* %A, <4 x i32>* %B) nounwind { 96 ;CHECK-LABEL: sqdmull2_2d: 97 ;CHECK: sqdmull2.2d 98 %load1 = load <4 x i32>, <4 x i32>* %A 99 %load2 = load <4 x i32>, <4 x i32>* %B 100 %tmp1 = shufflevector <4 x i32> %load1, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 101 %tmp2 = shufflevector <4 x i32> %load2, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 102 %tmp3 = call <2 x i64> @llvm.aarch64.neon.sqdmull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp2) 103 ret <2 x i64> %tmp3 104 } 105 106 107 declare <4 x i32> @llvm.aarch64.neon.sqdmull.v4i32(<4 x i16>, <4 x i16>) nounwind readnone 108 declare <2 x i64> @llvm.aarch64.neon.sqdmull.v2i64(<2 x i32>, <2 x i32>) nounwind readnone 109 110 define <8 x i16> @pmull8h(<8 x i8>* %A, <8 x i8>* %B) nounwind { 111 ;CHECK-LABEL: pmull8h: 112 ;CHECK: pmull.8h 113 %tmp1 = load <8 x i8>, <8 x i8>* %A 114 %tmp2 = load <8 x i8>, <8 x i8>* %B 115 %tmp3 = call <8 x i16> @llvm.aarch64.neon.pmull.v8i16(<8 x i8> %tmp1, <8 x i8> %tmp2) 116 ret <8 x i16> %tmp3 117 } 118 119 declare <8 x i16> @llvm.aarch64.neon.pmull.v8i16(<8 x i8>, <8 x i8>) nounwind readnone 120 121 define <4 x i16> @sqdmulh_4h(<4 x i16>* %A, <4 x i16>* %B) nounwind { 122 ;CHECK-LABEL: sqdmulh_4h: 123 ;CHECK: sqdmulh.4h 124 %tmp1 = load <4 x i16>, <4 x i16>* %A 125 %tmp2 = load <4 x i16>, <4 x i16>* %B 126 %tmp3 = call <4 x i16> @llvm.aarch64.neon.sqdmulh.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2) 127 ret <4 x i16> %tmp3 128 } 129 130 define <8 x i16> @sqdmulh_8h(<8 x i16>* %A, <8 x i16>* %B) nounwind { 131 ;CHECK-LABEL: sqdmulh_8h: 132 ;CHECK: sqdmulh.8h 133 %tmp1 = load <8 x i16>, <8 x i16>* %A 134 %tmp2 = load <8 x i16>, <8 x i16>* %B 135 %tmp3 = call <8 x i16> @llvm.aarch64.neon.sqdmulh.v8i16(<8 x i16> %tmp1, <8 x i16> %tmp2) 136 ret <8 x i16> %tmp3 137 } 138 139 define <2 x i32> @sqdmulh_2s(<2 x i32>* %A, <2 x i32>* %B) nounwind { 140 ;CHECK-LABEL: sqdmulh_2s: 141 ;CHECK: sqdmulh.2s 142 %tmp1 = load <2 x i32>, <2 x i32>* %A 143 %tmp2 = load <2 x i32>, <2 x i32>* %B 144 %tmp3 = call <2 x i32> @llvm.aarch64.neon.sqdmulh.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2) 145 ret <2 x i32> %tmp3 146 } 147 148 define <4 x i32> @sqdmulh_4s(<4 x i32>* %A, <4 x i32>* %B) nounwind { 149 ;CHECK-LABEL: sqdmulh_4s: 150 ;CHECK: sqdmulh.4s 151 %tmp1 = load <4 x i32>, <4 x i32>* %A 152 %tmp2 = load <4 x i32>, <4 x i32>* %B 153 %tmp3 = call <4 x i32> @llvm.aarch64.neon.sqdmulh.v4i32(<4 x i32> %tmp1, <4 x i32> %tmp2) 154 ret <4 x i32> %tmp3 155 } 156 157 define i32 @sqdmulh_1s(i32* %A, i32* %B) nounwind { 158 ;CHECK-LABEL: sqdmulh_1s: 159 ;CHECK: sqdmulh s0, {{s[0-9]+}}, {{s[0-9]+}} 160 %tmp1 = load i32, i32* %A 161 %tmp2 = load i32, i32* %B 162 %tmp3 = call i32 @llvm.aarch64.neon.sqdmulh.i32(i32 %tmp1, i32 %tmp2) 163 ret i32 %tmp3 164 } 165 166 declare <4 x i16> @llvm.aarch64.neon.sqdmulh.v4i16(<4 x i16>, <4 x i16>) nounwind readnone 167 declare <8 x i16> @llvm.aarch64.neon.sqdmulh.v8i16(<8 x i16>, <8 x i16>) nounwind readnone 168 declare <2 x i32> @llvm.aarch64.neon.sqdmulh.v2i32(<2 x i32>, <2 x i32>) nounwind readnone 169 declare <4 x i32> @llvm.aarch64.neon.sqdmulh.v4i32(<4 x i32>, <4 x i32>) nounwind readnone 170 declare i32 @llvm.aarch64.neon.sqdmulh.i32(i32, i32) nounwind readnone 171 172 define <4 x i16> @sqrdmulh_4h(<4 x i16>* %A, <4 x i16>* %B) nounwind { 173 ;CHECK-LABEL: sqrdmulh_4h: 174 ;CHECK: sqrdmulh.4h 175 %tmp1 = load <4 x i16>, <4 x i16>* %A 176 %tmp2 = load <4 x i16>, <4 x i16>* %B 177 %tmp3 = call <4 x i16> @llvm.aarch64.neon.sqrdmulh.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2) 178 ret <4 x i16> %tmp3 179 } 180 181 define <8 x i16> @sqrdmulh_8h(<8 x i16>* %A, <8 x i16>* %B) nounwind { 182 ;CHECK-LABEL: sqrdmulh_8h: 183 ;CHECK: sqrdmulh.8h 184 %tmp1 = load <8 x i16>, <8 x i16>* %A 185 %tmp2 = load <8 x i16>, <8 x i16>* %B 186 %tmp3 = call <8 x i16> @llvm.aarch64.neon.sqrdmulh.v8i16(<8 x i16> %tmp1, <8 x i16> %tmp2) 187 ret <8 x i16> %tmp3 188 } 189 190 define <2 x i32> @sqrdmulh_2s(<2 x i32>* %A, <2 x i32>* %B) nounwind { 191 ;CHECK-LABEL: sqrdmulh_2s: 192 ;CHECK: sqrdmulh.2s 193 %tmp1 = load <2 x i32>, <2 x i32>* %A 194 %tmp2 = load <2 x i32>, <2 x i32>* %B 195 %tmp3 = call <2 x i32> @llvm.aarch64.neon.sqrdmulh.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2) 196 ret <2 x i32> %tmp3 197 } 198 199 define <4 x i32> @sqrdmulh_4s(<4 x i32>* %A, <4 x i32>* %B) nounwind { 200 ;CHECK-LABEL: sqrdmulh_4s: 201 ;CHECK: sqrdmulh.4s 202 %tmp1 = load <4 x i32>, <4 x i32>* %A 203 %tmp2 = load <4 x i32>, <4 x i32>* %B 204 %tmp3 = call <4 x i32> @llvm.aarch64.neon.sqrdmulh.v4i32(<4 x i32> %tmp1, <4 x i32> %tmp2) 205 ret <4 x i32> %tmp3 206 } 207 208 define i32 @sqrdmulh_1s(i32* %A, i32* %B) nounwind { 209 ;CHECK-LABEL: sqrdmulh_1s: 210 ;CHECK: sqrdmulh s0, {{s[0-9]+}}, {{s[0-9]+}} 211 %tmp1 = load i32, i32* %A 212 %tmp2 = load i32, i32* %B 213 %tmp3 = call i32 @llvm.aarch64.neon.sqrdmulh.i32(i32 %tmp1, i32 %tmp2) 214 ret i32 %tmp3 215 } 216 217 declare <4 x i16> @llvm.aarch64.neon.sqrdmulh.v4i16(<4 x i16>, <4 x i16>) nounwind readnone 218 declare <8 x i16> @llvm.aarch64.neon.sqrdmulh.v8i16(<8 x i16>, <8 x i16>) nounwind readnone 219 declare <2 x i32> @llvm.aarch64.neon.sqrdmulh.v2i32(<2 x i32>, <2 x i32>) nounwind readnone 220 declare <4 x i32> @llvm.aarch64.neon.sqrdmulh.v4i32(<4 x i32>, <4 x i32>) nounwind readnone 221 declare i32 @llvm.aarch64.neon.sqrdmulh.i32(i32, i32) nounwind readnone 222 223 define <2 x float> @fmulx_2s(<2 x float>* %A, <2 x float>* %B) nounwind { 224 ;CHECK-LABEL: fmulx_2s: 225 ;CHECK: fmulx.2s 226 %tmp1 = load <2 x float>, <2 x float>* %A 227 %tmp2 = load <2 x float>, <2 x float>* %B 228 %tmp3 = call <2 x float> @llvm.aarch64.neon.fmulx.v2f32(<2 x float> %tmp1, <2 x float> %tmp2) 229 ret <2 x float> %tmp3 230 } 231 232 define <4 x float> @fmulx_4s(<4 x float>* %A, <4 x float>* %B) nounwind { 233 ;CHECK-LABEL: fmulx_4s: 234 ;CHECK: fmulx.4s 235 %tmp1 = load <4 x float>, <4 x float>* %A 236 %tmp2 = load <4 x float>, <4 x float>* %B 237 %tmp3 = call <4 x float> @llvm.aarch64.neon.fmulx.v4f32(<4 x float> %tmp1, <4 x float> %tmp2) 238 ret <4 x float> %tmp3 239 } 240 241 define <2 x double> @fmulx_2d(<2 x double>* %A, <2 x double>* %B) nounwind { 242 ;CHECK-LABEL: fmulx_2d: 243 ;CHECK: fmulx.2d 244 %tmp1 = load <2 x double>, <2 x double>* %A 245 %tmp2 = load <2 x double>, <2 x double>* %B 246 %tmp3 = call <2 x double> @llvm.aarch64.neon.fmulx.v2f64(<2 x double> %tmp1, <2 x double> %tmp2) 247 ret <2 x double> %tmp3 248 } 249 250 declare <2 x float> @llvm.aarch64.neon.fmulx.v2f32(<2 x float>, <2 x float>) nounwind readnone 251 declare <4 x float> @llvm.aarch64.neon.fmulx.v4f32(<4 x float>, <4 x float>) nounwind readnone 252 declare <2 x double> @llvm.aarch64.neon.fmulx.v2f64(<2 x double>, <2 x double>) nounwind readnone 253 254 define <4 x i32> @smlal4s(<4 x i16>* %A, <4 x i16>* %B, <4 x i32>* %C) nounwind { 255 ;CHECK-LABEL: smlal4s: 256 ;CHECK: smlal.4s 257 %tmp1 = load <4 x i16>, <4 x i16>* %A 258 %tmp2 = load <4 x i16>, <4 x i16>* %B 259 %tmp3 = load <4 x i32>, <4 x i32>* %C 260 %tmp4 = call <4 x i32> @llvm.aarch64.neon.smull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp2) 261 %tmp5 = add <4 x i32> %tmp3, %tmp4 262 ret <4 x i32> %tmp5 263 } 264 265 define <2 x i64> @smlal2d(<2 x i32>* %A, <2 x i32>* %B, <2 x i64>* %C) nounwind { 266 ;CHECK-LABEL: smlal2d: 267 ;CHECK: smlal.2d 268 %tmp1 = load <2 x i32>, <2 x i32>* %A 269 %tmp2 = load <2 x i32>, <2 x i32>* %B 270 %tmp3 = load <2 x i64>, <2 x i64>* %C 271 %tmp4 = call <2 x i64> @llvm.aarch64.neon.smull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp2) 272 %tmp5 = add <2 x i64> %tmp3, %tmp4 273 ret <2 x i64> %tmp5 274 } 275 276 define <4 x i32> @smlsl4s(<4 x i16>* %A, <4 x i16>* %B, <4 x i32>* %C) nounwind { 277 ;CHECK-LABEL: smlsl4s: 278 ;CHECK: smlsl.4s 279 %tmp1 = load <4 x i16>, <4 x i16>* %A 280 %tmp2 = load <4 x i16>, <4 x i16>* %B 281 %tmp3 = load <4 x i32>, <4 x i32>* %C 282 %tmp4 = call <4 x i32> @llvm.aarch64.neon.smull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp2) 283 %tmp5 = sub <4 x i32> %tmp3, %tmp4 284 ret <4 x i32> %tmp5 285 } 286 287 define <2 x i64> @smlsl2d(<2 x i32>* %A, <2 x i32>* %B, <2 x i64>* %C) nounwind { 288 ;CHECK-LABEL: smlsl2d: 289 ;CHECK: smlsl.2d 290 %tmp1 = load <2 x i32>, <2 x i32>* %A 291 %tmp2 = load <2 x i32>, <2 x i32>* %B 292 %tmp3 = load <2 x i64>, <2 x i64>* %C 293 %tmp4 = call <2 x i64> @llvm.aarch64.neon.smull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp2) 294 %tmp5 = sub <2 x i64> %tmp3, %tmp4 295 ret <2 x i64> %tmp5 296 } 297 298 declare <4 x i32> @llvm.aarch64.neon.sqadd.v4i32(<4 x i32>, <4 x i32>) 299 declare <2 x i64> @llvm.aarch64.neon.sqadd.v2i64(<2 x i64>, <2 x i64>) 300 declare <4 x i32> @llvm.aarch64.neon.sqsub.v4i32(<4 x i32>, <4 x i32>) 301 declare <2 x i64> @llvm.aarch64.neon.sqsub.v2i64(<2 x i64>, <2 x i64>) 302 303 define <4 x i32> @sqdmlal4s(<4 x i16>* %A, <4 x i16>* %B, <4 x i32>* %C) nounwind { 304 ;CHECK-LABEL: sqdmlal4s: 305 ;CHECK: sqdmlal.4s 306 %tmp1 = load <4 x i16>, <4 x i16>* %A 307 %tmp2 = load <4 x i16>, <4 x i16>* %B 308 %tmp3 = load <4 x i32>, <4 x i32>* %C 309 %tmp4 = call <4 x i32> @llvm.aarch64.neon.sqdmull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp2) 310 %tmp5 = call <4 x i32> @llvm.aarch64.neon.sqadd.v4i32(<4 x i32> %tmp3, <4 x i32> %tmp4) 311 ret <4 x i32> %tmp5 312 } 313 314 define <2 x i64> @sqdmlal2d(<2 x i32>* %A, <2 x i32>* %B, <2 x i64>* %C) nounwind { 315 ;CHECK-LABEL: sqdmlal2d: 316 ;CHECK: sqdmlal.2d 317 %tmp1 = load <2 x i32>, <2 x i32>* %A 318 %tmp2 = load <2 x i32>, <2 x i32>* %B 319 %tmp3 = load <2 x i64>, <2 x i64>* %C 320 %tmp4 = call <2 x i64> @llvm.aarch64.neon.sqdmull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp2) 321 %tmp5 = call <2 x i64> @llvm.aarch64.neon.sqadd.v2i64(<2 x i64> %tmp3, <2 x i64> %tmp4) 322 ret <2 x i64> %tmp5 323 } 324 325 define <4 x i32> @sqdmlal2_4s(<8 x i16>* %A, <8 x i16>* %B, <4 x i32>* %C) nounwind { 326 ;CHECK-LABEL: sqdmlal2_4s: 327 ;CHECK: sqdmlal2.4s 328 %load1 = load <8 x i16>, <8 x i16>* %A 329 %load2 = load <8 x i16>, <8 x i16>* %B 330 %tmp3 = load <4 x i32>, <4 x i32>* %C 331 %tmp1 = shufflevector <8 x i16> %load1, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7> 332 %tmp2 = shufflevector <8 x i16> %load2, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7> 333 %tmp4 = call <4 x i32> @llvm.aarch64.neon.sqdmull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp2) 334 %tmp5 = call <4 x i32> @llvm.aarch64.neon.sqadd.v4i32(<4 x i32> %tmp3, <4 x i32> %tmp4) 335 ret <4 x i32> %tmp5 336 } 337 338 define <2 x i64> @sqdmlal2_2d(<4 x i32>* %A, <4 x i32>* %B, <2 x i64>* %C) nounwind { 339 ;CHECK-LABEL: sqdmlal2_2d: 340 ;CHECK: sqdmlal2.2d 341 %load1 = load <4 x i32>, <4 x i32>* %A 342 %load2 = load <4 x i32>, <4 x i32>* %B 343 %tmp3 = load <2 x i64>, <2 x i64>* %C 344 %tmp1 = shufflevector <4 x i32> %load1, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 345 %tmp2 = shufflevector <4 x i32> %load2, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 346 %tmp4 = call <2 x i64> @llvm.aarch64.neon.sqdmull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp2) 347 %tmp5 = call <2 x i64> @llvm.aarch64.neon.sqadd.v2i64(<2 x i64> %tmp3, <2 x i64> %tmp4) 348 ret <2 x i64> %tmp5 349 } 350 351 define <4 x i32> @sqdmlsl4s(<4 x i16>* %A, <4 x i16>* %B, <4 x i32>* %C) nounwind { 352 ;CHECK-LABEL: sqdmlsl4s: 353 ;CHECK: sqdmlsl.4s 354 %tmp1 = load <4 x i16>, <4 x i16>* %A 355 %tmp2 = load <4 x i16>, <4 x i16>* %B 356 %tmp3 = load <4 x i32>, <4 x i32>* %C 357 %tmp4 = call <4 x i32> @llvm.aarch64.neon.sqdmull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp2) 358 %tmp5 = call <4 x i32> @llvm.aarch64.neon.sqsub.v4i32(<4 x i32> %tmp3, <4 x i32> %tmp4) 359 ret <4 x i32> %tmp5 360 } 361 362 define <2 x i64> @sqdmlsl2d(<2 x i32>* %A, <2 x i32>* %B, <2 x i64>* %C) nounwind { 363 ;CHECK-LABEL: sqdmlsl2d: 364 ;CHECK: sqdmlsl.2d 365 %tmp1 = load <2 x i32>, <2 x i32>* %A 366 %tmp2 = load <2 x i32>, <2 x i32>* %B 367 %tmp3 = load <2 x i64>, <2 x i64>* %C 368 %tmp4 = call <2 x i64> @llvm.aarch64.neon.sqdmull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp2) 369 %tmp5 = call <2 x i64> @llvm.aarch64.neon.sqsub.v2i64(<2 x i64> %tmp3, <2 x i64> %tmp4) 370 ret <2 x i64> %tmp5 371 } 372 373 define <4 x i32> @sqdmlsl2_4s(<8 x i16>* %A, <8 x i16>* %B, <4 x i32>* %C) nounwind { 374 ;CHECK-LABEL: sqdmlsl2_4s: 375 ;CHECK: sqdmlsl2.4s 376 %load1 = load <8 x i16>, <8 x i16>* %A 377 %load2 = load <8 x i16>, <8 x i16>* %B 378 %tmp3 = load <4 x i32>, <4 x i32>* %C 379 %tmp1 = shufflevector <8 x i16> %load1, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7> 380 %tmp2 = shufflevector <8 x i16> %load2, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7> 381 %tmp4 = call <4 x i32> @llvm.aarch64.neon.sqdmull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp2) 382 %tmp5 = call <4 x i32> @llvm.aarch64.neon.sqsub.v4i32(<4 x i32> %tmp3, <4 x i32> %tmp4) 383 ret <4 x i32> %tmp5 384 } 385 386 define <2 x i64> @sqdmlsl2_2d(<4 x i32>* %A, <4 x i32>* %B, <2 x i64>* %C) nounwind { 387 ;CHECK-LABEL: sqdmlsl2_2d: 388 ;CHECK: sqdmlsl2.2d 389 %load1 = load <4 x i32>, <4 x i32>* %A 390 %load2 = load <4 x i32>, <4 x i32>* %B 391 %tmp3 = load <2 x i64>, <2 x i64>* %C 392 %tmp1 = shufflevector <4 x i32> %load1, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 393 %tmp2 = shufflevector <4 x i32> %load2, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 394 %tmp4 = call <2 x i64> @llvm.aarch64.neon.sqdmull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp2) 395 %tmp5 = call <2 x i64> @llvm.aarch64.neon.sqsub.v2i64(<2 x i64> %tmp3, <2 x i64> %tmp4) 396 ret <2 x i64> %tmp5 397 } 398 399 define <4 x i32> @umlal4s(<4 x i16>* %A, <4 x i16>* %B, <4 x i32>* %C) nounwind { 400 ;CHECK-LABEL: umlal4s: 401 ;CHECK: umlal.4s 402 %tmp1 = load <4 x i16>, <4 x i16>* %A 403 %tmp2 = load <4 x i16>, <4 x i16>* %B 404 %tmp3 = load <4 x i32>, <4 x i32>* %C 405 %tmp4 = call <4 x i32> @llvm.aarch64.neon.umull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp2) 406 %tmp5 = add <4 x i32> %tmp3, %tmp4 407 ret <4 x i32> %tmp5 408 } 409 410 define <2 x i64> @umlal2d(<2 x i32>* %A, <2 x i32>* %B, <2 x i64>* %C) nounwind { 411 ;CHECK-LABEL: umlal2d: 412 ;CHECK: umlal.2d 413 %tmp1 = load <2 x i32>, <2 x i32>* %A 414 %tmp2 = load <2 x i32>, <2 x i32>* %B 415 %tmp3 = load <2 x i64>, <2 x i64>* %C 416 %tmp4 = call <2 x i64> @llvm.aarch64.neon.umull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp2) 417 %tmp5 = add <2 x i64> %tmp3, %tmp4 418 ret <2 x i64> %tmp5 419 } 420 421 define <4 x i32> @umlsl4s(<4 x i16>* %A, <4 x i16>* %B, <4 x i32>* %C) nounwind { 422 ;CHECK-LABEL: umlsl4s: 423 ;CHECK: umlsl.4s 424 %tmp1 = load <4 x i16>, <4 x i16>* %A 425 %tmp2 = load <4 x i16>, <4 x i16>* %B 426 %tmp3 = load <4 x i32>, <4 x i32>* %C 427 %tmp4 = call <4 x i32> @llvm.aarch64.neon.umull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp2) 428 %tmp5 = sub <4 x i32> %tmp3, %tmp4 429 ret <4 x i32> %tmp5 430 } 431 432 define <2 x i64> @umlsl2d(<2 x i32>* %A, <2 x i32>* %B, <2 x i64>* %C) nounwind { 433 ;CHECK-LABEL: umlsl2d: 434 ;CHECK: umlsl.2d 435 %tmp1 = load <2 x i32>, <2 x i32>* %A 436 %tmp2 = load <2 x i32>, <2 x i32>* %B 437 %tmp3 = load <2 x i64>, <2 x i64>* %C 438 %tmp4 = call <2 x i64> @llvm.aarch64.neon.umull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp2) 439 %tmp5 = sub <2 x i64> %tmp3, %tmp4 440 ret <2 x i64> %tmp5 441 } 442 443 define <2 x float> @fmla_2s(<2 x float>* %A, <2 x float>* %B, <2 x float>* %C) nounwind { 444 ;CHECK-LABEL: fmla_2s: 445 ;CHECK: fmla.2s 446 %tmp1 = load <2 x float>, <2 x float>* %A 447 %tmp2 = load <2 x float>, <2 x float>* %B 448 %tmp3 = load <2 x float>, <2 x float>* %C 449 %tmp4 = call <2 x float> @llvm.fma.v2f32(<2 x float> %tmp1, <2 x float> %tmp2, <2 x float> %tmp3) 450 ret <2 x float> %tmp4 451 } 452 453 define <4 x float> @fmla_4s(<4 x float>* %A, <4 x float>* %B, <4 x float>* %C) nounwind { 454 ;CHECK-LABEL: fmla_4s: 455 ;CHECK: fmla.4s 456 %tmp1 = load <4 x float>, <4 x float>* %A 457 %tmp2 = load <4 x float>, <4 x float>* %B 458 %tmp3 = load <4 x float>, <4 x float>* %C 459 %tmp4 = call <4 x float> @llvm.fma.v4f32(<4 x float> %tmp1, <4 x float> %tmp2, <4 x float> %tmp3) 460 ret <4 x float> %tmp4 461 } 462 463 define <2 x double> @fmla_2d(<2 x double>* %A, <2 x double>* %B, <2 x double>* %C) nounwind { 464 ;CHECK-LABEL: fmla_2d: 465 ;CHECK: fmla.2d 466 %tmp1 = load <2 x double>, <2 x double>* %A 467 %tmp2 = load <2 x double>, <2 x double>* %B 468 %tmp3 = load <2 x double>, <2 x double>* %C 469 %tmp4 = call <2 x double> @llvm.fma.v2f64(<2 x double> %tmp1, <2 x double> %tmp2, <2 x double> %tmp3) 470 ret <2 x double> %tmp4 471 } 472 473 declare <2 x float> @llvm.fma.v2f32(<2 x float>, <2 x float>, <2 x float>) nounwind readnone 474 declare <4 x float> @llvm.fma.v4f32(<4 x float>, <4 x float>, <4 x float>) nounwind readnone 475 declare <2 x double> @llvm.fma.v2f64(<2 x double>, <2 x double>, <2 x double>) nounwind readnone 476 477 define <2 x float> @fmls_2s(<2 x float>* %A, <2 x float>* %B, <2 x float>* %C) nounwind { 478 ;CHECK-LABEL: fmls_2s: 479 ;CHECK: fmls.2s 480 %tmp1 = load <2 x float>, <2 x float>* %A 481 %tmp2 = load <2 x float>, <2 x float>* %B 482 %tmp3 = load <2 x float>, <2 x float>* %C 483 %tmp4 = fsub <2 x float> <float -0.0, float -0.0>, %tmp2 484 %tmp5 = call <2 x float> @llvm.fma.v2f32(<2 x float> %tmp1, <2 x float> %tmp4, <2 x float> %tmp3) 485 ret <2 x float> %tmp5 486 } 487 488 define <4 x float> @fmls_4s(<4 x float>* %A, <4 x float>* %B, <4 x float>* %C) nounwind { 489 ;CHECK-LABEL: fmls_4s: 490 ;CHECK: fmls.4s 491 %tmp1 = load <4 x float>, <4 x float>* %A 492 %tmp2 = load <4 x float>, <4 x float>* %B 493 %tmp3 = load <4 x float>, <4 x float>* %C 494 %tmp4 = fsub <4 x float> <float -0.0, float -0.0, float -0.0, float -0.0>, %tmp2 495 %tmp5 = call <4 x float> @llvm.fma.v4f32(<4 x float> %tmp1, <4 x float> %tmp4, <4 x float> %tmp3) 496 ret <4 x float> %tmp5 497 } 498 499 define <2 x double> @fmls_2d(<2 x double>* %A, <2 x double>* %B, <2 x double>* %C) nounwind { 500 ;CHECK-LABEL: fmls_2d: 501 ;CHECK: fmls.2d 502 %tmp1 = load <2 x double>, <2 x double>* %A 503 %tmp2 = load <2 x double>, <2 x double>* %B 504 %tmp3 = load <2 x double>, <2 x double>* %C 505 %tmp4 = fsub <2 x double> <double -0.0, double -0.0>, %tmp2 506 %tmp5 = call <2 x double> @llvm.fma.v2f64(<2 x double> %tmp1, <2 x double> %tmp4, <2 x double> %tmp3) 507 ret <2 x double> %tmp5 508 } 509 510 define <2 x float> @fmls_commuted_neg_2s(<2 x float>* %A, <2 x float>* %B, <2 x float>* %C) nounwind { 511 ;CHECK-LABEL: fmls_commuted_neg_2s: 512 ;CHECK: fmls.2s 513 %tmp1 = load <2 x float>, <2 x float>* %A 514 %tmp2 = load <2 x float>, <2 x float>* %B 515 %tmp3 = load <2 x float>, <2 x float>* %C 516 %tmp4 = fsub <2 x float> <float -0.0, float -0.0>, %tmp2 517 %tmp5 = call <2 x float> @llvm.fma.v2f32(<2 x float> %tmp4, <2 x float> %tmp1, <2 x float> %tmp3) 518 ret <2 x float> %tmp5 519 } 520 521 define <4 x float> @fmls_commuted_neg_4s(<4 x float>* %A, <4 x float>* %B, <4 x float>* %C) nounwind { 522 ;CHECK-LABEL: fmls_commuted_neg_4s: 523 ;CHECK: fmls.4s 524 %tmp1 = load <4 x float>, <4 x float>* %A 525 %tmp2 = load <4 x float>, <4 x float>* %B 526 %tmp3 = load <4 x float>, <4 x float>* %C 527 %tmp4 = fsub <4 x float> <float -0.0, float -0.0, float -0.0, float -0.0>, %tmp2 528 %tmp5 = call <4 x float> @llvm.fma.v4f32(<4 x float> %tmp4, <4 x float> %tmp1, <4 x float> %tmp3) 529 ret <4 x float> %tmp5 530 } 531 532 define <2 x double> @fmls_commuted_neg_2d(<2 x double>* %A, <2 x double>* %B, <2 x double>* %C) nounwind { 533 ;CHECK-LABEL: fmls_commuted_neg_2d: 534 ;CHECK: fmls.2d 535 %tmp1 = load <2 x double>, <2 x double>* %A 536 %tmp2 = load <2 x double>, <2 x double>* %B 537 %tmp3 = load <2 x double>, <2 x double>* %C 538 %tmp4 = fsub <2 x double> <double -0.0, double -0.0>, %tmp2 539 %tmp5 = call <2 x double> @llvm.fma.v2f64(<2 x double> %tmp4, <2 x double> %tmp1, <2 x double> %tmp3) 540 ret <2 x double> %tmp5 541 } 542 543 define <2 x float> @fmls_indexed_2s(<2 x float> %a, <2 x float> %b, <2 x float> %c) nounwind readnone ssp { 544 ;CHECK-LABEL: fmls_indexed_2s: 545 ;CHECK: fmls.2s 546 entry: 547 %0 = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, %c 548 %lane = shufflevector <2 x float> %b, <2 x float> undef, <2 x i32> zeroinitializer 549 %fmls1 = tail call <2 x float> @llvm.fma.v2f32(<2 x float> %0, <2 x float> %lane, <2 x float> %a) 550 ret <2 x float> %fmls1 551 } 552 553 define <4 x float> @fmls_indexed_4s(<4 x float> %a, <4 x float> %b, <4 x float> %c) nounwind readnone ssp { 554 ;CHECK-LABEL: fmls_indexed_4s: 555 ;CHECK: fmls.4s 556 entry: 557 %0 = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %c 558 %lane = shufflevector <4 x float> %b, <4 x float> undef, <4 x i32> zeroinitializer 559 %fmls1 = tail call <4 x float> @llvm.fma.v4f32(<4 x float> %0, <4 x float> %lane, <4 x float> %a) 560 ret <4 x float> %fmls1 561 } 562 563 define <2 x double> @fmls_indexed_2d(<2 x double> %a, <2 x double> %b, <2 x double> %c) nounwind readnone ssp { 564 ;CHECK-LABEL: fmls_indexed_2d: 565 ;CHECK: fmls.2d 566 entry: 567 %0 = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %c 568 %lane = shufflevector <2 x double> %b, <2 x double> undef, <2 x i32> zeroinitializer 569 %fmls1 = tail call <2 x double> @llvm.fma.v2f64(<2 x double> %0, <2 x double> %lane, <2 x double> %a) 570 ret <2 x double> %fmls1 571 } 572 573 define <2 x float> @fmla_indexed_scalar_2s(<2 x float> %a, <2 x float> %b, float %c) nounwind readnone ssp { 574 entry: 575 ; CHECK-LABEL: fmla_indexed_scalar_2s: 576 ; CHECK-NEXT: fmla.2s 577 ; CHECK-NEXT: ret 578 %v1 = insertelement <2 x float> undef, float %c, i32 0 579 %v2 = insertelement <2 x float> %v1, float %c, i32 1 580 %fmla1 = tail call <2 x float> @llvm.fma.v2f32(<2 x float> %v1, <2 x float> %b, <2 x float> %a) nounwind 581 ret <2 x float> %fmla1 582 } 583 584 define <4 x float> @fmla_indexed_scalar_4s(<4 x float> %a, <4 x float> %b, float %c) nounwind readnone ssp { 585 entry: 586 ; CHECK-LABEL: fmla_indexed_scalar_4s: 587 ; CHECK-NEXT: fmla.4s 588 ; CHECK-NEXT: ret 589 %v1 = insertelement <4 x float> undef, float %c, i32 0 590 %v2 = insertelement <4 x float> %v1, float %c, i32 1 591 %v3 = insertelement <4 x float> %v2, float %c, i32 2 592 %v4 = insertelement <4 x float> %v3, float %c, i32 3 593 %fmla1 = tail call <4 x float> @llvm.fma.v4f32(<4 x float> %v4, <4 x float> %b, <4 x float> %a) nounwind 594 ret <4 x float> %fmla1 595 } 596 597 define <2 x double> @fmla_indexed_scalar_2d(<2 x double> %a, <2 x double> %b, double %c) nounwind readnone ssp { 598 ; CHECK-LABEL: fmla_indexed_scalar_2d: 599 ; CHECK-NEXT: fmla.2d 600 ; CHECK-NEXT: ret 601 entry: 602 %v1 = insertelement <2 x double> undef, double %c, i32 0 603 %v2 = insertelement <2 x double> %v1, double %c, i32 1 604 %fmla1 = tail call <2 x double> @llvm.fma.v2f64(<2 x double> %v2, <2 x double> %b, <2 x double> %a) nounwind 605 ret <2 x double> %fmla1 606 } 607 608 define <4 x i16> @mul_4h(<4 x i16>* %A, <4 x i16>* %B) nounwind { 609 ;CHECK-LABEL: mul_4h: 610 ;CHECK-NOT: dup 611 ;CHECK: mul.4h 612 %tmp1 = load <4 x i16>, <4 x i16>* %A 613 %tmp2 = load <4 x i16>, <4 x i16>* %B 614 %tmp3 = shufflevector <4 x i16> %tmp2, <4 x i16> %tmp2, <4 x i32> <i32 1, i32 1, i32 1, i32 1> 615 %tmp4 = mul <4 x i16> %tmp1, %tmp3 616 ret <4 x i16> %tmp4 617 } 618 619 define <8 x i16> @mul_8h(<8 x i16>* %A, <8 x i16>* %B) nounwind { 620 ;CHECK-LABEL: mul_8h: 621 ;CHECK-NOT: dup 622 ;CHECK: mul.8h 623 %tmp1 = load <8 x i16>, <8 x i16>* %A 624 %tmp2 = load <8 x i16>, <8 x i16>* %B 625 %tmp3 = shufflevector <8 x i16> %tmp2, <8 x i16> %tmp2, <8 x i32> <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> 626 %tmp4 = mul <8 x i16> %tmp1, %tmp3 627 ret <8 x i16> %tmp4 628 } 629 630 define <2 x i32> @mul_2s(<2 x i32>* %A, <2 x i32>* %B) nounwind { 631 ;CHECK-LABEL: mul_2s: 632 ;CHECK-NOT: dup 633 ;CHECK: mul.2s 634 %tmp1 = load <2 x i32>, <2 x i32>* %A 635 %tmp2 = load <2 x i32>, <2 x i32>* %B 636 %tmp3 = shufflevector <2 x i32> %tmp2, <2 x i32> %tmp2, <2 x i32> <i32 1, i32 1> 637 %tmp4 = mul <2 x i32> %tmp1, %tmp3 638 ret <2 x i32> %tmp4 639 } 640 641 define <4 x i32> @mul_4s(<4 x i32>* %A, <4 x i32>* %B) nounwind { 642 ;CHECK-LABEL: mul_4s: 643 ;CHECK-NOT: dup 644 ;CHECK: mul.4s 645 %tmp1 = load <4 x i32>, <4 x i32>* %A 646 %tmp2 = load <4 x i32>, <4 x i32>* %B 647 %tmp3 = shufflevector <4 x i32> %tmp2, <4 x i32> %tmp2, <4 x i32> <i32 1, i32 1, i32 1, i32 1> 648 %tmp4 = mul <4 x i32> %tmp1, %tmp3 649 ret <4 x i32> %tmp4 650 } 651 652 define <2 x i64> @mul_2d(<2 x i64> %A, <2 x i64> %B) nounwind { 653 ; CHECK-LABEL: mul_2d: 654 ; CHECK: mul 655 ; CHECK: mul 656 %tmp1 = mul <2 x i64> %A, %B 657 ret <2 x i64> %tmp1 658 } 659 660 define <2 x float> @fmul_lane_2s(<2 x float>* %A, <2 x float>* %B) nounwind { 661 ;CHECK-LABEL: fmul_lane_2s: 662 ;CHECK-NOT: dup 663 ;CHECK: fmul.2s 664 %tmp1 = load <2 x float>, <2 x float>* %A 665 %tmp2 = load <2 x float>, <2 x float>* %B 666 %tmp3 = shufflevector <2 x float> %tmp2, <2 x float> %tmp2, <2 x i32> <i32 1, i32 1> 667 %tmp4 = fmul <2 x float> %tmp1, %tmp3 668 ret <2 x float> %tmp4 669 } 670 671 define <4 x float> @fmul_lane_4s(<4 x float>* %A, <4 x float>* %B) nounwind { 672 ;CHECK-LABEL: fmul_lane_4s: 673 ;CHECK-NOT: dup 674 ;CHECK: fmul.4s 675 %tmp1 = load <4 x float>, <4 x float>* %A 676 %tmp2 = load <4 x float>, <4 x float>* %B 677 %tmp3 = shufflevector <4 x float> %tmp2, <4 x float> %tmp2, <4 x i32> <i32 1, i32 1, i32 1, i32 1> 678 %tmp4 = fmul <4 x float> %tmp1, %tmp3 679 ret <4 x float> %tmp4 680 } 681 682 define <2 x double> @fmul_lane_2d(<2 x double>* %A, <2 x double>* %B) nounwind { 683 ;CHECK-LABEL: fmul_lane_2d: 684 ;CHECK-NOT: dup 685 ;CHECK: fmul.2d 686 %tmp1 = load <2 x double>, <2 x double>* %A 687 %tmp2 = load <2 x double>, <2 x double>* %B 688 %tmp3 = shufflevector <2 x double> %tmp2, <2 x double> %tmp2, <2 x i32> <i32 1, i32 1> 689 %tmp4 = fmul <2 x double> %tmp1, %tmp3 690 ret <2 x double> %tmp4 691 } 692 693 define float @fmul_lane_s(float %A, <4 x float> %vec) nounwind { 694 ;CHECK-LABEL: fmul_lane_s: 695 ;CHECK-NOT: dup 696 ;CHECK: fmul.s s0, s0, v1[3] 697 %B = extractelement <4 x float> %vec, i32 3 698 %res = fmul float %A, %B 699 ret float %res 700 } 701 702 define double @fmul_lane_d(double %A, <2 x double> %vec) nounwind { 703 ;CHECK-LABEL: fmul_lane_d: 704 ;CHECK-NOT: dup 705 ;CHECK: fmul.d d0, d0, v1[1] 706 %B = extractelement <2 x double> %vec, i32 1 707 %res = fmul double %A, %B 708 ret double %res 709 } 710 711 712 713 define <2 x float> @fmulx_lane_2s(<2 x float>* %A, <2 x float>* %B) nounwind { 714 ;CHECK-LABEL: fmulx_lane_2s: 715 ;CHECK-NOT: dup 716 ;CHECK: fmulx.2s 717 %tmp1 = load <2 x float>, <2 x float>* %A 718 %tmp2 = load <2 x float>, <2 x float>* %B 719 %tmp3 = shufflevector <2 x float> %tmp2, <2 x float> %tmp2, <2 x i32> <i32 1, i32 1> 720 %tmp4 = call <2 x float> @llvm.aarch64.neon.fmulx.v2f32(<2 x float> %tmp1, <2 x float> %tmp3) 721 ret <2 x float> %tmp4 722 } 723 724 define <4 x float> @fmulx_lane_4s(<4 x float>* %A, <4 x float>* %B) nounwind { 725 ;CHECK-LABEL: fmulx_lane_4s: 726 ;CHECK-NOT: dup 727 ;CHECK: fmulx.4s 728 %tmp1 = load <4 x float>, <4 x float>* %A 729 %tmp2 = load <4 x float>, <4 x float>* %B 730 %tmp3 = shufflevector <4 x float> %tmp2, <4 x float> %tmp2, <4 x i32> <i32 1, i32 1, i32 1, i32 1> 731 %tmp4 = call <4 x float> @llvm.aarch64.neon.fmulx.v4f32(<4 x float> %tmp1, <4 x float> %tmp3) 732 ret <4 x float> %tmp4 733 } 734 735 define <2 x double> @fmulx_lane_2d(<2 x double>* %A, <2 x double>* %B) nounwind { 736 ;CHECK-LABEL: fmulx_lane_2d: 737 ;CHECK-NOT: dup 738 ;CHECK: fmulx.2d 739 %tmp1 = load <2 x double>, <2 x double>* %A 740 %tmp2 = load <2 x double>, <2 x double>* %B 741 %tmp3 = shufflevector <2 x double> %tmp2, <2 x double> %tmp2, <2 x i32> <i32 1, i32 1> 742 %tmp4 = call <2 x double> @llvm.aarch64.neon.fmulx.v2f64(<2 x double> %tmp1, <2 x double> %tmp3) 743 ret <2 x double> %tmp4 744 } 745 746 define <4 x i16> @sqdmulh_lane_4h(<4 x i16>* %A, <4 x i16>* %B) nounwind { 747 ;CHECK-LABEL: sqdmulh_lane_4h: 748 ;CHECK-NOT: dup 749 ;CHECK: sqdmulh.4h 750 %tmp1 = load <4 x i16>, <4 x i16>* %A 751 %tmp2 = load <4 x i16>, <4 x i16>* %B 752 %tmp3 = shufflevector <4 x i16> %tmp2, <4 x i16> %tmp2, <4 x i32> <i32 1, i32 1, i32 1, i32 1> 753 %tmp4 = call <4 x i16> @llvm.aarch64.neon.sqdmulh.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp3) 754 ret <4 x i16> %tmp4 755 } 756 757 define <8 x i16> @sqdmulh_lane_8h(<8 x i16>* %A, <8 x i16>* %B) nounwind { 758 ;CHECK-LABEL: sqdmulh_lane_8h: 759 ;CHECK-NOT: dup 760 ;CHECK: sqdmulh.8h 761 %tmp1 = load <8 x i16>, <8 x i16>* %A 762 %tmp2 = load <8 x i16>, <8 x i16>* %B 763 %tmp3 = shufflevector <8 x i16> %tmp2, <8 x i16> %tmp2, <8 x i32> <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> 764 %tmp4 = call <8 x i16> @llvm.aarch64.neon.sqdmulh.v8i16(<8 x i16> %tmp1, <8 x i16> %tmp3) 765 ret <8 x i16> %tmp4 766 } 767 768 define <2 x i32> @sqdmulh_lane_2s(<2 x i32>* %A, <2 x i32>* %B) nounwind { 769 ;CHECK-LABEL: sqdmulh_lane_2s: 770 ;CHECK-NOT: dup 771 ;CHECK: sqdmulh.2s 772 %tmp1 = load <2 x i32>, <2 x i32>* %A 773 %tmp2 = load <2 x i32>, <2 x i32>* %B 774 %tmp3 = shufflevector <2 x i32> %tmp2, <2 x i32> %tmp2, <2 x i32> <i32 1, i32 1> 775 %tmp4 = call <2 x i32> @llvm.aarch64.neon.sqdmulh.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp3) 776 ret <2 x i32> %tmp4 777 } 778 779 define <4 x i32> @sqdmulh_lane_4s(<4 x i32>* %A, <4 x i32>* %B) nounwind { 780 ;CHECK-LABEL: sqdmulh_lane_4s: 781 ;CHECK-NOT: dup 782 ;CHECK: sqdmulh.4s 783 %tmp1 = load <4 x i32>, <4 x i32>* %A 784 %tmp2 = load <4 x i32>, <4 x i32>* %B 785 %tmp3 = shufflevector <4 x i32> %tmp2, <4 x i32> %tmp2, <4 x i32> <i32 1, i32 1, i32 1, i32 1> 786 %tmp4 = call <4 x i32> @llvm.aarch64.neon.sqdmulh.v4i32(<4 x i32> %tmp1, <4 x i32> %tmp3) 787 ret <4 x i32> %tmp4 788 } 789 790 define i32 @sqdmulh_lane_1s(i32 %A, <4 x i32> %B) nounwind { 791 ;CHECK-LABEL: sqdmulh_lane_1s: 792 ;CHECK-NOT: dup 793 ;CHECK: sqdmulh.s s0, {{s[0-9]+}}, {{v[0-9]+}}[1] 794 %tmp1 = extractelement <4 x i32> %B, i32 1 795 %tmp2 = call i32 @llvm.aarch64.neon.sqdmulh.i32(i32 %A, i32 %tmp1) 796 ret i32 %tmp2 797 } 798 799 define <4 x i16> @sqrdmulh_lane_4h(<4 x i16>* %A, <4 x i16>* %B) nounwind { 800 ;CHECK-LABEL: sqrdmulh_lane_4h: 801 ;CHECK-NOT: dup 802 ;CHECK: sqrdmulh.4h 803 %tmp1 = load <4 x i16>, <4 x i16>* %A 804 %tmp2 = load <4 x i16>, <4 x i16>* %B 805 %tmp3 = shufflevector <4 x i16> %tmp2, <4 x i16> %tmp2, <4 x i32> <i32 1, i32 1, i32 1, i32 1> 806 %tmp4 = call <4 x i16> @llvm.aarch64.neon.sqrdmulh.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp3) 807 ret <4 x i16> %tmp4 808 } 809 810 define <8 x i16> @sqrdmulh_lane_8h(<8 x i16>* %A, <8 x i16>* %B) nounwind { 811 ;CHECK-LABEL: sqrdmulh_lane_8h: 812 ;CHECK-NOT: dup 813 ;CHECK: sqrdmulh.8h 814 %tmp1 = load <8 x i16>, <8 x i16>* %A 815 %tmp2 = load <8 x i16>, <8 x i16>* %B 816 %tmp3 = shufflevector <8 x i16> %tmp2, <8 x i16> %tmp2, <8 x i32> <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> 817 %tmp4 = call <8 x i16> @llvm.aarch64.neon.sqrdmulh.v8i16(<8 x i16> %tmp1, <8 x i16> %tmp3) 818 ret <8 x i16> %tmp4 819 } 820 821 define <2 x i32> @sqrdmulh_lane_2s(<2 x i32>* %A, <2 x i32>* %B) nounwind { 822 ;CHECK-LABEL: sqrdmulh_lane_2s: 823 ;CHECK-NOT: dup 824 ;CHECK: sqrdmulh.2s 825 %tmp1 = load <2 x i32>, <2 x i32>* %A 826 %tmp2 = load <2 x i32>, <2 x i32>* %B 827 %tmp3 = shufflevector <2 x i32> %tmp2, <2 x i32> %tmp2, <2 x i32> <i32 1, i32 1> 828 %tmp4 = call <2 x i32> @llvm.aarch64.neon.sqrdmulh.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp3) 829 ret <2 x i32> %tmp4 830 } 831 832 define <4 x i32> @sqrdmulh_lane_4s(<4 x i32>* %A, <4 x i32>* %B) nounwind { 833 ;CHECK-LABEL: sqrdmulh_lane_4s: 834 ;CHECK-NOT: dup 835 ;CHECK: sqrdmulh.4s 836 %tmp1 = load <4 x i32>, <4 x i32>* %A 837 %tmp2 = load <4 x i32>, <4 x i32>* %B 838 %tmp3 = shufflevector <4 x i32> %tmp2, <4 x i32> %tmp2, <4 x i32> <i32 1, i32 1, i32 1, i32 1> 839 %tmp4 = call <4 x i32> @llvm.aarch64.neon.sqrdmulh.v4i32(<4 x i32> %tmp1, <4 x i32> %tmp3) 840 ret <4 x i32> %tmp4 841 } 842 843 define i32 @sqrdmulh_lane_1s(i32 %A, <4 x i32> %B) nounwind { 844 ;CHECK-LABEL: sqrdmulh_lane_1s: 845 ;CHECK-NOT: dup 846 ;CHECK: sqrdmulh.s s0, {{s[0-9]+}}, {{v[0-9]+}}[1] 847 %tmp1 = extractelement <4 x i32> %B, i32 1 848 %tmp2 = call i32 @llvm.aarch64.neon.sqrdmulh.i32(i32 %A, i32 %tmp1) 849 ret i32 %tmp2 850 } 851 852 define <4 x i32> @sqdmull_lane_4s(<4 x i16>* %A, <4 x i16>* %B) nounwind { 853 ;CHECK-LABEL: sqdmull_lane_4s: 854 ;CHECK-NOT: dup 855 ;CHECK: sqdmull.4s 856 %tmp1 = load <4 x i16>, <4 x i16>* %A 857 %tmp2 = load <4 x i16>, <4 x i16>* %B 858 %tmp3 = shufflevector <4 x i16> %tmp2, <4 x i16> %tmp2, <4 x i32> <i32 1, i32 1, i32 1, i32 1> 859 %tmp4 = call <4 x i32> @llvm.aarch64.neon.sqdmull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp3) 860 ret <4 x i32> %tmp4 861 } 862 863 define <2 x i64> @sqdmull_lane_2d(<2 x i32>* %A, <2 x i32>* %B) nounwind { 864 ;CHECK-LABEL: sqdmull_lane_2d: 865 ;CHECK-NOT: dup 866 ;CHECK: sqdmull.2d 867 %tmp1 = load <2 x i32>, <2 x i32>* %A 868 %tmp2 = load <2 x i32>, <2 x i32>* %B 869 %tmp3 = shufflevector <2 x i32> %tmp2, <2 x i32> %tmp2, <2 x i32> <i32 1, i32 1> 870 %tmp4 = call <2 x i64> @llvm.aarch64.neon.sqdmull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp3) 871 ret <2 x i64> %tmp4 872 } 873 874 define <4 x i32> @sqdmull2_lane_4s(<8 x i16>* %A, <8 x i16>* %B) nounwind { 875 ;CHECK-LABEL: sqdmull2_lane_4s: 876 ;CHECK-NOT: dup 877 ;CHECK: sqdmull2.4s 878 %load1 = load <8 x i16>, <8 x i16>* %A 879 %load2 = load <8 x i16>, <8 x i16>* %B 880 %tmp1 = shufflevector <8 x i16> %load1, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7> 881 %tmp2 = shufflevector <8 x i16> %load2, <8 x i16> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1> 882 %tmp4 = call <4 x i32> @llvm.aarch64.neon.sqdmull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp2) 883 ret <4 x i32> %tmp4 884 } 885 886 define <2 x i64> @sqdmull2_lane_2d(<4 x i32>* %A, <4 x i32>* %B) nounwind { 887 ;CHECK-LABEL: sqdmull2_lane_2d: 888 ;CHECK-NOT: dup 889 ;CHECK: sqdmull2.2d 890 %load1 = load <4 x i32>, <4 x i32>* %A 891 %load2 = load <4 x i32>, <4 x i32>* %B 892 %tmp1 = shufflevector <4 x i32> %load1, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 893 %tmp2 = shufflevector <4 x i32> %load2, <4 x i32> undef, <2 x i32> <i32 1, i32 1> 894 %tmp4 = call <2 x i64> @llvm.aarch64.neon.sqdmull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp2) 895 ret <2 x i64> %tmp4 896 } 897 898 define <4 x i32> @umull_lane_4s(<4 x i16>* %A, <4 x i16>* %B) nounwind { 899 ;CHECK-LABEL: umull_lane_4s: 900 ;CHECK-NOT: dup 901 ;CHECK: umull.4s 902 %tmp1 = load <4 x i16>, <4 x i16>* %A 903 %tmp2 = load <4 x i16>, <4 x i16>* %B 904 %tmp3 = shufflevector <4 x i16> %tmp2, <4 x i16> %tmp2, <4 x i32> <i32 1, i32 1, i32 1, i32 1> 905 %tmp4 = call <4 x i32> @llvm.aarch64.neon.umull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp3) 906 ret <4 x i32> %tmp4 907 } 908 909 define <2 x i64> @umull_lane_2d(<2 x i32>* %A, <2 x i32>* %B) nounwind { 910 ;CHECK-LABEL: umull_lane_2d: 911 ;CHECK-NOT: dup 912 ;CHECK: umull.2d 913 %tmp1 = load <2 x i32>, <2 x i32>* %A 914 %tmp2 = load <2 x i32>, <2 x i32>* %B 915 %tmp3 = shufflevector <2 x i32> %tmp2, <2 x i32> %tmp2, <2 x i32> <i32 1, i32 1> 916 %tmp4 = call <2 x i64> @llvm.aarch64.neon.umull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp3) 917 ret <2 x i64> %tmp4 918 } 919 920 define <4 x i32> @smull_lane_4s(<4 x i16>* %A, <4 x i16>* %B) nounwind { 921 ;CHECK-LABEL: smull_lane_4s: 922 ;CHECK-NOT: dup 923 ;CHECK: smull.4s 924 %tmp1 = load <4 x i16>, <4 x i16>* %A 925 %tmp2 = load <4 x i16>, <4 x i16>* %B 926 %tmp3 = shufflevector <4 x i16> %tmp2, <4 x i16> %tmp2, <4 x i32> <i32 1, i32 1, i32 1, i32 1> 927 %tmp4 = call <4 x i32> @llvm.aarch64.neon.smull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp3) 928 ret <4 x i32> %tmp4 929 } 930 931 define <2 x i64> @smull_lane_2d(<2 x i32>* %A, <2 x i32>* %B) nounwind { 932 ;CHECK-LABEL: smull_lane_2d: 933 ;CHECK-NOT: dup 934 ;CHECK: smull.2d 935 %tmp1 = load <2 x i32>, <2 x i32>* %A 936 %tmp2 = load <2 x i32>, <2 x i32>* %B 937 %tmp3 = shufflevector <2 x i32> %tmp2, <2 x i32> %tmp2, <2 x i32> <i32 1, i32 1> 938 %tmp4 = call <2 x i64> @llvm.aarch64.neon.smull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp3) 939 ret <2 x i64> %tmp4 940 } 941 942 define <4 x i32> @smlal_lane_4s(<4 x i16>* %A, <4 x i16>* %B, <4 x i32>* %C) nounwind { 943 ;CHECK-LABEL: smlal_lane_4s: 944 ;CHECK-NOT: dup 945 ;CHECK: smlal.4s 946 %tmp1 = load <4 x i16>, <4 x i16>* %A 947 %tmp2 = load <4 x i16>, <4 x i16>* %B 948 %tmp3 = load <4 x i32>, <4 x i32>* %C 949 %tmp4 = shufflevector <4 x i16> %tmp2, <4 x i16> %tmp2, <4 x i32> <i32 1, i32 1, i32 1, i32 1> 950 %tmp5 = call <4 x i32> @llvm.aarch64.neon.smull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp4) 951 %tmp6 = add <4 x i32> %tmp3, %tmp5 952 ret <4 x i32> %tmp6 953 } 954 955 define <2 x i64> @smlal_lane_2d(<2 x i32>* %A, <2 x i32>* %B, <2 x i64>* %C) nounwind { 956 ;CHECK-LABEL: smlal_lane_2d: 957 ;CHECK-NOT: dup 958 ;CHECK: smlal.2d 959 %tmp1 = load <2 x i32>, <2 x i32>* %A 960 %tmp2 = load <2 x i32>, <2 x i32>* %B 961 %tmp3 = load <2 x i64>, <2 x i64>* %C 962 %tmp4 = shufflevector <2 x i32> %tmp2, <2 x i32> %tmp2, <2 x i32> <i32 1, i32 1> 963 %tmp5 = call <2 x i64> @llvm.aarch64.neon.smull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp4) 964 %tmp6 = add <2 x i64> %tmp3, %tmp5 965 ret <2 x i64> %tmp6 966 } 967 968 define <4 x i32> @sqdmlal_lane_4s(<4 x i16>* %A, <4 x i16>* %B, <4 x i32>* %C) nounwind { 969 ;CHECK-LABEL: sqdmlal_lane_4s: 970 ;CHECK-NOT: dup 971 ;CHECK: sqdmlal.4s 972 %tmp1 = load <4 x i16>, <4 x i16>* %A 973 %tmp2 = load <4 x i16>, <4 x i16>* %B 974 %tmp3 = load <4 x i32>, <4 x i32>* %C 975 %tmp4 = shufflevector <4 x i16> %tmp2, <4 x i16> %tmp2, <4 x i32> <i32 1, i32 1, i32 1, i32 1> 976 %tmp5 = call <4 x i32> @llvm.aarch64.neon.sqdmull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp4) 977 %tmp6 = call <4 x i32> @llvm.aarch64.neon.sqadd.v4i32(<4 x i32> %tmp3, <4 x i32> %tmp5) 978 ret <4 x i32> %tmp6 979 } 980 981 define <2 x i64> @sqdmlal_lane_2d(<2 x i32>* %A, <2 x i32>* %B, <2 x i64>* %C) nounwind { 982 ;CHECK-LABEL: sqdmlal_lane_2d: 983 ;CHECK-NOT: dup 984 ;CHECK: sqdmlal.2d 985 %tmp1 = load <2 x i32>, <2 x i32>* %A 986 %tmp2 = load <2 x i32>, <2 x i32>* %B 987 %tmp3 = load <2 x i64>, <2 x i64>* %C 988 %tmp4 = shufflevector <2 x i32> %tmp2, <2 x i32> %tmp2, <2 x i32> <i32 1, i32 1> 989 %tmp5 = call <2 x i64> @llvm.aarch64.neon.sqdmull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp4) 990 %tmp6 = call <2 x i64> @llvm.aarch64.neon.sqadd.v2i64(<2 x i64> %tmp3, <2 x i64> %tmp5) 991 ret <2 x i64> %tmp6 992 } 993 994 define <4 x i32> @sqdmlal2_lane_4s(<8 x i16>* %A, <8 x i16>* %B, <4 x i32>* %C) nounwind { 995 ;CHECK-LABEL: sqdmlal2_lane_4s: 996 ;CHECK-NOT: dup 997 ;CHECK: sqdmlal2.4s 998 %load1 = load <8 x i16>, <8 x i16>* %A 999 %load2 = load <8 x i16>, <8 x i16>* %B 1000 %tmp3 = load <4 x i32>, <4 x i32>* %C 1001 %tmp1 = shufflevector <8 x i16> %load1, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7> 1002 %tmp2 = shufflevector <8 x i16> %load2, <8 x i16> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1> 1003 %tmp5 = call <4 x i32> @llvm.aarch64.neon.sqdmull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp2) 1004 %tmp6 = call <4 x i32> @llvm.aarch64.neon.sqadd.v4i32(<4 x i32> %tmp3, <4 x i32> %tmp5) 1005 ret <4 x i32> %tmp6 1006 } 1007 1008 define <2 x i64> @sqdmlal2_lane_2d(<4 x i32>* %A, <4 x i32>* %B, <2 x i64>* %C) nounwind { 1009 ;CHECK-LABEL: sqdmlal2_lane_2d: 1010 ;CHECK-NOT: dup 1011 ;CHECK: sqdmlal2.2d 1012 %load1 = load <4 x i32>, <4 x i32>* %A 1013 %load2 = load <4 x i32>, <4 x i32>* %B 1014 %tmp3 = load <2 x i64>, <2 x i64>* %C 1015 %tmp1 = shufflevector <4 x i32> %load1, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 1016 %tmp2 = shufflevector <4 x i32> %load2, <4 x i32> undef, <2 x i32> <i32 1, i32 1> 1017 %tmp5 = call <2 x i64> @llvm.aarch64.neon.sqdmull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp2) 1018 %tmp6 = call <2 x i64> @llvm.aarch64.neon.sqadd.v2i64(<2 x i64> %tmp3, <2 x i64> %tmp5) 1019 ret <2 x i64> %tmp6 1020 } 1021 1022 define i32 @sqdmlal_lane_1s(i32 %A, i16 %B, <4 x i16> %C) nounwind { 1023 ;CHECK-LABEL: sqdmlal_lane_1s: 1024 ;CHECK: sqdmlal.4s 1025 %lhs = insertelement <4 x i16> undef, i16 %B, i32 0 1026 %rhs = shufflevector <4 x i16> %C, <4 x i16> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef> 1027 %prod.vec = call <4 x i32> @llvm.aarch64.neon.sqdmull.v4i32(<4 x i16> %lhs, <4 x i16> %rhs) 1028 %prod = extractelement <4 x i32> %prod.vec, i32 0 1029 %res = call i32 @llvm.aarch64.neon.sqadd.i32(i32 %A, i32 %prod) 1030 ret i32 %res 1031 } 1032 declare i32 @llvm.aarch64.neon.sqadd.i32(i32, i32) 1033 1034 define i32 @sqdmlsl_lane_1s(i32 %A, i16 %B, <4 x i16> %C) nounwind { 1035 ;CHECK-LABEL: sqdmlsl_lane_1s: 1036 ;CHECK: sqdmlsl.4s 1037 %lhs = insertelement <4 x i16> undef, i16 %B, i32 0 1038 %rhs = shufflevector <4 x i16> %C, <4 x i16> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef> 1039 %prod.vec = call <4 x i32> @llvm.aarch64.neon.sqdmull.v4i32(<4 x i16> %lhs, <4 x i16> %rhs) 1040 %prod = extractelement <4 x i32> %prod.vec, i32 0 1041 %res = call i32 @llvm.aarch64.neon.sqsub.i32(i32 %A, i32 %prod) 1042 ret i32 %res 1043 } 1044 declare i32 @llvm.aarch64.neon.sqsub.i32(i32, i32) 1045 1046 define i64 @sqdmlal_lane_1d(i64 %A, i32 %B, <2 x i32> %C) nounwind { 1047 ;CHECK-LABEL: sqdmlal_lane_1d: 1048 ;CHECK: sqdmlal.s 1049 %rhs = extractelement <2 x i32> %C, i32 1 1050 %prod = call i64 @llvm.aarch64.neon.sqdmulls.scalar(i32 %B, i32 %rhs) 1051 %res = call i64 @llvm.aarch64.neon.sqadd.i64(i64 %A, i64 %prod) 1052 ret i64 %res 1053 } 1054 declare i64 @llvm.aarch64.neon.sqdmulls.scalar(i32, i32) 1055 declare i64 @llvm.aarch64.neon.sqadd.i64(i64, i64) 1056 1057 define i64 @sqdmlsl_lane_1d(i64 %A, i32 %B, <2 x i32> %C) nounwind { 1058 ;CHECK-LABEL: sqdmlsl_lane_1d: 1059 ;CHECK: sqdmlsl.s 1060 %rhs = extractelement <2 x i32> %C, i32 1 1061 %prod = call i64 @llvm.aarch64.neon.sqdmulls.scalar(i32 %B, i32 %rhs) 1062 %res = call i64 @llvm.aarch64.neon.sqsub.i64(i64 %A, i64 %prod) 1063 ret i64 %res 1064 } 1065 declare i64 @llvm.aarch64.neon.sqsub.i64(i64, i64) 1066 1067 1068 define <4 x i32> @umlal_lane_4s(<4 x i16>* %A, <4 x i16>* %B, <4 x i32>* %C) nounwind { 1069 ;CHECK-LABEL: umlal_lane_4s: 1070 ;CHECK-NOT: dup 1071 ;CHECK: umlal.4s 1072 %tmp1 = load <4 x i16>, <4 x i16>* %A 1073 %tmp2 = load <4 x i16>, <4 x i16>* %B 1074 %tmp3 = load <4 x i32>, <4 x i32>* %C 1075 %tmp4 = shufflevector <4 x i16> %tmp2, <4 x i16> %tmp2, <4 x i32> <i32 1, i32 1, i32 1, i32 1> 1076 %tmp5 = call <4 x i32> @llvm.aarch64.neon.umull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp4) 1077 %tmp6 = add <4 x i32> %tmp3, %tmp5 1078 ret <4 x i32> %tmp6 1079 } 1080 1081 define <2 x i64> @umlal_lane_2d(<2 x i32>* %A, <2 x i32>* %B, <2 x i64>* %C) nounwind { 1082 ;CHECK-LABEL: umlal_lane_2d: 1083 ;CHECK-NOT: dup 1084 ;CHECK: umlal.2d 1085 %tmp1 = load <2 x i32>, <2 x i32>* %A 1086 %tmp2 = load <2 x i32>, <2 x i32>* %B 1087 %tmp3 = load <2 x i64>, <2 x i64>* %C 1088 %tmp4 = shufflevector <2 x i32> %tmp2, <2 x i32> %tmp2, <2 x i32> <i32 1, i32 1> 1089 %tmp5 = call <2 x i64> @llvm.aarch64.neon.umull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp4) 1090 %tmp6 = add <2 x i64> %tmp3, %tmp5 1091 ret <2 x i64> %tmp6 1092 } 1093 1094 1095 define <4 x i32> @smlsl_lane_4s(<4 x i16>* %A, <4 x i16>* %B, <4 x i32>* %C) nounwind { 1096 ;CHECK-LABEL: smlsl_lane_4s: 1097 ;CHECK-NOT: dup 1098 ;CHECK: smlsl.4s 1099 %tmp1 = load <4 x i16>, <4 x i16>* %A 1100 %tmp2 = load <4 x i16>, <4 x i16>* %B 1101 %tmp3 = load <4 x i32>, <4 x i32>* %C 1102 %tmp4 = shufflevector <4 x i16> %tmp2, <4 x i16> %tmp2, <4 x i32> <i32 1, i32 1, i32 1, i32 1> 1103 %tmp5 = call <4 x i32> @llvm.aarch64.neon.smull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp4) 1104 %tmp6 = sub <4 x i32> %tmp3, %tmp5 1105 ret <4 x i32> %tmp6 1106 } 1107 1108 define <2 x i64> @smlsl_lane_2d(<2 x i32>* %A, <2 x i32>* %B, <2 x i64>* %C) nounwind { 1109 ;CHECK-LABEL: smlsl_lane_2d: 1110 ;CHECK-NOT: dup 1111 ;CHECK: smlsl.2d 1112 %tmp1 = load <2 x i32>, <2 x i32>* %A 1113 %tmp2 = load <2 x i32>, <2 x i32>* %B 1114 %tmp3 = load <2 x i64>, <2 x i64>* %C 1115 %tmp4 = shufflevector <2 x i32> %tmp2, <2 x i32> %tmp2, <2 x i32> <i32 1, i32 1> 1116 %tmp5 = call <2 x i64> @llvm.aarch64.neon.smull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp4) 1117 %tmp6 = sub <2 x i64> %tmp3, %tmp5 1118 ret <2 x i64> %tmp6 1119 } 1120 1121 define <4 x i32> @sqdmlsl_lane_4s(<4 x i16>* %A, <4 x i16>* %B, <4 x i32>* %C) nounwind { 1122 ;CHECK-LABEL: sqdmlsl_lane_4s: 1123 ;CHECK-NOT: dup 1124 ;CHECK: sqdmlsl.4s 1125 %tmp1 = load <4 x i16>, <4 x i16>* %A 1126 %tmp2 = load <4 x i16>, <4 x i16>* %B 1127 %tmp3 = load <4 x i32>, <4 x i32>* %C 1128 %tmp4 = shufflevector <4 x i16> %tmp2, <4 x i16> %tmp2, <4 x i32> <i32 1, i32 1, i32 1, i32 1> 1129 %tmp5 = call <4 x i32> @llvm.aarch64.neon.sqdmull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp4) 1130 %tmp6 = call <4 x i32> @llvm.aarch64.neon.sqsub.v4i32(<4 x i32> %tmp3, <4 x i32> %tmp5) 1131 ret <4 x i32> %tmp6 1132 } 1133 1134 define <2 x i64> @sqdmlsl_lane_2d(<2 x i32>* %A, <2 x i32>* %B, <2 x i64>* %C) nounwind { 1135 ;CHECK-LABEL: sqdmlsl_lane_2d: 1136 ;CHECK-NOT: dup 1137 ;CHECK: sqdmlsl.2d 1138 %tmp1 = load <2 x i32>, <2 x i32>* %A 1139 %tmp2 = load <2 x i32>, <2 x i32>* %B 1140 %tmp3 = load <2 x i64>, <2 x i64>* %C 1141 %tmp4 = shufflevector <2 x i32> %tmp2, <2 x i32> %tmp2, <2 x i32> <i32 1, i32 1> 1142 %tmp5 = call <2 x i64> @llvm.aarch64.neon.sqdmull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp4) 1143 %tmp6 = call <2 x i64> @llvm.aarch64.neon.sqsub.v2i64(<2 x i64> %tmp3, <2 x i64> %tmp5) 1144 ret <2 x i64> %tmp6 1145 } 1146 1147 define <4 x i32> @sqdmlsl2_lane_4s(<8 x i16>* %A, <8 x i16>* %B, <4 x i32>* %C) nounwind { 1148 ;CHECK-LABEL: sqdmlsl2_lane_4s: 1149 ;CHECK-NOT: dup 1150 ;CHECK: sqdmlsl2.4s 1151 %load1 = load <8 x i16>, <8 x i16>* %A 1152 %load2 = load <8 x i16>, <8 x i16>* %B 1153 %tmp3 = load <4 x i32>, <4 x i32>* %C 1154 %tmp1 = shufflevector <8 x i16> %load1, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7> 1155 %tmp2 = shufflevector <8 x i16> %load2, <8 x i16> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1> 1156 %tmp5 = call <4 x i32> @llvm.aarch64.neon.sqdmull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp2) 1157 %tmp6 = call <4 x i32> @llvm.aarch64.neon.sqsub.v4i32(<4 x i32> %tmp3, <4 x i32> %tmp5) 1158 ret <4 x i32> %tmp6 1159 } 1160 1161 define <2 x i64> @sqdmlsl2_lane_2d(<4 x i32>* %A, <4 x i32>* %B, <2 x i64>* %C) nounwind { 1162 ;CHECK-LABEL: sqdmlsl2_lane_2d: 1163 ;CHECK-NOT: dup 1164 ;CHECK: sqdmlsl2.2d 1165 %load1 = load <4 x i32>, <4 x i32>* %A 1166 %load2 = load <4 x i32>, <4 x i32>* %B 1167 %tmp3 = load <2 x i64>, <2 x i64>* %C 1168 %tmp1 = shufflevector <4 x i32> %load1, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 1169 %tmp2 = shufflevector <4 x i32> %load2, <4 x i32> undef, <2 x i32> <i32 1, i32 1> 1170 %tmp5 = call <2 x i64> @llvm.aarch64.neon.sqdmull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp2) 1171 %tmp6 = call <2 x i64> @llvm.aarch64.neon.sqsub.v2i64(<2 x i64> %tmp3, <2 x i64> %tmp5) 1172 ret <2 x i64> %tmp6 1173 } 1174 1175 define <4 x i32> @umlsl_lane_4s(<4 x i16>* %A, <4 x i16>* %B, <4 x i32>* %C) nounwind { 1176 ;CHECK-LABEL: umlsl_lane_4s: 1177 ;CHECK-NOT: dup 1178 ;CHECK: umlsl.4s 1179 %tmp1 = load <4 x i16>, <4 x i16>* %A 1180 %tmp2 = load <4 x i16>, <4 x i16>* %B 1181 %tmp3 = load <4 x i32>, <4 x i32>* %C 1182 %tmp4 = shufflevector <4 x i16> %tmp2, <4 x i16> %tmp2, <4 x i32> <i32 1, i32 1, i32 1, i32 1> 1183 %tmp5 = call <4 x i32> @llvm.aarch64.neon.umull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp4) 1184 %tmp6 = sub <4 x i32> %tmp3, %tmp5 1185 ret <4 x i32> %tmp6 1186 } 1187 1188 define <2 x i64> @umlsl_lane_2d(<2 x i32>* %A, <2 x i32>* %B, <2 x i64>* %C) nounwind { 1189 ;CHECK-LABEL: umlsl_lane_2d: 1190 ;CHECK-NOT: dup 1191 ;CHECK: umlsl.2d 1192 %tmp1 = load <2 x i32>, <2 x i32>* %A 1193 %tmp2 = load <2 x i32>, <2 x i32>* %B 1194 %tmp3 = load <2 x i64>, <2 x i64>* %C 1195 %tmp4 = shufflevector <2 x i32> %tmp2, <2 x i32> %tmp2, <2 x i32> <i32 1, i32 1> 1196 %tmp5 = call <2 x i64> @llvm.aarch64.neon.umull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp4) 1197 %tmp6 = sub <2 x i64> %tmp3, %tmp5 1198 ret <2 x i64> %tmp6 1199 } 1200 1201 ; Scalar FMULX 1202 define float @fmulxs(float %a, float %b) nounwind { 1203 ; CHECK-LABEL: fmulxs: 1204 ; CHECKNEXT: fmulx s0, s0, s1 1205 %fmulx.i = tail call float @llvm.aarch64.neon.fmulx.f32(float %a, float %b) nounwind 1206 ; CHECKNEXT: ret 1207 ret float %fmulx.i 1208 } 1209 1210 define double @fmulxd(double %a, double %b) nounwind { 1211 ; CHECK-LABEL: fmulxd: 1212 ; CHECKNEXT: fmulx d0, d0, d1 1213 %fmulx.i = tail call double @llvm.aarch64.neon.fmulx.f64(double %a, double %b) nounwind 1214 ; CHECKNEXT: ret 1215 ret double %fmulx.i 1216 } 1217 1218 define float @fmulxs_lane(float %a, <4 x float> %vec) nounwind { 1219 ; CHECK-LABEL: fmulxs_lane: 1220 ; CHECKNEXT: fmulx.s s0, s0, v1[3] 1221 %b = extractelement <4 x float> %vec, i32 3 1222 %fmulx.i = tail call float @llvm.aarch64.neon.fmulx.f32(float %a, float %b) nounwind 1223 ; CHECKNEXT: ret 1224 ret float %fmulx.i 1225 } 1226 1227 define double @fmulxd_lane(double %a, <2 x double> %vec) nounwind { 1228 ; CHECK-LABEL: fmulxd_lane: 1229 ; CHECKNEXT: fmulx d0, d0, v1[1] 1230 %b = extractelement <2 x double> %vec, i32 1 1231 %fmulx.i = tail call double @llvm.aarch64.neon.fmulx.f64(double %a, double %b) nounwind 1232 ; CHECKNEXT: ret 1233 ret double %fmulx.i 1234 } 1235 1236 declare double @llvm.aarch64.neon.fmulx.f64(double, double) nounwind readnone 1237 declare float @llvm.aarch64.neon.fmulx.f32(float, float) nounwind readnone 1238 1239 1240 define <8 x i16> @smull2_8h_simple(<16 x i8> %a, <16 x i8> %b) nounwind { 1241 ; CHECK-LABEL: smull2_8h_simple: 1242 ; CHECK-NEXT: smull2.8h v0, v0, v1 1243 ; CHECK-NEXT: ret 1244 %1 = shufflevector <16 x i8> %a, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> 1245 %2 = shufflevector <16 x i8> %b, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> 1246 %3 = tail call <8 x i16> @llvm.aarch64.neon.smull.v8i16(<8 x i8> %1, <8 x i8> %2) #2 1247 ret <8 x i16> %3 1248 } 1249 1250 define <8 x i16> @foo0(<16 x i8> %a, <16 x i8> %b) nounwind { 1251 ; CHECK-LABEL: foo0: 1252 ; CHECK: smull2.8h v0, v0, v1 1253 %tmp = bitcast <16 x i8> %a to <2 x i64> 1254 %shuffle.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1> 1255 %tmp1 = bitcast <1 x i64> %shuffle.i.i to <8 x i8> 1256 %tmp2 = bitcast <16 x i8> %b to <2 x i64> 1257 %shuffle.i3.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1> 1258 %tmp3 = bitcast <1 x i64> %shuffle.i3.i to <8 x i8> 1259 %vmull.i.i = tail call <8 x i16> @llvm.aarch64.neon.smull.v8i16(<8 x i8> %tmp1, <8 x i8> %tmp3) nounwind 1260 ret <8 x i16> %vmull.i.i 1261 } 1262 1263 define <4 x i32> @foo1(<8 x i16> %a, <8 x i16> %b) nounwind { 1264 ; CHECK-LABEL: foo1: 1265 ; CHECK: smull2.4s v0, v0, v1 1266 %tmp = bitcast <8 x i16> %a to <2 x i64> 1267 %shuffle.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1> 1268 %tmp1 = bitcast <1 x i64> %shuffle.i.i to <4 x i16> 1269 %tmp2 = bitcast <8 x i16> %b to <2 x i64> 1270 %shuffle.i3.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1> 1271 %tmp3 = bitcast <1 x i64> %shuffle.i3.i to <4 x i16> 1272 %vmull2.i.i = tail call <4 x i32> @llvm.aarch64.neon.smull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp3) nounwind 1273 ret <4 x i32> %vmull2.i.i 1274 } 1275 1276 define <2 x i64> @foo2(<4 x i32> %a, <4 x i32> %b) nounwind { 1277 ; CHECK-LABEL: foo2: 1278 ; CHECK: smull2.2d v0, v0, v1 1279 %tmp = bitcast <4 x i32> %a to <2 x i64> 1280 %shuffle.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1> 1281 %tmp1 = bitcast <1 x i64> %shuffle.i.i to <2 x i32> 1282 %tmp2 = bitcast <4 x i32> %b to <2 x i64> 1283 %shuffle.i3.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1> 1284 %tmp3 = bitcast <1 x i64> %shuffle.i3.i to <2 x i32> 1285 %vmull2.i.i = tail call <2 x i64> @llvm.aarch64.neon.smull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp3) nounwind 1286 ret <2 x i64> %vmull2.i.i 1287 } 1288 1289 define <8 x i16> @foo3(<16 x i8> %a, <16 x i8> %b) nounwind { 1290 ; CHECK-LABEL: foo3: 1291 ; CHECK: umull2.8h v0, v0, v1 1292 %tmp = bitcast <16 x i8> %a to <2 x i64> 1293 %shuffle.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1> 1294 %tmp1 = bitcast <1 x i64> %shuffle.i.i to <8 x i8> 1295 %tmp2 = bitcast <16 x i8> %b to <2 x i64> 1296 %shuffle.i3.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1> 1297 %tmp3 = bitcast <1 x i64> %shuffle.i3.i to <8 x i8> 1298 %vmull.i.i = tail call <8 x i16> @llvm.aarch64.neon.umull.v8i16(<8 x i8> %tmp1, <8 x i8> %tmp3) nounwind 1299 ret <8 x i16> %vmull.i.i 1300 } 1301 1302 define <4 x i32> @foo4(<8 x i16> %a, <8 x i16> %b) nounwind { 1303 ; CHECK-LABEL: foo4: 1304 ; CHECK: umull2.4s v0, v0, v1 1305 %tmp = bitcast <8 x i16> %a to <2 x i64> 1306 %shuffle.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1> 1307 %tmp1 = bitcast <1 x i64> %shuffle.i.i to <4 x i16> 1308 %tmp2 = bitcast <8 x i16> %b to <2 x i64> 1309 %shuffle.i3.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1> 1310 %tmp3 = bitcast <1 x i64> %shuffle.i3.i to <4 x i16> 1311 %vmull2.i.i = tail call <4 x i32> @llvm.aarch64.neon.umull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp3) nounwind 1312 ret <4 x i32> %vmull2.i.i 1313 } 1314 1315 define <2 x i64> @foo5(<4 x i32> %a, <4 x i32> %b) nounwind { 1316 ; CHECK-LABEL: foo5: 1317 ; CHECK: umull2.2d v0, v0, v1 1318 %tmp = bitcast <4 x i32> %a to <2 x i64> 1319 %shuffle.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1> 1320 %tmp1 = bitcast <1 x i64> %shuffle.i.i to <2 x i32> 1321 %tmp2 = bitcast <4 x i32> %b to <2 x i64> 1322 %shuffle.i3.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1> 1323 %tmp3 = bitcast <1 x i64> %shuffle.i3.i to <2 x i32> 1324 %vmull2.i.i = tail call <2 x i64> @llvm.aarch64.neon.umull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp3) nounwind 1325 ret <2 x i64> %vmull2.i.i 1326 } 1327 1328 define <4 x i32> @foo6(<4 x i32> %a, <8 x i16> %b, <4 x i16> %c) nounwind readnone optsize ssp { 1329 ; CHECK-LABEL: foo6: 1330 ; CHECK-NEXT: smull2.4s v0, v1, v2[1] 1331 ; CHECK-NEXT: ret 1332 entry: 1333 %0 = bitcast <8 x i16> %b to <2 x i64> 1334 %shuffle.i = shufflevector <2 x i64> %0, <2 x i64> undef, <1 x i32> <i32 1> 1335 %1 = bitcast <1 x i64> %shuffle.i to <4 x i16> 1336 %shuffle = shufflevector <4 x i16> %c, <4 x i16> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1> 1337 %vmull2.i = tail call <4 x i32> @llvm.aarch64.neon.smull.v4i32(<4 x i16> %1, <4 x i16> %shuffle) nounwind 1338 ret <4 x i32> %vmull2.i 1339 } 1340 1341 define <2 x i64> @foo7(<2 x i64> %a, <4 x i32> %b, <2 x i32> %c) nounwind readnone optsize ssp { 1342 ; CHECK-LABEL: foo7: 1343 ; CHECK-NEXT: smull2.2d v0, v1, v2[1] 1344 ; CHECK-NEXT: ret 1345 entry: 1346 %0 = bitcast <4 x i32> %b to <2 x i64> 1347 %shuffle.i = shufflevector <2 x i64> %0, <2 x i64> undef, <1 x i32> <i32 1> 1348 %1 = bitcast <1 x i64> %shuffle.i to <2 x i32> 1349 %shuffle = shufflevector <2 x i32> %c, <2 x i32> undef, <2 x i32> <i32 1, i32 1> 1350 %vmull2.i = tail call <2 x i64> @llvm.aarch64.neon.smull.v2i64(<2 x i32> %1, <2 x i32> %shuffle) nounwind 1351 ret <2 x i64> %vmull2.i 1352 } 1353 1354 define <4 x i32> @foo8(<4 x i32> %a, <8 x i16> %b, <4 x i16> %c) nounwind readnone optsize ssp { 1355 ; CHECK-LABEL: foo8: 1356 ; CHECK-NEXT: umull2.4s v0, v1, v2[1] 1357 ; CHECK-NEXT: ret 1358 entry: 1359 %0 = bitcast <8 x i16> %b to <2 x i64> 1360 %shuffle.i = shufflevector <2 x i64> %0, <2 x i64> undef, <1 x i32> <i32 1> 1361 %1 = bitcast <1 x i64> %shuffle.i to <4 x i16> 1362 %shuffle = shufflevector <4 x i16> %c, <4 x i16> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1> 1363 %vmull2.i = tail call <4 x i32> @llvm.aarch64.neon.umull.v4i32(<4 x i16> %1, <4 x i16> %shuffle) nounwind 1364 ret <4 x i32> %vmull2.i 1365 } 1366 1367 define <2 x i64> @foo9(<2 x i64> %a, <4 x i32> %b, <2 x i32> %c) nounwind readnone optsize ssp { 1368 ; CHECK-LABEL: foo9: 1369 ; CHECK-NEXT: umull2.2d v0, v1, v2[1] 1370 ; CHECK-NEXT: ret 1371 entry: 1372 %0 = bitcast <4 x i32> %b to <2 x i64> 1373 %shuffle.i = shufflevector <2 x i64> %0, <2 x i64> undef, <1 x i32> <i32 1> 1374 %1 = bitcast <1 x i64> %shuffle.i to <2 x i32> 1375 %shuffle = shufflevector <2 x i32> %c, <2 x i32> undef, <2 x i32> <i32 1, i32 1> 1376 %vmull2.i = tail call <2 x i64> @llvm.aarch64.neon.umull.v2i64(<2 x i32> %1, <2 x i32> %shuffle) nounwind 1377 ret <2 x i64> %vmull2.i 1378 } 1379 1380 define <8 x i16> @bar0(<8 x i16> %a, <16 x i8> %b, <16 x i8> %c) nounwind { 1381 ; CHECK-LABEL: bar0: 1382 ; CHECK: smlal2.8h v0, v1, v2 1383 ; CHECK-NEXT: ret 1384 1385 %tmp = bitcast <16 x i8> %b to <2 x i64> 1386 %shuffle.i.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1> 1387 %tmp1 = bitcast <1 x i64> %shuffle.i.i.i to <8 x i8> 1388 %tmp2 = bitcast <16 x i8> %c to <2 x i64> 1389 %shuffle.i3.i.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1> 1390 %tmp3 = bitcast <1 x i64> %shuffle.i3.i.i to <8 x i8> 1391 %vmull.i.i.i = tail call <8 x i16> @llvm.aarch64.neon.smull.v8i16(<8 x i8> %tmp1, <8 x i8> %tmp3) nounwind 1392 %add.i = add <8 x i16> %vmull.i.i.i, %a 1393 ret <8 x i16> %add.i 1394 } 1395 1396 define <4 x i32> @bar1(<4 x i32> %a, <8 x i16> %b, <8 x i16> %c) nounwind { 1397 ; CHECK-LABEL: bar1: 1398 ; CHECK: smlal2.4s v0, v1, v2 1399 ; CHECK-NEXT: ret 1400 1401 %tmp = bitcast <8 x i16> %b to <2 x i64> 1402 %shuffle.i.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1> 1403 %tmp1 = bitcast <1 x i64> %shuffle.i.i.i to <4 x i16> 1404 %tmp2 = bitcast <8 x i16> %c to <2 x i64> 1405 %shuffle.i3.i.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1> 1406 %tmp3 = bitcast <1 x i64> %shuffle.i3.i.i to <4 x i16> 1407 %vmull2.i.i.i = tail call <4 x i32> @llvm.aarch64.neon.smull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp3) nounwind 1408 %add.i = add <4 x i32> %vmull2.i.i.i, %a 1409 ret <4 x i32> %add.i 1410 } 1411 1412 define <2 x i64> @bar2(<2 x i64> %a, <4 x i32> %b, <4 x i32> %c) nounwind { 1413 ; CHECK-LABEL: bar2: 1414 ; CHECK: smlal2.2d v0, v1, v2 1415 ; CHECK-NEXT: ret 1416 1417 %tmp = bitcast <4 x i32> %b to <2 x i64> 1418 %shuffle.i.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1> 1419 %tmp1 = bitcast <1 x i64> %shuffle.i.i.i to <2 x i32> 1420 %tmp2 = bitcast <4 x i32> %c to <2 x i64> 1421 %shuffle.i3.i.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1> 1422 %tmp3 = bitcast <1 x i64> %shuffle.i3.i.i to <2 x i32> 1423 %vmull2.i.i.i = tail call <2 x i64> @llvm.aarch64.neon.smull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp3) nounwind 1424 %add.i = add <2 x i64> %vmull2.i.i.i, %a 1425 ret <2 x i64> %add.i 1426 } 1427 1428 define <8 x i16> @bar3(<8 x i16> %a, <16 x i8> %b, <16 x i8> %c) nounwind { 1429 ; CHECK-LABEL: bar3: 1430 ; CHECK: umlal2.8h v0, v1, v2 1431 ; CHECK-NEXT: ret 1432 1433 %tmp = bitcast <16 x i8> %b to <2 x i64> 1434 %shuffle.i.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1> 1435 %tmp1 = bitcast <1 x i64> %shuffle.i.i.i to <8 x i8> 1436 %tmp2 = bitcast <16 x i8> %c to <2 x i64> 1437 %shuffle.i3.i.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1> 1438 %tmp3 = bitcast <1 x i64> %shuffle.i3.i.i to <8 x i8> 1439 %vmull.i.i.i = tail call <8 x i16> @llvm.aarch64.neon.umull.v8i16(<8 x i8> %tmp1, <8 x i8> %tmp3) nounwind 1440 %add.i = add <8 x i16> %vmull.i.i.i, %a 1441 ret <8 x i16> %add.i 1442 } 1443 1444 define <4 x i32> @bar4(<4 x i32> %a, <8 x i16> %b, <8 x i16> %c) nounwind { 1445 ; CHECK-LABEL: bar4: 1446 ; CHECK: umlal2.4s v0, v1, v2 1447 ; CHECK-NEXT: ret 1448 1449 %tmp = bitcast <8 x i16> %b to <2 x i64> 1450 %shuffle.i.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1> 1451 %tmp1 = bitcast <1 x i64> %shuffle.i.i.i to <4 x i16> 1452 %tmp2 = bitcast <8 x i16> %c to <2 x i64> 1453 %shuffle.i3.i.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1> 1454 %tmp3 = bitcast <1 x i64> %shuffle.i3.i.i to <4 x i16> 1455 %vmull2.i.i.i = tail call <4 x i32> @llvm.aarch64.neon.umull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp3) nounwind 1456 %add.i = add <4 x i32> %vmull2.i.i.i, %a 1457 ret <4 x i32> %add.i 1458 } 1459 1460 define <2 x i64> @bar5(<2 x i64> %a, <4 x i32> %b, <4 x i32> %c) nounwind { 1461 ; CHECK-LABEL: bar5: 1462 ; CHECK: umlal2.2d v0, v1, v2 1463 ; CHECK-NEXT: ret 1464 1465 %tmp = bitcast <4 x i32> %b to <2 x i64> 1466 %shuffle.i.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1> 1467 %tmp1 = bitcast <1 x i64> %shuffle.i.i.i to <2 x i32> 1468 %tmp2 = bitcast <4 x i32> %c to <2 x i64> 1469 %shuffle.i3.i.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1> 1470 %tmp3 = bitcast <1 x i64> %shuffle.i3.i.i to <2 x i32> 1471 %vmull2.i.i.i = tail call <2 x i64> @llvm.aarch64.neon.umull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp3) nounwind 1472 %add.i = add <2 x i64> %vmull2.i.i.i, %a 1473 ret <2 x i64> %add.i 1474 } 1475 1476 define <4 x i32> @mlal2_1(<4 x i32> %a, <8 x i16> %b, <4 x i16> %c) nounwind { 1477 ; CHECK-LABEL: mlal2_1: 1478 ; CHECK: smlal2.4s v0, v1, v2[3] 1479 ; CHECK-NEXT: ret 1480 %shuffle = shufflevector <4 x i16> %c, <4 x i16> undef, <8 x i32> <i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3> 1481 %tmp = bitcast <8 x i16> %b to <2 x i64> 1482 %shuffle.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1> 1483 %tmp1 = bitcast <1 x i64> %shuffle.i.i to <4 x i16> 1484 %tmp2 = bitcast <8 x i16> %shuffle to <2 x i64> 1485 %shuffle.i3.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1> 1486 %tmp3 = bitcast <1 x i64> %shuffle.i3.i to <4 x i16> 1487 %vmull2.i.i = tail call <4 x i32> @llvm.aarch64.neon.smull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp3) nounwind 1488 %add = add <4 x i32> %vmull2.i.i, %a 1489 ret <4 x i32> %add 1490 } 1491 1492 define <2 x i64> @mlal2_2(<2 x i64> %a, <4 x i32> %b, <2 x i32> %c) nounwind { 1493 ; CHECK-LABEL: mlal2_2: 1494 ; CHECK: smlal2.2d v0, v1, v2[1] 1495 ; CHECK-NEXT: ret 1496 %shuffle = shufflevector <2 x i32> %c, <2 x i32> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1> 1497 %tmp = bitcast <4 x i32> %b to <2 x i64> 1498 %shuffle.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1> 1499 %tmp1 = bitcast <1 x i64> %shuffle.i.i to <2 x i32> 1500 %tmp2 = bitcast <4 x i32> %shuffle to <2 x i64> 1501 %shuffle.i3.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1> 1502 %tmp3 = bitcast <1 x i64> %shuffle.i3.i to <2 x i32> 1503 %vmull2.i.i = tail call <2 x i64> @llvm.aarch64.neon.smull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp3) nounwind 1504 %add = add <2 x i64> %vmull2.i.i, %a 1505 ret <2 x i64> %add 1506 } 1507 1508 define <4 x i32> @mlal2_4(<4 x i32> %a, <8 x i16> %b, <4 x i16> %c) nounwind { 1509 ; CHECK-LABEL: mlal2_4: 1510 ; CHECK: umlal2.4s v0, v1, v2[2] 1511 ; CHECK-NEXT: ret 1512 1513 %shuffle = shufflevector <4 x i16> %c, <4 x i16> undef, <8 x i32> <i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2> 1514 %tmp = bitcast <8 x i16> %b to <2 x i64> 1515 %shuffle.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1> 1516 %tmp1 = bitcast <1 x i64> %shuffle.i.i to <4 x i16> 1517 %tmp2 = bitcast <8 x i16> %shuffle to <2 x i64> 1518 %shuffle.i3.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1> 1519 %tmp3 = bitcast <1 x i64> %shuffle.i3.i to <4 x i16> 1520 %vmull2.i.i = tail call <4 x i32> @llvm.aarch64.neon.umull.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp3) nounwind 1521 %add = add <4 x i32> %vmull2.i.i, %a 1522 ret <4 x i32> %add 1523 } 1524 1525 define <2 x i64> @mlal2_5(<2 x i64> %a, <4 x i32> %b, <2 x i32> %c) nounwind { 1526 ; CHECK-LABEL: mlal2_5: 1527 ; CHECK: umlal2.2d v0, v1, v2[0] 1528 ; CHECK-NEXT: ret 1529 %shuffle = shufflevector <2 x i32> %c, <2 x i32> undef, <4 x i32> zeroinitializer 1530 %tmp = bitcast <4 x i32> %b to <2 x i64> 1531 %shuffle.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1> 1532 %tmp1 = bitcast <1 x i64> %shuffle.i.i to <2 x i32> 1533 %tmp2 = bitcast <4 x i32> %shuffle to <2 x i64> 1534 %shuffle.i3.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1> 1535 %tmp3 = bitcast <1 x i64> %shuffle.i3.i to <2 x i32> 1536 %vmull2.i.i = tail call <2 x i64> @llvm.aarch64.neon.umull.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp3) nounwind 1537 %add = add <2 x i64> %vmull2.i.i, %a 1538 ret <2 x i64> %add 1539 } 1540 1541 ; rdar://12328502 1542 define <2 x double> @vmulq_n_f64(<2 x double> %x, double %y) nounwind readnone ssp { 1543 entry: 1544 ; CHECK-LABEL: vmulq_n_f64: 1545 ; CHECK-NOT: dup.2d 1546 ; CHECK: fmul.2d v0, v0, v1[0] 1547 %vecinit.i = insertelement <2 x double> undef, double %y, i32 0 1548 %vecinit1.i = insertelement <2 x double> %vecinit.i, double %y, i32 1 1549 %mul.i = fmul <2 x double> %vecinit1.i, %x 1550 ret <2 x double> %mul.i 1551 } 1552 1553 define <4 x float> @vmulq_n_f32(<4 x float> %x, float %y) nounwind readnone ssp { 1554 entry: 1555 ; CHECK-LABEL: vmulq_n_f32: 1556 ; CHECK-NOT: dup.4s 1557 ; CHECK: fmul.4s v0, v0, v1[0] 1558 %vecinit.i = insertelement <4 x float> undef, float %y, i32 0 1559 %vecinit1.i = insertelement <4 x float> %vecinit.i, float %y, i32 1 1560 %vecinit2.i = insertelement <4 x float> %vecinit1.i, float %y, i32 2 1561 %vecinit3.i = insertelement <4 x float> %vecinit2.i, float %y, i32 3 1562 %mul.i = fmul <4 x float> %vecinit3.i, %x 1563 ret <4 x float> %mul.i 1564 } 1565 1566 define <2 x float> @vmul_n_f32(<2 x float> %x, float %y) nounwind readnone ssp { 1567 entry: 1568 ; CHECK-LABEL: vmul_n_f32: 1569 ; CHECK-NOT: dup.2s 1570 ; CHECK: fmul.2s v0, v0, v1[0] 1571 %vecinit.i = insertelement <2 x float> undef, float %y, i32 0 1572 %vecinit1.i = insertelement <2 x float> %vecinit.i, float %y, i32 1 1573 %mul.i = fmul <2 x float> %vecinit1.i, %x 1574 ret <2 x float> %mul.i 1575 } 1576 1577 define <4 x i16> @vmla_laneq_s16_test(<4 x i16> %a, <4 x i16> %b, <8 x i16> %c) nounwind readnone ssp { 1578 entry: 1579 ; CHECK: vmla_laneq_s16_test 1580 ; CHECK-NOT: ext 1581 ; CHECK: mla.4h v0, v1, v2[6] 1582 ; CHECK-NEXT: ret 1583 %shuffle = shufflevector <8 x i16> %c, <8 x i16> undef, <4 x i32> <i32 6, i32 6, i32 6, i32 6> 1584 %mul = mul <4 x i16> %shuffle, %b 1585 %add = add <4 x i16> %mul, %a 1586 ret <4 x i16> %add 1587 } 1588 1589 define <2 x i32> @vmla_laneq_s32_test(<2 x i32> %a, <2 x i32> %b, <4 x i32> %c) nounwind readnone ssp { 1590 entry: 1591 ; CHECK: vmla_laneq_s32_test 1592 ; CHECK-NOT: ext 1593 ; CHECK: mla.2s v0, v1, v2[3] 1594 ; CHECK-NEXT: ret 1595 %shuffle = shufflevector <4 x i32> %c, <4 x i32> undef, <2 x i32> <i32 3, i32 3> 1596 %mul = mul <2 x i32> %shuffle, %b 1597 %add = add <2 x i32> %mul, %a 1598 ret <2 x i32> %add 1599 } 1600 1601 define <8 x i16> @not_really_vmlaq_laneq_s16_test(<8 x i16> %a, <8 x i16> %b, <8 x i16> %c) nounwind readnone ssp { 1602 entry: 1603 ; CHECK: not_really_vmlaq_laneq_s16_test 1604 ; CHECK-NOT: ext 1605 ; CHECK: mla.8h v0, v1, v2[5] 1606 ; CHECK-NEXT: ret 1607 %shuffle1 = shufflevector <8 x i16> %c, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7> 1608 %shuffle2 = shufflevector <4 x i16> %shuffle1, <4 x i16> undef, <8 x i32> <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> 1609 %mul = mul <8 x i16> %shuffle2, %b 1610 %add = add <8 x i16> %mul, %a 1611 ret <8 x i16> %add 1612 } 1613 1614 define <4 x i32> @not_really_vmlaq_laneq_s32_test(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) nounwind readnone ssp { 1615 entry: 1616 ; CHECK: not_really_vmlaq_laneq_s32_test 1617 ; CHECK-NOT: ext 1618 ; CHECK: mla.4s v0, v1, v2[3] 1619 ; CHECK-NEXT: ret 1620 %shuffle1 = shufflevector <4 x i32> %c, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 1621 %shuffle2 = shufflevector <2 x i32> %shuffle1, <2 x i32> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1> 1622 %mul = mul <4 x i32> %shuffle2, %b 1623 %add = add <4 x i32> %mul, %a 1624 ret <4 x i32> %add 1625 } 1626 1627 define <4 x i32> @vmull_laneq_s16_test(<4 x i16> %a, <8 x i16> %b) nounwind readnone ssp { 1628 entry: 1629 ; CHECK: vmull_laneq_s16_test 1630 ; CHECK-NOT: ext 1631 ; CHECK: smull.4s v0, v0, v1[6] 1632 ; CHECK-NEXT: ret 1633 %shuffle = shufflevector <8 x i16> %b, <8 x i16> undef, <4 x i32> <i32 6, i32 6, i32 6, i32 6> 1634 %vmull2.i = tail call <4 x i32> @llvm.aarch64.neon.smull.v4i32(<4 x i16> %a, <4 x i16> %shuffle) #2 1635 ret <4 x i32> %vmull2.i 1636 } 1637 1638 define <2 x i64> @vmull_laneq_s32_test(<2 x i32> %a, <4 x i32> %b) nounwind readnone ssp { 1639 entry: 1640 ; CHECK: vmull_laneq_s32_test 1641 ; CHECK-NOT: ext 1642 ; CHECK: smull.2d v0, v0, v1[2] 1643 ; CHECK-NEXT: ret 1644 %shuffle = shufflevector <4 x i32> %b, <4 x i32> undef, <2 x i32> <i32 2, i32 2> 1645 %vmull2.i = tail call <2 x i64> @llvm.aarch64.neon.smull.v2i64(<2 x i32> %a, <2 x i32> %shuffle) #2 1646 ret <2 x i64> %vmull2.i 1647 } 1648 define <4 x i32> @vmull_laneq_u16_test(<4 x i16> %a, <8 x i16> %b) nounwind readnone ssp { 1649 entry: 1650 ; CHECK: vmull_laneq_u16_test 1651 ; CHECK-NOT: ext 1652 ; CHECK: umull.4s v0, v0, v1[6] 1653 ; CHECK-NEXT: ret 1654 %shuffle = shufflevector <8 x i16> %b, <8 x i16> undef, <4 x i32> <i32 6, i32 6, i32 6, i32 6> 1655 %vmull2.i = tail call <4 x i32> @llvm.aarch64.neon.umull.v4i32(<4 x i16> %a, <4 x i16> %shuffle) #2 1656 ret <4 x i32> %vmull2.i 1657 } 1658 1659 define <2 x i64> @vmull_laneq_u32_test(<2 x i32> %a, <4 x i32> %b) nounwind readnone ssp { 1660 entry: 1661 ; CHECK: vmull_laneq_u32_test 1662 ; CHECK-NOT: ext 1663 ; CHECK: umull.2d v0, v0, v1[2] 1664 ; CHECK-NEXT: ret 1665 %shuffle = shufflevector <4 x i32> %b, <4 x i32> undef, <2 x i32> <i32 2, i32 2> 1666 %vmull2.i = tail call <2 x i64> @llvm.aarch64.neon.umull.v2i64(<2 x i32> %a, <2 x i32> %shuffle) #2 1667 ret <2 x i64> %vmull2.i 1668 } 1669 1670 define <4 x i32> @vmull_high_n_s16_test(<4 x i32> %a, <8 x i16> %b, <4 x i16> %c, i32 %d) nounwind readnone optsize ssp { 1671 entry: 1672 ; CHECK: vmull_high_n_s16_test 1673 ; CHECK-NOT: ext 1674 ; CHECK: smull2.4s 1675 ; CHECK-NEXT: ret 1676 %conv = trunc i32 %d to i16 1677 %0 = bitcast <8 x i16> %b to <2 x i64> 1678 %shuffle.i.i = shufflevector <2 x i64> %0, <2 x i64> undef, <1 x i32> <i32 1> 1679 %1 = bitcast <1 x i64> %shuffle.i.i to <4 x i16> 1680 %vecinit.i = insertelement <4 x i16> undef, i16 %conv, i32 0 1681 %vecinit1.i = insertelement <4 x i16> %vecinit.i, i16 %conv, i32 1 1682 %vecinit2.i = insertelement <4 x i16> %vecinit1.i, i16 %conv, i32 2 1683 %vecinit3.i = insertelement <4 x i16> %vecinit2.i, i16 %conv, i32 3 1684 %vmull2.i.i = tail call <4 x i32> @llvm.aarch64.neon.smull.v4i32(<4 x i16> %1, <4 x i16> %vecinit3.i) nounwind 1685 ret <4 x i32> %vmull2.i.i 1686 } 1687 1688 define <2 x i64> @vmull_high_n_s32_test(<2 x i64> %a, <4 x i32> %b, <2 x i32> %c, i32 %d) nounwind readnone optsize ssp { 1689 entry: 1690 ; CHECK: vmull_high_n_s32_test 1691 ; CHECK-NOT: ext 1692 ; CHECK: smull2.2d 1693 ; CHECK-NEXT: ret 1694 %0 = bitcast <4 x i32> %b to <2 x i64> 1695 %shuffle.i.i = shufflevector <2 x i64> %0, <2 x i64> undef, <1 x i32> <i32 1> 1696 %1 = bitcast <1 x i64> %shuffle.i.i to <2 x i32> 1697 %vecinit.i = insertelement <2 x i32> undef, i32 %d, i32 0 1698 %vecinit1.i = insertelement <2 x i32> %vecinit.i, i32 %d, i32 1 1699 %vmull2.i.i = tail call <2 x i64> @llvm.aarch64.neon.smull.v2i64(<2 x i32> %1, <2 x i32> %vecinit1.i) nounwind 1700 ret <2 x i64> %vmull2.i.i 1701 } 1702 1703 define <4 x i32> @vmull_high_n_u16_test(<4 x i32> %a, <8 x i16> %b, <4 x i16> %c, i32 %d) nounwind readnone optsize ssp { 1704 entry: 1705 ; CHECK: vmull_high_n_u16_test 1706 ; CHECK-NOT: ext 1707 ; CHECK: umull2.4s 1708 ; CHECK-NEXT: ret 1709 %conv = trunc i32 %d to i16 1710 %0 = bitcast <8 x i16> %b to <2 x i64> 1711 %shuffle.i.i = shufflevector <2 x i64> %0, <2 x i64> undef, <1 x i32> <i32 1> 1712 %1 = bitcast <1 x i64> %shuffle.i.i to <4 x i16> 1713 %vecinit.i = insertelement <4 x i16> undef, i16 %conv, i32 0 1714 %vecinit1.i = insertelement <4 x i16> %vecinit.i, i16 %conv, i32 1 1715 %vecinit2.i = insertelement <4 x i16> %vecinit1.i, i16 %conv, i32 2 1716 %vecinit3.i = insertelement <4 x i16> %vecinit2.i, i16 %conv, i32 3 1717 %vmull2.i.i = tail call <4 x i32> @llvm.aarch64.neon.umull.v4i32(<4 x i16> %1, <4 x i16> %vecinit3.i) nounwind 1718 ret <4 x i32> %vmull2.i.i 1719 } 1720 1721 define <2 x i64> @vmull_high_n_u32_test(<2 x i64> %a, <4 x i32> %b, <2 x i32> %c, i32 %d) nounwind readnone optsize ssp { 1722 entry: 1723 ; CHECK: vmull_high_n_u32_test 1724 ; CHECK-NOT: ext 1725 ; CHECK: umull2.2d 1726 ; CHECK-NEXT: ret 1727 %0 = bitcast <4 x i32> %b to <2 x i64> 1728 %shuffle.i.i = shufflevector <2 x i64> %0, <2 x i64> undef, <1 x i32> <i32 1> 1729 %1 = bitcast <1 x i64> %shuffle.i.i to <2 x i32> 1730 %vecinit.i = insertelement <2 x i32> undef, i32 %d, i32 0 1731 %vecinit1.i = insertelement <2 x i32> %vecinit.i, i32 %d, i32 1 1732 %vmull2.i.i = tail call <2 x i64> @llvm.aarch64.neon.umull.v2i64(<2 x i32> %1, <2 x i32> %vecinit1.i) nounwind 1733 ret <2 x i64> %vmull2.i.i 1734 } 1735 1736 define <4 x i32> @vmul_built_dup_test(<4 x i32> %a, <4 x i32> %b) { 1737 ; CHECK-LABEL: vmul_built_dup_test: 1738 ; CHECK-NOT: ins 1739 ; CHECK-NOT: dup 1740 ; CHECK: mul.4s {{v[0-9]+}}, {{v[0-9]+}}, {{v[0-9]+}}[1] 1741 %vget_lane = extractelement <4 x i32> %b, i32 1 1742 %vecinit.i = insertelement <4 x i32> undef, i32 %vget_lane, i32 0 1743 %vecinit1.i = insertelement <4 x i32> %vecinit.i, i32 %vget_lane, i32 1 1744 %vecinit2.i = insertelement <4 x i32> %vecinit1.i, i32 %vget_lane, i32 2 1745 %vecinit3.i = insertelement <4 x i32> %vecinit2.i, i32 %vget_lane, i32 3 1746 %prod = mul <4 x i32> %a, %vecinit3.i 1747 ret <4 x i32> %prod 1748 } 1749 1750 define <4 x i16> @vmul_built_dup_fromsmall_test(<4 x i16> %a, <4 x i16> %b) { 1751 ; CHECK-LABEL: vmul_built_dup_fromsmall_test: 1752 ; CHECK-NOT: ins 1753 ; CHECK-NOT: dup 1754 ; CHECK: mul.4h {{v[0-9]+}}, {{v[0-9]+}}, {{v[0-9]+}}[3] 1755 %vget_lane = extractelement <4 x i16> %b, i32 3 1756 %vecinit.i = insertelement <4 x i16> undef, i16 %vget_lane, i32 0 1757 %vecinit1.i = insertelement <4 x i16> %vecinit.i, i16 %vget_lane, i32 1 1758 %vecinit2.i = insertelement <4 x i16> %vecinit1.i, i16 %vget_lane, i32 2 1759 %vecinit3.i = insertelement <4 x i16> %vecinit2.i, i16 %vget_lane, i32 3 1760 %prod = mul <4 x i16> %a, %vecinit3.i 1761 ret <4 x i16> %prod 1762 } 1763 1764 define <8 x i16> @vmulq_built_dup_fromsmall_test(<8 x i16> %a, <4 x i16> %b) { 1765 ; CHECK-LABEL: vmulq_built_dup_fromsmall_test: 1766 ; CHECK-NOT: ins 1767 ; CHECK-NOT: dup 1768 ; CHECK: mul.8h {{v[0-9]+}}, {{v[0-9]+}}, {{v[0-9]+}}[0] 1769 %vget_lane = extractelement <4 x i16> %b, i32 0 1770 %vecinit.i = insertelement <8 x i16> undef, i16 %vget_lane, i32 0 1771 %vecinit1.i = insertelement <8 x i16> %vecinit.i, i16 %vget_lane, i32 1 1772 %vecinit2.i = insertelement <8 x i16> %vecinit1.i, i16 %vget_lane, i32 2 1773 %vecinit3.i = insertelement <8 x i16> %vecinit2.i, i16 %vget_lane, i32 3 1774 %vecinit4.i = insertelement <8 x i16> %vecinit3.i, i16 %vget_lane, i32 4 1775 %vecinit5.i = insertelement <8 x i16> %vecinit4.i, i16 %vget_lane, i32 5 1776 %vecinit6.i = insertelement <8 x i16> %vecinit5.i, i16 %vget_lane, i32 6 1777 %vecinit7.i = insertelement <8 x i16> %vecinit6.i, i16 %vget_lane, i32 7 1778 %prod = mul <8 x i16> %a, %vecinit7.i 1779 ret <8 x i16> %prod 1780 } 1781 1782 define <2 x i64> @mull_from_two_extracts(<4 x i32> %lhs, <4 x i32> %rhs) { 1783 ; CHECK-LABEL: mull_from_two_extracts: 1784 ; CHECK-NOT: ext 1785 ; CHECK: sqdmull2.2d 1786 1787 %lhs.high = shufflevector <4 x i32> %lhs, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 1788 %rhs.high = shufflevector <4 x i32> %rhs, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 1789 1790 %res = tail call <2 x i64> @llvm.aarch64.neon.sqdmull.v2i64(<2 x i32> %lhs.high, <2 x i32> %rhs.high) nounwind 1791 ret <2 x i64> %res 1792 } 1793 1794 define <2 x i64> @mlal_from_two_extracts(<2 x i64> %accum, <4 x i32> %lhs, <4 x i32> %rhs) { 1795 ; CHECK-LABEL: mlal_from_two_extracts: 1796 ; CHECK-NOT: ext 1797 ; CHECK: sqdmlal2.2d 1798 1799 %lhs.high = shufflevector <4 x i32> %lhs, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 1800 %rhs.high = shufflevector <4 x i32> %rhs, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 1801 1802 %res = tail call <2 x i64> @llvm.aarch64.neon.sqdmull.v2i64(<2 x i32> %lhs.high, <2 x i32> %rhs.high) nounwind 1803 %sum = call <2 x i64> @llvm.aarch64.neon.sqadd.v2i64(<2 x i64> %accum, <2 x i64> %res) 1804 ret <2 x i64> %sum 1805 } 1806 1807 define <2 x i64> @mull_from_extract_dup(<4 x i32> %lhs, i32 %rhs) { 1808 ; CHECK-LABEL: mull_from_extract_dup: 1809 ; CHECK-NOT: ext 1810 ; CHECK: sqdmull2.2d 1811 %rhsvec.tmp = insertelement <2 x i32> undef, i32 %rhs, i32 0 1812 %rhsvec = insertelement <2 x i32> %rhsvec.tmp, i32 %rhs, i32 1 1813 1814 %lhs.high = shufflevector <4 x i32> %lhs, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 1815 1816 %res = tail call <2 x i64> @llvm.aarch64.neon.sqdmull.v2i64(<2 x i32> %lhs.high, <2 x i32> %rhsvec) nounwind 1817 ret <2 x i64> %res 1818 } 1819 1820 define <8 x i16> @pmull_from_extract_dup(<16 x i8> %lhs, i8 %rhs) { 1821 ; CHECK-LABEL: pmull_from_extract_dup: 1822 ; CHECK-NOT: ext 1823 ; CHECK: pmull2.8h 1824 %rhsvec.0 = insertelement <8 x i8> undef, i8 %rhs, i32 0 1825 %rhsvec = shufflevector <8 x i8> %rhsvec.0, <8 x i8> undef, <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0> 1826 1827 %lhs.high = shufflevector <16 x i8> %lhs, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> 1828 1829 %res = tail call <8 x i16> @llvm.aarch64.neon.pmull.v8i16(<8 x i8> %lhs.high, <8 x i8> %rhsvec) nounwind 1830 ret <8 x i16> %res 1831 } 1832 1833 define <8 x i16> @pmull_from_extract_duplane(<16 x i8> %lhs, <8 x i8> %rhs) { 1834 ; CHECK-LABEL: pmull_from_extract_duplane: 1835 ; CHECK-NOT: ext 1836 ; CHECK: pmull2.8h 1837 1838 %lhs.high = shufflevector <16 x i8> %lhs, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> 1839 %rhs.high = shufflevector <8 x i8> %rhs, <8 x i8> undef, <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0> 1840 1841 %res = tail call <8 x i16> @llvm.aarch64.neon.pmull.v8i16(<8 x i8> %lhs.high, <8 x i8> %rhs.high) nounwind 1842 ret <8 x i16> %res 1843 } 1844 1845 define <2 x i64> @sqdmull_from_extract_duplane(<4 x i32> %lhs, <4 x i32> %rhs) { 1846 ; CHECK-LABEL: sqdmull_from_extract_duplane: 1847 ; CHECK-NOT: ext 1848 ; CHECK: sqdmull2.2d 1849 1850 %lhs.high = shufflevector <4 x i32> %lhs, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 1851 %rhs.high = shufflevector <4 x i32> %rhs, <4 x i32> undef, <2 x i32> <i32 0, i32 0> 1852 1853 %res = tail call <2 x i64> @llvm.aarch64.neon.sqdmull.v2i64(<2 x i32> %lhs.high, <2 x i32> %rhs.high) nounwind 1854 ret <2 x i64> %res 1855 } 1856 1857 define <2 x i64> @sqdmlal_from_extract_duplane(<2 x i64> %accum, <4 x i32> %lhs, <4 x i32> %rhs) { 1858 ; CHECK-LABEL: sqdmlal_from_extract_duplane: 1859 ; CHECK-NOT: ext 1860 ; CHECK: sqdmlal2.2d 1861 1862 %lhs.high = shufflevector <4 x i32> %lhs, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 1863 %rhs.high = shufflevector <4 x i32> %rhs, <4 x i32> undef, <2 x i32> <i32 0, i32 0> 1864 1865 %res = tail call <2 x i64> @llvm.aarch64.neon.sqdmull.v2i64(<2 x i32> %lhs.high, <2 x i32> %rhs.high) nounwind 1866 %sum = call <2 x i64> @llvm.aarch64.neon.sqadd.v2i64(<2 x i64> %accum, <2 x i64> %res) 1867 ret <2 x i64> %sum 1868 } 1869 1870 define <2 x i64> @umlal_from_extract_duplane(<2 x i64> %accum, <4 x i32> %lhs, <4 x i32> %rhs) { 1871 ; CHECK-LABEL: umlal_from_extract_duplane: 1872 ; CHECK-NOT: ext 1873 ; CHECK: umlal2.2d 1874 1875 %lhs.high = shufflevector <4 x i32> %lhs, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 1876 %rhs.high = shufflevector <4 x i32> %rhs, <4 x i32> undef, <2 x i32> <i32 0, i32 0> 1877 1878 %res = tail call <2 x i64> @llvm.aarch64.neon.umull.v2i64(<2 x i32> %lhs.high, <2 x i32> %rhs.high) nounwind 1879 %sum = add <2 x i64> %accum, %res 1880 ret <2 x i64> %sum 1881 } 1882 1883 define float @scalar_fmla_from_extract_v4f32(float %accum, float %lhs, <4 x float> %rvec) { 1884 ; CHECK-LABEL: scalar_fmla_from_extract_v4f32: 1885 ; CHECK: fmla.s s0, s1, v2[3] 1886 %rhs = extractelement <4 x float> %rvec, i32 3 1887 %res = call float @llvm.fma.f32(float %lhs, float %rhs, float %accum) 1888 ret float %res 1889 } 1890 1891 define float @scalar_fmla_from_extract_v2f32(float %accum, float %lhs, <2 x float> %rvec) { 1892 ; CHECK-LABEL: scalar_fmla_from_extract_v2f32: 1893 ; CHECK: fmla.s s0, s1, v2[1] 1894 %rhs = extractelement <2 x float> %rvec, i32 1 1895 %res = call float @llvm.fma.f32(float %lhs, float %rhs, float %accum) 1896 ret float %res 1897 } 1898 1899 define float @scalar_fmls_from_extract_v4f32(float %accum, float %lhs, <4 x float> %rvec) { 1900 ; CHECK-LABEL: scalar_fmls_from_extract_v4f32: 1901 ; CHECK: fmls.s s0, s1, v2[3] 1902 %rhs.scal = extractelement <4 x float> %rvec, i32 3 1903 %rhs = fsub float -0.0, %rhs.scal 1904 %res = call float @llvm.fma.f32(float %lhs, float %rhs, float %accum) 1905 ret float %res 1906 } 1907 1908 define float @scalar_fmls_from_extract_v2f32(float %accum, float %lhs, <2 x float> %rvec) { 1909 ; CHECK-LABEL: scalar_fmls_from_extract_v2f32: 1910 ; CHECK: fmls.s s0, s1, v2[1] 1911 %rhs.scal = extractelement <2 x float> %rvec, i32 1 1912 %rhs = fsub float -0.0, %rhs.scal 1913 %res = call float @llvm.fma.f32(float %lhs, float %rhs, float %accum) 1914 ret float %res 1915 } 1916 1917 declare float @llvm.fma.f32(float, float, float) 1918 1919 define double @scalar_fmla_from_extract_v2f64(double %accum, double %lhs, <2 x double> %rvec) { 1920 ; CHECK-LABEL: scalar_fmla_from_extract_v2f64: 1921 ; CHECK: fmla.d d0, d1, v2[1] 1922 %rhs = extractelement <2 x double> %rvec, i32 1 1923 %res = call double @llvm.fma.f64(double %lhs, double %rhs, double %accum) 1924 ret double %res 1925 } 1926 1927 define double @scalar_fmls_from_extract_v2f64(double %accum, double %lhs, <2 x double> %rvec) { 1928 ; CHECK-LABEL: scalar_fmls_from_extract_v2f64: 1929 ; CHECK: fmls.d d0, d1, v2[1] 1930 %rhs.scal = extractelement <2 x double> %rvec, i32 1 1931 %rhs = fsub double -0.0, %rhs.scal 1932 %res = call double @llvm.fma.f64(double %lhs, double %rhs, double %accum) 1933 ret double %res 1934 } 1935 1936 declare double @llvm.fma.f64(double, double, double) 1937 1938 define <2 x float> @fmls_with_fneg_before_extract_v2f32(<2 x float> %accum, <2 x float> %lhs, <4 x float> %rhs) { 1939 ; CHECK-LABEL: fmls_with_fneg_before_extract_v2f32: 1940 ; CHECK: fmls.2s v0, v1, v2[3] 1941 %rhs_neg = fsub <4 x float> <float -0.0, float -0.0, float -0.0, float -0.0>, %rhs 1942 %splat = shufflevector <4 x float> %rhs_neg, <4 x float> undef, <2 x i32> <i32 3, i32 3> 1943 %res = call <2 x float> @llvm.fma.v2f32(<2 x float> %lhs, <2 x float> %splat, <2 x float> %accum) 1944 ret <2 x float> %res 1945 } 1946 1947 define <2 x float> @fmls_with_fneg_before_extract_v2f32_1(<2 x float> %accum, <2 x float> %lhs, <2 x float> %rhs) { 1948 ; CHECK-LABEL: fmls_with_fneg_before_extract_v2f32_1: 1949 ; CHECK: fmls.2s v0, v1, v2[1] 1950 %rhs_neg = fsub <2 x float> <float -0.0, float -0.0>, %rhs 1951 %splat = shufflevector <2 x float> %rhs_neg, <2 x float> undef, <2 x i32> <i32 1, i32 1> 1952 %res = call <2 x float> @llvm.fma.v2f32(<2 x float> %lhs, <2 x float> %splat, <2 x float> %accum) 1953 ret <2 x float> %res 1954 } 1955 1956 define <4 x float> @fmls_with_fneg_before_extract_v4f32(<4 x float> %accum, <4 x float> %lhs, <4 x float> %rhs) { 1957 ; CHECK-LABEL: fmls_with_fneg_before_extract_v4f32: 1958 ; CHECK: fmls.4s v0, v1, v2[3] 1959 %rhs_neg = fsub <4 x float> <float -0.0, float -0.0, float -0.0, float -0.0>, %rhs 1960 %splat = shufflevector <4 x float> %rhs_neg, <4 x float> undef, <4 x i32> <i32 3, i32 3, i32 3, i32 3> 1961 %res = call <4 x float> @llvm.fma.v4f32(<4 x float> %lhs, <4 x float> %splat, <4 x float> %accum) 1962 ret <4 x float> %res 1963 } 1964 1965 define <4 x float> @fmls_with_fneg_before_extract_v4f32_1(<4 x float> %accum, <4 x float> %lhs, <2 x float> %rhs) { 1966 ; CHECK-LABEL: fmls_with_fneg_before_extract_v4f32_1: 1967 ; CHECK: fmls.4s v0, v1, v2[1] 1968 %rhs_neg = fsub <2 x float> <float -0.0, float -0.0>, %rhs 1969 %splat = shufflevector <2 x float> %rhs_neg, <2 x float> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1> 1970 %res = call <4 x float> @llvm.fma.v4f32(<4 x float> %lhs, <4 x float> %splat, <4 x float> %accum) 1971 ret <4 x float> %res 1972 } 1973 1974 define <2 x double> @fmls_with_fneg_before_extract_v2f64(<2 x double> %accum, <2 x double> %lhs, <2 x double> %rhs) { 1975 ; CHECK-LABEL: fmls_with_fneg_before_extract_v2f64: 1976 ; CHECK: fmls.2d v0, v1, v2[1] 1977 %rhs_neg = fsub <2 x double> <double -0.0, double -0.0>, %rhs 1978 %splat = shufflevector <2 x double> %rhs_neg, <2 x double> undef, <2 x i32> <i32 1, i32 1> 1979 %res = call <2 x double> @llvm.fma.v2f64(<2 x double> %lhs, <2 x double> %splat, <2 x double> %accum) 1980 ret <2 x double> %res 1981 } 1982 1983 define <1 x double> @test_fmul_v1f64(<1 x double> %L, <1 x double> %R) nounwind { 1984 ; CHECK-LABEL: test_fmul_v1f64: 1985 ; CHECK: fmul 1986 %prod = fmul <1 x double> %L, %R 1987 ret <1 x double> %prod 1988 } 1989 1990 define <1 x double> @test_fdiv_v1f64(<1 x double> %L, <1 x double> %R) nounwind { 1991 ; CHECK-LABEL: test_fdiv_v1f64: 1992 ; CHECK-LABEL: fdiv 1993 %prod = fdiv <1 x double> %L, %R 1994 ret <1 x double> %prod 1995 } 1996 1997 define i64 @sqdmlal_d(i32 %A, i32 %B, i64 %C) nounwind { 1998 ;CHECK-LABEL: sqdmlal_d: 1999 ;CHECK: sqdmlal 2000 %tmp4 = call i64 @llvm.aarch64.neon.sqdmulls.scalar(i32 %A, i32 %B) 2001 %tmp5 = call i64 @llvm.aarch64.neon.sqadd.i64(i64 %C, i64 %tmp4) 2002 ret i64 %tmp5 2003 } 2004 2005 define i64 @sqdmlsl_d(i32 %A, i32 %B, i64 %C) nounwind { 2006 ;CHECK-LABEL: sqdmlsl_d: 2007 ;CHECK: sqdmlsl 2008 %tmp4 = call i64 @llvm.aarch64.neon.sqdmulls.scalar(i32 %A, i32 %B) 2009 %tmp5 = call i64 @llvm.aarch64.neon.sqsub.i64(i64 %C, i64 %tmp4) 2010 ret i64 %tmp5 2011 } 2012 2013 define <16 x i8> @test_pmull_64(i64 %l, i64 %r) nounwind { 2014 ; CHECK-LABEL: test_pmull_64: 2015 ; CHECK: pmull.1q 2016 %val = call <16 x i8> @llvm.aarch64.neon.pmull64(i64 %l, i64 %r) 2017 ret <16 x i8> %val 2018 } 2019 2020 define <16 x i8> @test_pmull_high_64(<2 x i64> %l, <2 x i64> %r) nounwind { 2021 ; CHECK-LABEL: test_pmull_high_64: 2022 ; CHECK: pmull2.1q 2023 %l_hi = extractelement <2 x i64> %l, i32 1 2024 %r_hi = extractelement <2 x i64> %r, i32 1 2025 %val = call <16 x i8> @llvm.aarch64.neon.pmull64(i64 %l_hi, i64 %r_hi) 2026 ret <16 x i8> %val 2027 } 2028 2029 declare <16 x i8> @llvm.aarch64.neon.pmull64(i64, i64) 2030 2031 define <1 x i64> @test_mul_v1i64(<1 x i64> %lhs, <1 x i64> %rhs) nounwind { 2032 ; CHECK-LABEL: test_mul_v1i64: 2033 ; CHECK: mul 2034 %prod = mul <1 x i64> %lhs, %rhs 2035 ret <1 x i64> %prod 2036 } 2037