1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=arm64-eabi -aarch64-neon-syntax=apple | FileCheck -check-prefixes=CHECK,CHECK-SD %s 3; RUN: llc < %s -mtriple=arm64-eabi -aarch64-neon-syntax=apple -global-isel -global-isel-abort=2 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-GI 4 5; CHECK-GI: warning: Instruction selection used fallback path for fabds 6; CHECK-GI-NEXT: warning: Instruction selection used fallback path for fabdd 7; CHECK-GI-NEXT: warning: Instruction selection used fallback path for uabd_i64 8 9define <8 x i16> @sabdl8h(ptr %A, ptr %B) nounwind { 10; CHECK-LABEL: sabdl8h: 11; CHECK: // %bb.0: 12; CHECK-NEXT: ldr d0, [x0] 13; CHECK-NEXT: ldr d1, [x1] 14; CHECK-NEXT: sabdl.8h v0, v0, v1 15; CHECK-NEXT: ret 16 %tmp1 = load <8 x i8>, ptr %A 17 %tmp2 = load <8 x i8>, ptr %B 18 %tmp3 = call <8 x i8> @llvm.aarch64.neon.sabd.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2) 19 %tmp4 = zext <8 x i8> %tmp3 to <8 x i16> 20 ret <8 x i16> %tmp4 21} 22 23define <4 x i32> @sabdl4s(ptr %A, ptr %B) nounwind { 24; CHECK-LABEL: sabdl4s: 25; CHECK: // %bb.0: 26; CHECK-NEXT: ldr d0, [x0] 27; CHECK-NEXT: ldr d1, [x1] 28; CHECK-NEXT: sabdl.4s v0, v0, v1 29; CHECK-NEXT: ret 30 %tmp1 = load <4 x i16>, ptr %A 31 %tmp2 = load <4 x i16>, ptr %B 32 %tmp3 = call <4 x i16> @llvm.aarch64.neon.sabd.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2) 33 %tmp4 = zext <4 x i16> %tmp3 to <4 x i32> 34 ret <4 x i32> %tmp4 35} 36 37define <2 x i64> @sabdl2d(ptr %A, ptr %B) nounwind { 38; CHECK-LABEL: sabdl2d: 39; CHECK: // %bb.0: 40; CHECK-NEXT: ldr d0, [x0] 41; CHECK-NEXT: ldr d1, [x1] 42; CHECK-NEXT: sabdl.2d v0, v0, v1 43; CHECK-NEXT: ret 44 %tmp1 = load <2 x i32>, ptr %A 45 %tmp2 = load <2 x i32>, ptr %B 46 %tmp3 = call <2 x i32> @llvm.aarch64.neon.sabd.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2) 47 %tmp4 = zext <2 x i32> %tmp3 to <2 x i64> 48 ret <2 x i64> %tmp4 49} 50 51define <8 x i16> @sabdl2_8h(ptr %A, ptr %B) nounwind { 52; CHECK-SD-LABEL: sabdl2_8h: 53; CHECK-SD: // %bb.0: 54; CHECK-SD-NEXT: ldr d0, [x0, #8] 55; CHECK-SD-NEXT: ldr d1, [x1, #8] 56; CHECK-SD-NEXT: sabdl.8h v0, v0, v1 57; CHECK-SD-NEXT: ret 58; 59; CHECK-GI-LABEL: sabdl2_8h: 60; CHECK-GI: // %bb.0: 61; CHECK-GI-NEXT: ldr q0, [x0] 62; CHECK-GI-NEXT: ldr q1, [x1] 63; CHECK-GI-NEXT: sabdl2.8h v0, v0, v1 64; CHECK-GI-NEXT: ret 65 %load1 = load <16 x i8>, ptr %A 66 %load2 = load <16 x i8>, ptr %B 67 %tmp1 = shufflevector <16 x i8> %load1, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> 68 %tmp2 = shufflevector <16 x i8> %load2, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> 69 %tmp3 = call <8 x i8> @llvm.aarch64.neon.sabd.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2) 70 %tmp4 = zext <8 x i8> %tmp3 to <8 x i16> 71 ret <8 x i16> %tmp4 72} 73 74define <4 x i32> @sabdl2_4s(ptr %A, ptr %B) nounwind { 75; CHECK-SD-LABEL: sabdl2_4s: 76; CHECK-SD: // %bb.0: 77; CHECK-SD-NEXT: ldr d0, [x0, #8] 78; CHECK-SD-NEXT: ldr d1, [x1, #8] 79; CHECK-SD-NEXT: sabdl.4s v0, v0, v1 80; CHECK-SD-NEXT: ret 81; 82; CHECK-GI-LABEL: sabdl2_4s: 83; CHECK-GI: // %bb.0: 84; CHECK-GI-NEXT: ldr q0, [x0] 85; CHECK-GI-NEXT: ldr q1, [x1] 86; CHECK-GI-NEXT: sabdl2.4s v0, v0, v1 87; CHECK-GI-NEXT: ret 88 %load1 = load <8 x i16>, ptr %A 89 %load2 = load <8 x i16>, ptr %B 90 %tmp1 = shufflevector <8 x i16> %load1, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7> 91 %tmp2 = shufflevector <8 x i16> %load2, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7> 92 %tmp3 = call <4 x i16> @llvm.aarch64.neon.sabd.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2) 93 %tmp4 = zext <4 x i16> %tmp3 to <4 x i32> 94 ret <4 x i32> %tmp4 95} 96 97define <2 x i64> @sabdl2_2d(ptr %A, ptr %B) nounwind { 98; CHECK-SD-LABEL: sabdl2_2d: 99; CHECK-SD: // %bb.0: 100; CHECK-SD-NEXT: ldr d0, [x0, #8] 101; CHECK-SD-NEXT: ldr d1, [x1, #8] 102; CHECK-SD-NEXT: sabdl.2d v0, v0, v1 103; CHECK-SD-NEXT: ret 104; 105; CHECK-GI-LABEL: sabdl2_2d: 106; CHECK-GI: // %bb.0: 107; CHECK-GI-NEXT: ldr q0, [x0] 108; CHECK-GI-NEXT: ldr q1, [x1] 109; CHECK-GI-NEXT: sabdl2.2d v0, v0, v1 110; CHECK-GI-NEXT: ret 111 %load1 = load <4 x i32>, ptr %A 112 %load2 = load <4 x i32>, ptr %B 113 %tmp1 = shufflevector <4 x i32> %load1, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 114 %tmp2 = shufflevector <4 x i32> %load2, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 115 %tmp3 = call <2 x i32> @llvm.aarch64.neon.sabd.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2) 116 %tmp4 = zext <2 x i32> %tmp3 to <2 x i64> 117 ret <2 x i64> %tmp4 118} 119 120define <8 x i16> @uabdl8h(ptr %A, ptr %B) nounwind { 121; CHECK-LABEL: uabdl8h: 122; CHECK: // %bb.0: 123; CHECK-NEXT: ldr d0, [x0] 124; CHECK-NEXT: ldr d1, [x1] 125; CHECK-NEXT: uabdl.8h v0, v0, v1 126; CHECK-NEXT: ret 127 %tmp1 = load <8 x i8>, ptr %A 128 %tmp2 = load <8 x i8>, ptr %B 129 %tmp3 = call <8 x i8> @llvm.aarch64.neon.uabd.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2) 130 %tmp4 = zext <8 x i8> %tmp3 to <8 x i16> 131 ret <8 x i16> %tmp4 132} 133 134define <4 x i32> @uabdl4s(ptr %A, ptr %B) nounwind { 135; CHECK-LABEL: uabdl4s: 136; CHECK: // %bb.0: 137; CHECK-NEXT: ldr d0, [x0] 138; CHECK-NEXT: ldr d1, [x1] 139; CHECK-NEXT: uabdl.4s v0, v0, v1 140; CHECK-NEXT: ret 141 %tmp1 = load <4 x i16>, ptr %A 142 %tmp2 = load <4 x i16>, ptr %B 143 %tmp3 = call <4 x i16> @llvm.aarch64.neon.uabd.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2) 144 %tmp4 = zext <4 x i16> %tmp3 to <4 x i32> 145 ret <4 x i32> %tmp4 146} 147 148define <2 x i64> @uabdl2d(ptr %A, ptr %B) nounwind { 149; CHECK-LABEL: uabdl2d: 150; CHECK: // %bb.0: 151; CHECK-NEXT: ldr d0, [x0] 152; CHECK-NEXT: ldr d1, [x1] 153; CHECK-NEXT: uabdl.2d v0, v0, v1 154; CHECK-NEXT: ret 155 %tmp1 = load <2 x i32>, ptr %A 156 %tmp2 = load <2 x i32>, ptr %B 157 %tmp3 = call <2 x i32> @llvm.aarch64.neon.uabd.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2) 158 %tmp4 = zext <2 x i32> %tmp3 to <2 x i64> 159 ret <2 x i64> %tmp4 160} 161 162define <8 x i16> @uabdl2_8h(ptr %A, ptr %B) nounwind { 163; CHECK-SD-LABEL: uabdl2_8h: 164; CHECK-SD: // %bb.0: 165; CHECK-SD-NEXT: ldr d0, [x0, #8] 166; CHECK-SD-NEXT: ldr d1, [x1, #8] 167; CHECK-SD-NEXT: uabdl.8h v0, v0, v1 168; CHECK-SD-NEXT: ret 169; 170; CHECK-GI-LABEL: uabdl2_8h: 171; CHECK-GI: // %bb.0: 172; CHECK-GI-NEXT: ldr q0, [x0] 173; CHECK-GI-NEXT: ldr q1, [x1] 174; CHECK-GI-NEXT: uabdl2.8h v0, v0, v1 175; CHECK-GI-NEXT: ret 176 %load1 = load <16 x i8>, ptr %A 177 %load2 = load <16 x i8>, ptr %B 178 %tmp1 = shufflevector <16 x i8> %load1, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> 179 %tmp2 = shufflevector <16 x i8> %load2, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> 180 181 %tmp3 = call <8 x i8> @llvm.aarch64.neon.uabd.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2) 182 %tmp4 = zext <8 x i8> %tmp3 to <8 x i16> 183 ret <8 x i16> %tmp4 184} 185 186define <4 x i32> @uabdl2_4s(ptr %A, ptr %B) nounwind { 187; CHECK-SD-LABEL: uabdl2_4s: 188; CHECK-SD: // %bb.0: 189; CHECK-SD-NEXT: ldr d0, [x0, #8] 190; CHECK-SD-NEXT: ldr d1, [x1, #8] 191; CHECK-SD-NEXT: uabdl.4s v0, v0, v1 192; CHECK-SD-NEXT: ret 193; 194; CHECK-GI-LABEL: uabdl2_4s: 195; CHECK-GI: // %bb.0: 196; CHECK-GI-NEXT: ldr q0, [x0] 197; CHECK-GI-NEXT: ldr q1, [x1] 198; CHECK-GI-NEXT: uabdl2.4s v0, v0, v1 199; CHECK-GI-NEXT: ret 200 %load1 = load <8 x i16>, ptr %A 201 %load2 = load <8 x i16>, ptr %B 202 %tmp1 = shufflevector <8 x i16> %load1, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7> 203 %tmp2 = shufflevector <8 x i16> %load2, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7> 204 %tmp3 = call <4 x i16> @llvm.aarch64.neon.uabd.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2) 205 %tmp4 = zext <4 x i16> %tmp3 to <4 x i32> 206 ret <4 x i32> %tmp4 207} 208 209define <2 x i64> @uabdl2_2d(ptr %A, ptr %B) nounwind { 210; CHECK-SD-LABEL: uabdl2_2d: 211; CHECK-SD: // %bb.0: 212; CHECK-SD-NEXT: ldr d0, [x0, #8] 213; CHECK-SD-NEXT: ldr d1, [x1, #8] 214; CHECK-SD-NEXT: uabdl.2d v0, v0, v1 215; CHECK-SD-NEXT: ret 216; 217; CHECK-GI-LABEL: uabdl2_2d: 218; CHECK-GI: // %bb.0: 219; CHECK-GI-NEXT: ldr q0, [x0] 220; CHECK-GI-NEXT: ldr q1, [x1] 221; CHECK-GI-NEXT: uabdl2.2d v0, v0, v1 222; CHECK-GI-NEXT: ret 223 %load1 = load <4 x i32>, ptr %A 224 %load2 = load <4 x i32>, ptr %B 225 %tmp1 = shufflevector <4 x i32> %load1, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 226 %tmp2 = shufflevector <4 x i32> %load2, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 227 %tmp3 = call <2 x i32> @llvm.aarch64.neon.uabd.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2) 228 %tmp4 = zext <2 x i32> %tmp3 to <2 x i64> 229 ret <2 x i64> %tmp4 230} 231 232declare i16 @llvm.vector.reduce.add.v16i16(<16 x i16>) 233declare i32 @llvm.vector.reduce.add.v16i32(<16 x i32>) 234 235define i16 @uabd16b_rdx(ptr %a, ptr %b) { 236; CHECK-SD-LABEL: uabd16b_rdx: 237; CHECK-SD: // %bb.0: 238; CHECK-SD-NEXT: ldr q0, [x0] 239; CHECK-SD-NEXT: ldr q1, [x1] 240; CHECK-SD-NEXT: uabd.16b v0, v0, v1 241; CHECK-SD-NEXT: uaddlv.16b h0, v0 242; CHECK-SD-NEXT: fmov w0, s0 243; CHECK-SD-NEXT: ret 244; 245; CHECK-GI-LABEL: uabd16b_rdx: 246; CHECK-GI: // %bb.0: 247; CHECK-GI-NEXT: ldr q0, [x0] 248; CHECK-GI-NEXT: ldr q1, [x1] 249; CHECK-GI-NEXT: usubl.8h v2, v0, v1 250; CHECK-GI-NEXT: usubl2.8h v0, v0, v1 251; CHECK-GI-NEXT: cmlt.8h v1, v2, #0 252; CHECK-GI-NEXT: cmlt.8h v3, v0, #0 253; CHECK-GI-NEXT: neg.8h v4, v2 254; CHECK-GI-NEXT: neg.8h v5, v0 255; CHECK-GI-NEXT: bsl.16b v1, v4, v2 256; CHECK-GI-NEXT: bit.16b v0, v5, v3 257; CHECK-GI-NEXT: add.8h v0, v1, v0 258; CHECK-GI-NEXT: addv.8h h0, v0 259; CHECK-GI-NEXT: fmov w0, s0 260; CHECK-GI-NEXT: ret 261 %aload = load <16 x i8>, ptr %a, align 1 262 %bload = load <16 x i8>, ptr %b, align 1 263 %aext = zext <16 x i8> %aload to <16 x i16> 264 %bext = zext <16 x i8> %bload to <16 x i16> 265 %abdiff = sub nsw <16 x i16> %aext, %bext 266 %abcmp = icmp slt <16 x i16> %abdiff, zeroinitializer 267 %ababs = sub nsw <16 x i16> zeroinitializer, %abdiff 268 %absel = select <16 x i1> %abcmp, <16 x i16> %ababs, <16 x i16> %abdiff 269 %reduced_v = call i16 @llvm.vector.reduce.add.v16i16(<16 x i16> %absel) 270 ret i16 %reduced_v 271} 272 273define i32 @uabd16b_rdx_i32(<16 x i8> %a, <16 x i8> %b) { 274; CHECK-SD-LABEL: uabd16b_rdx_i32: 275; CHECK-SD: // %bb.0: 276; CHECK-SD-NEXT: uabdl.8h v2, v0, v1 277; CHECK-SD-NEXT: uabal2.8h v2, v0, v1 278; CHECK-SD-NEXT: uaddlv.8h s0, v2 279; CHECK-SD-NEXT: fmov w0, s0 280; CHECK-SD-NEXT: ret 281; 282; CHECK-GI-LABEL: uabd16b_rdx_i32: 283; CHECK-GI: // %bb.0: 284; CHECK-GI-NEXT: usubl.8h v3, v0, v1 285; CHECK-GI-NEXT: movi.2d v2, #0000000000000000 286; CHECK-GI-NEXT: usubl2.8h v0, v0, v1 287; CHECK-GI-NEXT: sshll.4s v1, v3, #0 288; CHECK-GI-NEXT: sshll2.4s v4, v3, #0 289; CHECK-GI-NEXT: sshll.4s v5, v0, #0 290; CHECK-GI-NEXT: sshll2.4s v6, v0, #0 291; CHECK-GI-NEXT: ssubw2.4s v3, v2, v3 292; CHECK-GI-NEXT: ssubw2.4s v0, v2, v0 293; CHECK-GI-NEXT: cmlt.4s v2, v1, #0 294; CHECK-GI-NEXT: cmlt.4s v7, v4, #0 295; CHECK-GI-NEXT: neg.4s v16, v1 296; CHECK-GI-NEXT: cmlt.4s v17, v5, #0 297; CHECK-GI-NEXT: cmlt.4s v18, v6, #0 298; CHECK-GI-NEXT: neg.4s v19, v5 299; CHECK-GI-NEXT: bit.16b v1, v16, v2 300; CHECK-GI-NEXT: mov.16b v2, v7 301; CHECK-GI-NEXT: bif.16b v0, v6, v18 302; CHECK-GI-NEXT: bsl.16b v2, v3, v4 303; CHECK-GI-NEXT: mov.16b v3, v17 304; CHECK-GI-NEXT: bsl.16b v3, v19, v5 305; CHECK-GI-NEXT: add.4s v1, v1, v2 306; CHECK-GI-NEXT: add.4s v0, v3, v0 307; CHECK-GI-NEXT: add.4s v0, v1, v0 308; CHECK-GI-NEXT: addv.4s s0, v0 309; CHECK-GI-NEXT: fmov w0, s0 310; CHECK-GI-NEXT: ret 311 %aext = zext <16 x i8> %a to <16 x i32> 312 %bext = zext <16 x i8> %b to <16 x i32> 313 %abdiff = sub nsw <16 x i32> %aext, %bext 314 %abcmp = icmp slt <16 x i32> %abdiff, zeroinitializer 315 %ababs = sub nsw <16 x i32> zeroinitializer, %abdiff 316 %absel = select <16 x i1> %abcmp, <16 x i32> %ababs, <16 x i32> %abdiff 317 %reduced_v = call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %absel) 318 ret i32 %reduced_v 319} 320 321define i32 @sabd16b_rdx_i32(<16 x i8> %a, <16 x i8> %b) { 322; CHECK-SD-LABEL: sabd16b_rdx_i32: 323; CHECK-SD: // %bb.0: 324; CHECK-SD-NEXT: sabdl.8h v2, v0, v1 325; CHECK-SD-NEXT: sabal2.8h v2, v0, v1 326; CHECK-SD-NEXT: uaddlv.8h s0, v2 327; CHECK-SD-NEXT: fmov w0, s0 328; CHECK-SD-NEXT: ret 329; 330; CHECK-GI-LABEL: sabd16b_rdx_i32: 331; CHECK-GI: // %bb.0: 332; CHECK-GI-NEXT: ssubl.8h v3, v0, v1 333; CHECK-GI-NEXT: movi.2d v2, #0000000000000000 334; CHECK-GI-NEXT: ssubl2.8h v0, v0, v1 335; CHECK-GI-NEXT: sshll.4s v1, v3, #0 336; CHECK-GI-NEXT: sshll2.4s v4, v3, #0 337; CHECK-GI-NEXT: sshll.4s v5, v0, #0 338; CHECK-GI-NEXT: sshll2.4s v6, v0, #0 339; CHECK-GI-NEXT: ssubw2.4s v3, v2, v3 340; CHECK-GI-NEXT: ssubw2.4s v0, v2, v0 341; CHECK-GI-NEXT: cmlt.4s v2, v1, #0 342; CHECK-GI-NEXT: cmlt.4s v7, v4, #0 343; CHECK-GI-NEXT: neg.4s v16, v1 344; CHECK-GI-NEXT: cmlt.4s v17, v5, #0 345; CHECK-GI-NEXT: cmlt.4s v18, v6, #0 346; CHECK-GI-NEXT: neg.4s v19, v5 347; CHECK-GI-NEXT: bit.16b v1, v16, v2 348; CHECK-GI-NEXT: mov.16b v2, v7 349; CHECK-GI-NEXT: bif.16b v0, v6, v18 350; CHECK-GI-NEXT: bsl.16b v2, v3, v4 351; CHECK-GI-NEXT: mov.16b v3, v17 352; CHECK-GI-NEXT: bsl.16b v3, v19, v5 353; CHECK-GI-NEXT: add.4s v1, v1, v2 354; CHECK-GI-NEXT: add.4s v0, v3, v0 355; CHECK-GI-NEXT: add.4s v0, v1, v0 356; CHECK-GI-NEXT: addv.4s s0, v0 357; CHECK-GI-NEXT: fmov w0, s0 358; CHECK-GI-NEXT: ret 359 %aext = sext <16 x i8> %a to <16 x i32> 360 %bext = sext <16 x i8> %b to <16 x i32> 361 %abdiff = sub nsw <16 x i32> %aext, %bext 362 %abcmp = icmp slt <16 x i32> %abdiff, zeroinitializer 363 %ababs = sub nsw <16 x i32> zeroinitializer, %abdiff 364 %absel = select <16 x i1> %abcmp, <16 x i32> %ababs, <16 x i32> %abdiff 365 %reduced_v = call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %absel) 366 ret i32 %reduced_v 367} 368 369 370declare i32 @llvm.vector.reduce.add.v8i32(<8 x i32>) 371declare i32 @llvm.vector.reduce.add.v4i32(<4 x i32>) 372 373define i32 @uabd8h_rdx(ptr %a, ptr %b) { 374; CHECK-SD-LABEL: uabd8h_rdx: 375; CHECK-SD: // %bb.0: 376; CHECK-SD-NEXT: ldr q0, [x0] 377; CHECK-SD-NEXT: ldr q1, [x1] 378; CHECK-SD-NEXT: uabd.8h v0, v0, v1 379; CHECK-SD-NEXT: uaddlv.8h s0, v0 380; CHECK-SD-NEXT: fmov w0, s0 381; CHECK-SD-NEXT: ret 382; 383; CHECK-GI-LABEL: uabd8h_rdx: 384; CHECK-GI: // %bb.0: 385; CHECK-GI-NEXT: ldr q0, [x0] 386; CHECK-GI-NEXT: ldr q1, [x1] 387; CHECK-GI-NEXT: usubl.4s v2, v0, v1 388; CHECK-GI-NEXT: usubl2.4s v0, v0, v1 389; CHECK-GI-NEXT: cmlt.4s v1, v2, #0 390; CHECK-GI-NEXT: cmlt.4s v3, v0, #0 391; CHECK-GI-NEXT: neg.4s v4, v2 392; CHECK-GI-NEXT: neg.4s v5, v0 393; CHECK-GI-NEXT: bsl.16b v1, v4, v2 394; CHECK-GI-NEXT: bit.16b v0, v5, v3 395; CHECK-GI-NEXT: add.4s v0, v1, v0 396; CHECK-GI-NEXT: addv.4s s0, v0 397; CHECK-GI-NEXT: fmov w0, s0 398; CHECK-GI-NEXT: ret 399 %aload = load <8 x i16>, ptr %a, align 1 400 %bload = load <8 x i16>, ptr %b, align 1 401 %aext = zext <8 x i16> %aload to <8 x i32> 402 %bext = zext <8 x i16> %bload to <8 x i32> 403 %abdiff = sub nsw <8 x i32> %aext, %bext 404 %abcmp = icmp slt <8 x i32> %abdiff, zeroinitializer 405 %ababs = sub nsw <8 x i32> zeroinitializer, %abdiff 406 %absel = select <8 x i1> %abcmp, <8 x i32> %ababs, <8 x i32> %abdiff 407 %reduced_v = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %absel) 408 ret i32 %reduced_v 409} 410 411define i32 @sabd8h_rdx(<8 x i16> %a, <8 x i16> %b) { 412; CHECK-SD-LABEL: sabd8h_rdx: 413; CHECK-SD: // %bb.0: 414; CHECK-SD-NEXT: sabd.8h v0, v0, v1 415; CHECK-SD-NEXT: uaddlv.8h s0, v0 416; CHECK-SD-NEXT: fmov w0, s0 417; CHECK-SD-NEXT: ret 418; 419; CHECK-GI-LABEL: sabd8h_rdx: 420; CHECK-GI: // %bb.0: 421; CHECK-GI-NEXT: ssubl.4s v2, v0, v1 422; CHECK-GI-NEXT: ssubl2.4s v0, v0, v1 423; CHECK-GI-NEXT: cmlt.4s v1, v2, #0 424; CHECK-GI-NEXT: cmlt.4s v3, v0, #0 425; CHECK-GI-NEXT: neg.4s v4, v2 426; CHECK-GI-NEXT: neg.4s v5, v0 427; CHECK-GI-NEXT: bsl.16b v1, v4, v2 428; CHECK-GI-NEXT: bit.16b v0, v5, v3 429; CHECK-GI-NEXT: add.4s v0, v1, v0 430; CHECK-GI-NEXT: addv.4s s0, v0 431; CHECK-GI-NEXT: fmov w0, s0 432; CHECK-GI-NEXT: ret 433 %aext = sext <8 x i16> %a to <8 x i32> 434 %bext = sext <8 x i16> %b to <8 x i32> 435 %abdiff = sub nsw <8 x i32> %aext, %bext 436 %abcmp = icmp slt <8 x i32> %abdiff, zeroinitializer 437 %ababs = sub nsw <8 x i32> zeroinitializer, %abdiff 438 %absel = select <8 x i1> %abcmp, <8 x i32> %ababs, <8 x i32> %abdiff 439 %reduced_v = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %absel) 440 ret i32 %reduced_v 441} 442 443define i32 @uabdl4s_rdx_i32(<4 x i16> %a, <4 x i16> %b) { 444; CHECK-SD-LABEL: uabdl4s_rdx_i32: 445; CHECK-SD: // %bb.0: 446; CHECK-SD-NEXT: uabdl.4s v0, v0, v1 447; CHECK-SD-NEXT: addv.4s s0, v0 448; CHECK-SD-NEXT: fmov w0, s0 449; CHECK-SD-NEXT: ret 450; 451; CHECK-GI-LABEL: uabdl4s_rdx_i32: 452; CHECK-GI: // %bb.0: 453; CHECK-GI-NEXT: usubl.4s v0, v0, v1 454; CHECK-GI-NEXT: cmlt.4s v1, v0, #0 455; CHECK-GI-NEXT: neg.4s v2, v0 456; CHECK-GI-NEXT: bit.16b v0, v2, v1 457; CHECK-GI-NEXT: addv.4s s0, v0 458; CHECK-GI-NEXT: fmov w0, s0 459; CHECK-GI-NEXT: ret 460 %aext = zext <4 x i16> %a to <4 x i32> 461 %bext = zext <4 x i16> %b to <4 x i32> 462 %abdiff = sub nsw <4 x i32> %aext, %bext 463 %abcmp = icmp slt <4 x i32> %abdiff, zeroinitializer 464 %ababs = sub nsw <4 x i32> zeroinitializer, %abdiff 465 %absel = select <4 x i1> %abcmp, <4 x i32> %ababs, <4 x i32> %abdiff 466 %reduced_v = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %absel) 467 ret i32 %reduced_v 468} 469 470declare i64 @llvm.vector.reduce.add.v4i64(<4 x i64>) 471declare i64 @llvm.vector.reduce.add.v2i64(<2 x i64>) 472 473define i64 @uabd4s_rdx(ptr %a, ptr %b, i32 %h) { 474; CHECK-SD-LABEL: uabd4s_rdx: 475; CHECK-SD: // %bb.0: 476; CHECK-SD-NEXT: ldr q0, [x0] 477; CHECK-SD-NEXT: ldr q1, [x1] 478; CHECK-SD-NEXT: uabd.4s v0, v0, v1 479; CHECK-SD-NEXT: uaddlv.4s d0, v0 480; CHECK-SD-NEXT: fmov x0, d0 481; CHECK-SD-NEXT: ret 482; 483; CHECK-GI-LABEL: uabd4s_rdx: 484; CHECK-GI: // %bb.0: 485; CHECK-GI-NEXT: ldr q0, [x0] 486; CHECK-GI-NEXT: ldr q1, [x1] 487; CHECK-GI-NEXT: usubl.2d v2, v0, v1 488; CHECK-GI-NEXT: usubl2.2d v0, v0, v1 489; CHECK-GI-NEXT: cmlt.2d v1, v2, #0 490; CHECK-GI-NEXT: cmlt.2d v3, v0, #0 491; CHECK-GI-NEXT: neg.2d v4, v2 492; CHECK-GI-NEXT: neg.2d v5, v0 493; CHECK-GI-NEXT: bsl.16b v1, v4, v2 494; CHECK-GI-NEXT: bit.16b v0, v5, v3 495; CHECK-GI-NEXT: add.2d v0, v1, v0 496; CHECK-GI-NEXT: addp.2d d0, v0 497; CHECK-GI-NEXT: fmov x0, d0 498; CHECK-GI-NEXT: ret 499 %aload = load <4 x i32>, ptr %a, align 1 500 %bload = load <4 x i32>, ptr %b, align 1 501 %aext = zext <4 x i32> %aload to <4 x i64> 502 %bext = zext <4 x i32> %bload to <4 x i64> 503 %abdiff = sub nsw <4 x i64> %aext, %bext 504 %abcmp = icmp slt <4 x i64> %abdiff, zeroinitializer 505 %ababs = sub nsw <4 x i64> zeroinitializer, %abdiff 506 %absel = select <4 x i1> %abcmp, <4 x i64> %ababs, <4 x i64> %abdiff 507 %reduced_v = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %absel) 508 ret i64 %reduced_v 509} 510 511define i64 @sabd4s_rdx(<4 x i32> %a, <4 x i32> %b) { 512; CHECK-SD-LABEL: sabd4s_rdx: 513; CHECK-SD: // %bb.0: 514; CHECK-SD-NEXT: sabd.4s v0, v0, v1 515; CHECK-SD-NEXT: uaddlv.4s d0, v0 516; CHECK-SD-NEXT: fmov x0, d0 517; CHECK-SD-NEXT: ret 518; 519; CHECK-GI-LABEL: sabd4s_rdx: 520; CHECK-GI: // %bb.0: 521; CHECK-GI-NEXT: ssubl.2d v2, v0, v1 522; CHECK-GI-NEXT: ssubl2.2d v0, v0, v1 523; CHECK-GI-NEXT: cmlt.2d v1, v2, #0 524; CHECK-GI-NEXT: cmlt.2d v3, v0, #0 525; CHECK-GI-NEXT: neg.2d v4, v2 526; CHECK-GI-NEXT: neg.2d v5, v0 527; CHECK-GI-NEXT: bsl.16b v1, v4, v2 528; CHECK-GI-NEXT: bit.16b v0, v5, v3 529; CHECK-GI-NEXT: add.2d v0, v1, v0 530; CHECK-GI-NEXT: addp.2d d0, v0 531; CHECK-GI-NEXT: fmov x0, d0 532; CHECK-GI-NEXT: ret 533 %aext = sext <4 x i32> %a to <4 x i64> 534 %bext = sext <4 x i32> %b to <4 x i64> 535 %abdiff = sub nsw <4 x i64> %aext, %bext 536 %abcmp = icmp slt <4 x i64> %abdiff, zeroinitializer 537 %ababs = sub nsw <4 x i64> zeroinitializer, %abdiff 538 %absel = select <4 x i1> %abcmp, <4 x i64> %ababs, <4 x i64> %abdiff 539 %reduced_v = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %absel) 540 ret i64 %reduced_v 541} 542 543define i64 @uabdl2d_rdx_i64(<2 x i32> %a, <2 x i32> %b) { 544; CHECK-SD-LABEL: uabdl2d_rdx_i64: 545; CHECK-SD: // %bb.0: 546; CHECK-SD-NEXT: uabdl.2d v0, v0, v1 547; CHECK-SD-NEXT: addp.2d d0, v0 548; CHECK-SD-NEXT: fmov x0, d0 549; CHECK-SD-NEXT: ret 550; 551; CHECK-GI-LABEL: uabdl2d_rdx_i64: 552; CHECK-GI: // %bb.0: 553; CHECK-GI-NEXT: usubl.2d v0, v0, v1 554; CHECK-GI-NEXT: cmlt.2d v1, v0, #0 555; CHECK-GI-NEXT: neg.2d v2, v0 556; CHECK-GI-NEXT: bit.16b v0, v2, v1 557; CHECK-GI-NEXT: addp.2d d0, v0 558; CHECK-GI-NEXT: fmov x0, d0 559; CHECK-GI-NEXT: ret 560 %aext = zext <2 x i32> %a to <2 x i64> 561 %bext = zext <2 x i32> %b to <2 x i64> 562 %abdiff = sub nsw <2 x i64> %aext, %bext 563 %abcmp = icmp slt <2 x i64> %abdiff, zeroinitializer 564 %ababs = sub nsw <2 x i64> zeroinitializer, %abdiff 565 %absel = select <2 x i1> %abcmp, <2 x i64> %ababs, <2 x i64> %abdiff 566 %reduced_v = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %absel) 567 ret i64 %reduced_v 568} 569 570define <2 x float> @fabd_2s(ptr %A, ptr %B) nounwind { 571; CHECK-LABEL: fabd_2s: 572; CHECK: // %bb.0: 573; CHECK-NEXT: ldr d0, [x0] 574; CHECK-NEXT: ldr d1, [x1] 575; CHECK-NEXT: fabd.2s v0, v0, v1 576; CHECK-NEXT: ret 577 %tmp1 = load <2 x float>, ptr %A 578 %tmp2 = load <2 x float>, ptr %B 579 %tmp3 = call <2 x float> @llvm.aarch64.neon.fabd.v2f32(<2 x float> %tmp1, <2 x float> %tmp2) 580 ret <2 x float> %tmp3 581} 582 583define <4 x float> @fabd_4s(ptr %A, ptr %B) nounwind { 584; CHECK-LABEL: fabd_4s: 585; CHECK: // %bb.0: 586; CHECK-NEXT: ldr q0, [x0] 587; CHECK-NEXT: ldr q1, [x1] 588; CHECK-NEXT: fabd.4s v0, v0, v1 589; CHECK-NEXT: ret 590 %tmp1 = load <4 x float>, ptr %A 591 %tmp2 = load <4 x float>, ptr %B 592 %tmp3 = call <4 x float> @llvm.aarch64.neon.fabd.v4f32(<4 x float> %tmp1, <4 x float> %tmp2) 593 ret <4 x float> %tmp3 594} 595 596define <2 x double> @fabd_2d(ptr %A, ptr %B) nounwind { 597; CHECK-LABEL: fabd_2d: 598; CHECK: // %bb.0: 599; CHECK-NEXT: ldr q0, [x0] 600; CHECK-NEXT: ldr q1, [x1] 601; CHECK-NEXT: fabd.2d v0, v0, v1 602; CHECK-NEXT: ret 603 %tmp1 = load <2 x double>, ptr %A 604 %tmp2 = load <2 x double>, ptr %B 605 %tmp3 = call <2 x double> @llvm.aarch64.neon.fabd.v2f64(<2 x double> %tmp1, <2 x double> %tmp2) 606 ret <2 x double> %tmp3 607} 608 609declare <2 x float> @llvm.aarch64.neon.fabd.v2f32(<2 x float>, <2 x float>) nounwind readnone 610declare <4 x float> @llvm.aarch64.neon.fabd.v4f32(<4 x float>, <4 x float>) nounwind readnone 611declare <2 x double> @llvm.aarch64.neon.fabd.v2f64(<2 x double>, <2 x double>) nounwind readnone 612 613define <2 x float> @fabd_2s_from_fsub_fabs(ptr %A, ptr %B) nounwind { 614; CHECK-LABEL: fabd_2s_from_fsub_fabs: 615; CHECK: // %bb.0: 616; CHECK-NEXT: ldr d0, [x0] 617; CHECK-NEXT: ldr d1, [x1] 618; CHECK-NEXT: fabd.2s v0, v0, v1 619; CHECK-NEXT: ret 620 %tmp1 = load <2 x float>, ptr %A 621 %tmp2 = load <2 x float>, ptr %B 622 %sub = fsub <2 x float> %tmp1, %tmp2 623 %abs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %sub) 624 ret <2 x float> %abs 625} 626 627define <4 x float> @fabd_4s_from_fsub_fabs(ptr %A, ptr %B) nounwind { 628; CHECK-LABEL: fabd_4s_from_fsub_fabs: 629; CHECK: // %bb.0: 630; CHECK-NEXT: ldr q0, [x0] 631; CHECK-NEXT: ldr q1, [x1] 632; CHECK-NEXT: fabd.4s v0, v0, v1 633; CHECK-NEXT: ret 634 %tmp1 = load <4 x float>, ptr %A 635 %tmp2 = load <4 x float>, ptr %B 636 %sub = fsub <4 x float> %tmp1, %tmp2 637 %abs = call <4 x float> @llvm.fabs.v4f32(<4 x float> %sub) 638 ret <4 x float> %abs 639} 640 641define <2 x double> @fabd_2d_from_fsub_fabs(ptr %A, ptr %B) nounwind { 642; CHECK-LABEL: fabd_2d_from_fsub_fabs: 643; CHECK: // %bb.0: 644; CHECK-NEXT: ldr q0, [x0] 645; CHECK-NEXT: ldr q1, [x1] 646; CHECK-NEXT: fabd.2d v0, v0, v1 647; CHECK-NEXT: ret 648 %tmp1 = load <2 x double>, ptr %A 649 %tmp2 = load <2 x double>, ptr %B 650 %sub = fsub <2 x double> %tmp1, %tmp2 651 %abs = call <2 x double> @llvm.fabs.v2f64(<2 x double> %sub) 652 ret <2 x double> %abs 653} 654 655declare <2 x float> @llvm.fabs.v2f32(<2 x float>) nounwind readnone 656declare <4 x float> @llvm.fabs.v4f32(<4 x float>) nounwind readnone 657declare <2 x double> @llvm.fabs.v2f64(<2 x double>) nounwind readnone 658 659define <8 x i8> @sabd_8b(ptr %A, ptr %B) nounwind { 660; CHECK-LABEL: sabd_8b: 661; CHECK: // %bb.0: 662; CHECK-NEXT: ldr d0, [x0] 663; CHECK-NEXT: ldr d1, [x1] 664; CHECK-NEXT: sabd.8b v0, v0, v1 665; CHECK-NEXT: ret 666 %tmp1 = load <8 x i8>, ptr %A 667 %tmp2 = load <8 x i8>, ptr %B 668 %tmp3 = call <8 x i8> @llvm.aarch64.neon.sabd.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2) 669 ret <8 x i8> %tmp3 670} 671 672define <16 x i8> @sabd_16b(ptr %A, ptr %B) nounwind { 673; CHECK-LABEL: sabd_16b: 674; CHECK: // %bb.0: 675; CHECK-NEXT: ldr q0, [x0] 676; CHECK-NEXT: ldr q1, [x1] 677; CHECK-NEXT: sabd.16b v0, v0, v1 678; CHECK-NEXT: ret 679 %tmp1 = load <16 x i8>, ptr %A 680 %tmp2 = load <16 x i8>, ptr %B 681 %tmp3 = call <16 x i8> @llvm.aarch64.neon.sabd.v16i8(<16 x i8> %tmp1, <16 x i8> %tmp2) 682 ret <16 x i8> %tmp3 683} 684 685define <4 x i16> @sabd_4h(ptr %A, ptr %B) nounwind { 686; CHECK-LABEL: sabd_4h: 687; CHECK: // %bb.0: 688; CHECK-NEXT: ldr d0, [x0] 689; CHECK-NEXT: ldr d1, [x1] 690; CHECK-NEXT: sabd.4h v0, v0, v1 691; CHECK-NEXT: ret 692 %tmp1 = load <4 x i16>, ptr %A 693 %tmp2 = load <4 x i16>, ptr %B 694 %tmp3 = call <4 x i16> @llvm.aarch64.neon.sabd.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2) 695 ret <4 x i16> %tmp3 696} 697 698define <8 x i16> @sabd_8h(ptr %A, ptr %B) nounwind { 699; CHECK-LABEL: sabd_8h: 700; CHECK: // %bb.0: 701; CHECK-NEXT: ldr q0, [x0] 702; CHECK-NEXT: ldr q1, [x1] 703; CHECK-NEXT: sabd.8h v0, v0, v1 704; CHECK-NEXT: ret 705 %tmp1 = load <8 x i16>, ptr %A 706 %tmp2 = load <8 x i16>, ptr %B 707 %tmp3 = call <8 x i16> @llvm.aarch64.neon.sabd.v8i16(<8 x i16> %tmp1, <8 x i16> %tmp2) 708 ret <8 x i16> %tmp3 709} 710 711define <2 x i32> @sabd_2s(ptr %A, ptr %B) nounwind { 712; CHECK-LABEL: sabd_2s: 713; CHECK: // %bb.0: 714; CHECK-NEXT: ldr d0, [x0] 715; CHECK-NEXT: ldr d1, [x1] 716; CHECK-NEXT: sabd.2s v0, v0, v1 717; CHECK-NEXT: ret 718 %tmp1 = load <2 x i32>, ptr %A 719 %tmp2 = load <2 x i32>, ptr %B 720 %tmp3 = call <2 x i32> @llvm.aarch64.neon.sabd.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2) 721 ret <2 x i32> %tmp3 722} 723 724define <4 x i32> @sabd_4s(ptr %A, ptr %B) nounwind { 725; CHECK-LABEL: sabd_4s: 726; CHECK: // %bb.0: 727; CHECK-NEXT: ldr q0, [x0] 728; CHECK-NEXT: ldr q1, [x1] 729; CHECK-NEXT: sabd.4s v0, v0, v1 730; CHECK-NEXT: ret 731 %tmp1 = load <4 x i32>, ptr %A 732 %tmp2 = load <4 x i32>, ptr %B 733 %tmp3 = call <4 x i32> @llvm.aarch64.neon.sabd.v4i32(<4 x i32> %tmp1, <4 x i32> %tmp2) 734 ret <4 x i32> %tmp3 735} 736 737declare <8 x i8> @llvm.aarch64.neon.sabd.v8i8(<8 x i8>, <8 x i8>) nounwind readnone 738declare <16 x i8> @llvm.aarch64.neon.sabd.v16i8(<16 x i8>, <16 x i8>) nounwind readnone 739declare <4 x i16> @llvm.aarch64.neon.sabd.v4i16(<4 x i16>, <4 x i16>) nounwind readnone 740declare <8 x i16> @llvm.aarch64.neon.sabd.v8i16(<8 x i16>, <8 x i16>) nounwind readnone 741declare <2 x i32> @llvm.aarch64.neon.sabd.v2i32(<2 x i32>, <2 x i32>) nounwind readnone 742declare <4 x i32> @llvm.aarch64.neon.sabd.v4i32(<4 x i32>, <4 x i32>) nounwind readnone 743 744define <8 x i8> @uabd_8b(ptr %A, ptr %B) nounwind { 745; CHECK-LABEL: uabd_8b: 746; CHECK: // %bb.0: 747; CHECK-NEXT: ldr d0, [x0] 748; CHECK-NEXT: ldr d1, [x1] 749; CHECK-NEXT: uabd.8b v0, v0, v1 750; CHECK-NEXT: ret 751 %tmp1 = load <8 x i8>, ptr %A 752 %tmp2 = load <8 x i8>, ptr %B 753 %tmp3 = call <8 x i8> @llvm.aarch64.neon.uabd.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2) 754 ret <8 x i8> %tmp3 755} 756 757define <16 x i8> @uabd_16b(ptr %A, ptr %B) nounwind { 758; CHECK-LABEL: uabd_16b: 759; CHECK: // %bb.0: 760; CHECK-NEXT: ldr q0, [x0] 761; CHECK-NEXT: ldr q1, [x1] 762; CHECK-NEXT: uabd.16b v0, v0, v1 763; CHECK-NEXT: ret 764 %tmp1 = load <16 x i8>, ptr %A 765 %tmp2 = load <16 x i8>, ptr %B 766 %tmp3 = call <16 x i8> @llvm.aarch64.neon.uabd.v16i8(<16 x i8> %tmp1, <16 x i8> %tmp2) 767 ret <16 x i8> %tmp3 768} 769 770define <4 x i16> @uabd_4h(ptr %A, ptr %B) nounwind { 771; CHECK-LABEL: uabd_4h: 772; CHECK: // %bb.0: 773; CHECK-NEXT: ldr d0, [x0] 774; CHECK-NEXT: ldr d1, [x1] 775; CHECK-NEXT: uabd.4h v0, v0, v1 776; CHECK-NEXT: ret 777 %tmp1 = load <4 x i16>, ptr %A 778 %tmp2 = load <4 x i16>, ptr %B 779 %tmp3 = call <4 x i16> @llvm.aarch64.neon.uabd.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2) 780 ret <4 x i16> %tmp3 781} 782 783define <8 x i16> @uabd_8h(ptr %A, ptr %B) nounwind { 784; CHECK-LABEL: uabd_8h: 785; CHECK: // %bb.0: 786; CHECK-NEXT: ldr q0, [x0] 787; CHECK-NEXT: ldr q1, [x1] 788; CHECK-NEXT: uabd.8h v0, v0, v1 789; CHECK-NEXT: ret 790 %tmp1 = load <8 x i16>, ptr %A 791 %tmp2 = load <8 x i16>, ptr %B 792 %tmp3 = call <8 x i16> @llvm.aarch64.neon.uabd.v8i16(<8 x i16> %tmp1, <8 x i16> %tmp2) 793 ret <8 x i16> %tmp3 794} 795 796define <2 x i32> @uabd_2s(ptr %A, ptr %B) nounwind { 797; CHECK-LABEL: uabd_2s: 798; CHECK: // %bb.0: 799; CHECK-NEXT: ldr d0, [x0] 800; CHECK-NEXT: ldr d1, [x1] 801; CHECK-NEXT: uabd.2s v0, v0, v1 802; CHECK-NEXT: ret 803 %tmp1 = load <2 x i32>, ptr %A 804 %tmp2 = load <2 x i32>, ptr %B 805 %tmp3 = call <2 x i32> @llvm.aarch64.neon.uabd.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2) 806 ret <2 x i32> %tmp3 807} 808 809define <4 x i32> @uabd_4s(ptr %A, ptr %B) nounwind { 810; CHECK-LABEL: uabd_4s: 811; CHECK: // %bb.0: 812; CHECK-NEXT: ldr q0, [x0] 813; CHECK-NEXT: ldr q1, [x1] 814; CHECK-NEXT: uabd.4s v0, v0, v1 815; CHECK-NEXT: ret 816 %tmp1 = load <4 x i32>, ptr %A 817 %tmp2 = load <4 x i32>, ptr %B 818 %tmp3 = call <4 x i32> @llvm.aarch64.neon.uabd.v4i32(<4 x i32> %tmp1, <4 x i32> %tmp2) 819 ret <4 x i32> %tmp3 820} 821 822declare <8 x i8> @llvm.aarch64.neon.uabd.v8i8(<8 x i8>, <8 x i8>) nounwind readnone 823declare <16 x i8> @llvm.aarch64.neon.uabd.v16i8(<16 x i8>, <16 x i8>) nounwind readnone 824declare <4 x i16> @llvm.aarch64.neon.uabd.v4i16(<4 x i16>, <4 x i16>) nounwind readnone 825declare <8 x i16> @llvm.aarch64.neon.uabd.v8i16(<8 x i16>, <8 x i16>) nounwind readnone 826declare <2 x i32> @llvm.aarch64.neon.uabd.v2i32(<2 x i32>, <2 x i32>) nounwind readnone 827declare <4 x i32> @llvm.aarch64.neon.uabd.v4i32(<4 x i32>, <4 x i32>) nounwind readnone 828 829define <8 x i8> @sqabs_8b(ptr %A) nounwind { 830; CHECK-LABEL: sqabs_8b: 831; CHECK: // %bb.0: 832; CHECK-NEXT: ldr d0, [x0] 833; CHECK-NEXT: sqabs.8b v0, v0 834; CHECK-NEXT: ret 835 %tmp1 = load <8 x i8>, ptr %A 836 %tmp3 = call <8 x i8> @llvm.aarch64.neon.sqabs.v8i8(<8 x i8> %tmp1) 837 ret <8 x i8> %tmp3 838} 839 840define <16 x i8> @sqabs_16b(ptr %A) nounwind { 841; CHECK-LABEL: sqabs_16b: 842; CHECK: // %bb.0: 843; CHECK-NEXT: ldr q0, [x0] 844; CHECK-NEXT: sqabs.16b v0, v0 845; CHECK-NEXT: ret 846 %tmp1 = load <16 x i8>, ptr %A 847 %tmp3 = call <16 x i8> @llvm.aarch64.neon.sqabs.v16i8(<16 x i8> %tmp1) 848 ret <16 x i8> %tmp3 849} 850 851define <4 x i16> @sqabs_4h(ptr %A) nounwind { 852; CHECK-LABEL: sqabs_4h: 853; CHECK: // %bb.0: 854; CHECK-NEXT: ldr d0, [x0] 855; CHECK-NEXT: sqabs.4h v0, v0 856; CHECK-NEXT: ret 857 %tmp1 = load <4 x i16>, ptr %A 858 %tmp3 = call <4 x i16> @llvm.aarch64.neon.sqabs.v4i16(<4 x i16> %tmp1) 859 ret <4 x i16> %tmp3 860} 861 862define <8 x i16> @sqabs_8h(ptr %A) nounwind { 863; CHECK-LABEL: sqabs_8h: 864; CHECK: // %bb.0: 865; CHECK-NEXT: ldr q0, [x0] 866; CHECK-NEXT: sqabs.8h v0, v0 867; CHECK-NEXT: ret 868 %tmp1 = load <8 x i16>, ptr %A 869 %tmp3 = call <8 x i16> @llvm.aarch64.neon.sqabs.v8i16(<8 x i16> %tmp1) 870 ret <8 x i16> %tmp3 871} 872 873define <2 x i32> @sqabs_2s(ptr %A) nounwind { 874; CHECK-LABEL: sqabs_2s: 875; CHECK: // %bb.0: 876; CHECK-NEXT: ldr d0, [x0] 877; CHECK-NEXT: sqabs.2s v0, v0 878; CHECK-NEXT: ret 879 %tmp1 = load <2 x i32>, ptr %A 880 %tmp3 = call <2 x i32> @llvm.aarch64.neon.sqabs.v2i32(<2 x i32> %tmp1) 881 ret <2 x i32> %tmp3 882} 883 884define <4 x i32> @sqabs_4s(ptr %A) nounwind { 885; CHECK-LABEL: sqabs_4s: 886; CHECK: // %bb.0: 887; CHECK-NEXT: ldr q0, [x0] 888; CHECK-NEXT: sqabs.4s v0, v0 889; CHECK-NEXT: ret 890 %tmp1 = load <4 x i32>, ptr %A 891 %tmp3 = call <4 x i32> @llvm.aarch64.neon.sqabs.v4i32(<4 x i32> %tmp1) 892 ret <4 x i32> %tmp3 893} 894 895declare <8 x i8> @llvm.aarch64.neon.sqabs.v8i8(<8 x i8>) nounwind readnone 896declare <16 x i8> @llvm.aarch64.neon.sqabs.v16i8(<16 x i8>) nounwind readnone 897declare <4 x i16> @llvm.aarch64.neon.sqabs.v4i16(<4 x i16>) nounwind readnone 898declare <8 x i16> @llvm.aarch64.neon.sqabs.v8i16(<8 x i16>) nounwind readnone 899declare <2 x i32> @llvm.aarch64.neon.sqabs.v2i32(<2 x i32>) nounwind readnone 900declare <4 x i32> @llvm.aarch64.neon.sqabs.v4i32(<4 x i32>) nounwind readnone 901 902define <8 x i8> @sqneg_8b(ptr %A) nounwind { 903; CHECK-LABEL: sqneg_8b: 904; CHECK: // %bb.0: 905; CHECK-NEXT: ldr d0, [x0] 906; CHECK-NEXT: sqneg.8b v0, v0 907; CHECK-NEXT: ret 908 %tmp1 = load <8 x i8>, ptr %A 909 %tmp3 = call <8 x i8> @llvm.aarch64.neon.sqneg.v8i8(<8 x i8> %tmp1) 910 ret <8 x i8> %tmp3 911} 912 913define <16 x i8> @sqneg_16b(ptr %A) nounwind { 914; CHECK-LABEL: sqneg_16b: 915; CHECK: // %bb.0: 916; CHECK-NEXT: ldr q0, [x0] 917; CHECK-NEXT: sqneg.16b v0, v0 918; CHECK-NEXT: ret 919 %tmp1 = load <16 x i8>, ptr %A 920 %tmp3 = call <16 x i8> @llvm.aarch64.neon.sqneg.v16i8(<16 x i8> %tmp1) 921 ret <16 x i8> %tmp3 922} 923 924define <4 x i16> @sqneg_4h(ptr %A) nounwind { 925; CHECK-LABEL: sqneg_4h: 926; CHECK: // %bb.0: 927; CHECK-NEXT: ldr d0, [x0] 928; CHECK-NEXT: sqneg.4h v0, v0 929; CHECK-NEXT: ret 930 %tmp1 = load <4 x i16>, ptr %A 931 %tmp3 = call <4 x i16> @llvm.aarch64.neon.sqneg.v4i16(<4 x i16> %tmp1) 932 ret <4 x i16> %tmp3 933} 934 935define <8 x i16> @sqneg_8h(ptr %A) nounwind { 936; CHECK-LABEL: sqneg_8h: 937; CHECK: // %bb.0: 938; CHECK-NEXT: ldr q0, [x0] 939; CHECK-NEXT: sqneg.8h v0, v0 940; CHECK-NEXT: ret 941 %tmp1 = load <8 x i16>, ptr %A 942 %tmp3 = call <8 x i16> @llvm.aarch64.neon.sqneg.v8i16(<8 x i16> %tmp1) 943 ret <8 x i16> %tmp3 944} 945 946define <2 x i32> @sqneg_2s(ptr %A) nounwind { 947; CHECK-LABEL: sqneg_2s: 948; CHECK: // %bb.0: 949; CHECK-NEXT: ldr d0, [x0] 950; CHECK-NEXT: sqneg.2s v0, v0 951; CHECK-NEXT: ret 952 %tmp1 = load <2 x i32>, ptr %A 953 %tmp3 = call <2 x i32> @llvm.aarch64.neon.sqneg.v2i32(<2 x i32> %tmp1) 954 ret <2 x i32> %tmp3 955} 956 957define <4 x i32> @sqneg_4s(ptr %A) nounwind { 958; CHECK-LABEL: sqneg_4s: 959; CHECK: // %bb.0: 960; CHECK-NEXT: ldr q0, [x0] 961; CHECK-NEXT: sqneg.4s v0, v0 962; CHECK-NEXT: ret 963 %tmp1 = load <4 x i32>, ptr %A 964 %tmp3 = call <4 x i32> @llvm.aarch64.neon.sqneg.v4i32(<4 x i32> %tmp1) 965 ret <4 x i32> %tmp3 966} 967 968declare <8 x i8> @llvm.aarch64.neon.sqneg.v8i8(<8 x i8>) nounwind readnone 969declare <16 x i8> @llvm.aarch64.neon.sqneg.v16i8(<16 x i8>) nounwind readnone 970declare <4 x i16> @llvm.aarch64.neon.sqneg.v4i16(<4 x i16>) nounwind readnone 971declare <8 x i16> @llvm.aarch64.neon.sqneg.v8i16(<8 x i16>) nounwind readnone 972declare <2 x i32> @llvm.aarch64.neon.sqneg.v2i32(<2 x i32>) nounwind readnone 973declare <4 x i32> @llvm.aarch64.neon.sqneg.v4i32(<4 x i32>) nounwind readnone 974 975define <8 x i8> @abs_8b(ptr %A) nounwind { 976; CHECK-LABEL: abs_8b: 977; CHECK: // %bb.0: 978; CHECK-NEXT: ldr d0, [x0] 979; CHECK-NEXT: abs.8b v0, v0 980; CHECK-NEXT: ret 981 %tmp1 = load <8 x i8>, ptr %A 982 %tmp3 = call <8 x i8> @llvm.aarch64.neon.abs.v8i8(<8 x i8> %tmp1) 983 ret <8 x i8> %tmp3 984} 985 986define <16 x i8> @abs_16b(ptr %A) nounwind { 987; CHECK-LABEL: abs_16b: 988; CHECK: // %bb.0: 989; CHECK-NEXT: ldr q0, [x0] 990; CHECK-NEXT: abs.16b v0, v0 991; CHECK-NEXT: ret 992 %tmp1 = load <16 x i8>, ptr %A 993 %tmp3 = call <16 x i8> @llvm.aarch64.neon.abs.v16i8(<16 x i8> %tmp1) 994 ret <16 x i8> %tmp3 995} 996 997define <4 x i16> @abs_4h(ptr %A) nounwind { 998; CHECK-LABEL: abs_4h: 999; CHECK: // %bb.0: 1000; CHECK-NEXT: ldr d0, [x0] 1001; CHECK-NEXT: abs.4h v0, v0 1002; CHECK-NEXT: ret 1003 %tmp1 = load <4 x i16>, ptr %A 1004 %tmp3 = call <4 x i16> @llvm.aarch64.neon.abs.v4i16(<4 x i16> %tmp1) 1005 ret <4 x i16> %tmp3 1006} 1007 1008define <8 x i16> @abs_8h(ptr %A) nounwind { 1009; CHECK-LABEL: abs_8h: 1010; CHECK: // %bb.0: 1011; CHECK-NEXT: ldr q0, [x0] 1012; CHECK-NEXT: abs.8h v0, v0 1013; CHECK-NEXT: ret 1014 %tmp1 = load <8 x i16>, ptr %A 1015 %tmp3 = call <8 x i16> @llvm.aarch64.neon.abs.v8i16(<8 x i16> %tmp1) 1016 ret <8 x i16> %tmp3 1017} 1018 1019define <2 x i32> @abs_2s(ptr %A) nounwind { 1020; CHECK-LABEL: abs_2s: 1021; CHECK: // %bb.0: 1022; CHECK-NEXT: ldr d0, [x0] 1023; CHECK-NEXT: abs.2s v0, v0 1024; CHECK-NEXT: ret 1025 %tmp1 = load <2 x i32>, ptr %A 1026 %tmp3 = call <2 x i32> @llvm.aarch64.neon.abs.v2i32(<2 x i32> %tmp1) 1027 ret <2 x i32> %tmp3 1028} 1029 1030define <4 x i32> @abs_4s(ptr %A) nounwind { 1031; CHECK-LABEL: abs_4s: 1032; CHECK: // %bb.0: 1033; CHECK-NEXT: ldr q0, [x0] 1034; CHECK-NEXT: abs.4s v0, v0 1035; CHECK-NEXT: ret 1036 %tmp1 = load <4 x i32>, ptr %A 1037 %tmp3 = call <4 x i32> @llvm.aarch64.neon.abs.v4i32(<4 x i32> %tmp1) 1038 ret <4 x i32> %tmp3 1039} 1040 1041define <1 x i64> @abs_1d(<1 x i64> %A) nounwind { 1042; CHECK-SD-LABEL: abs_1d: 1043; CHECK-SD: // %bb.0: 1044; CHECK-SD-NEXT: abs d0, d0 1045; CHECK-SD-NEXT: ret 1046; 1047; CHECK-GI-LABEL: abs_1d: 1048; CHECK-GI: // %bb.0: 1049; CHECK-GI-NEXT: fmov x8, d0 1050; CHECK-GI-NEXT: fmov x9, d0 1051; CHECK-GI-NEXT: neg x8, x8 1052; CHECK-GI-NEXT: cmp x9, #0 1053; CHECK-GI-NEXT: fmov d1, x8 1054; CHECK-GI-NEXT: fcsel d0, d0, d1, gt 1055; CHECK-GI-NEXT: ret 1056 %abs = call <1 x i64> @llvm.aarch64.neon.abs.v1i64(<1 x i64> %A) 1057 ret <1 x i64> %abs 1058} 1059 1060define i64 @abs_1d_honestly(i64 %A) nounwind { 1061; CHECK-SD-LABEL: abs_1d_honestly: 1062; CHECK-SD: // %bb.0: 1063; CHECK-SD-NEXT: fmov d0, x0 1064; CHECK-SD-NEXT: abs d0, d0 1065; CHECK-SD-NEXT: fmov x0, d0 1066; CHECK-SD-NEXT: ret 1067; 1068; CHECK-GI-LABEL: abs_1d_honestly: 1069; CHECK-GI: // %bb.0: 1070; CHECK-GI-NEXT: cmp x0, #0 1071; CHECK-GI-NEXT: cneg x0, x0, le 1072; CHECK-GI-NEXT: ret 1073 %abs = call i64 @llvm.aarch64.neon.abs.i64(i64 %A) 1074 ret i64 %abs 1075} 1076 1077declare <8 x i8> @llvm.aarch64.neon.abs.v8i8(<8 x i8>) nounwind readnone 1078declare <16 x i8> @llvm.aarch64.neon.abs.v16i8(<16 x i8>) nounwind readnone 1079declare <4 x i16> @llvm.aarch64.neon.abs.v4i16(<4 x i16>) nounwind readnone 1080declare <8 x i16> @llvm.aarch64.neon.abs.v8i16(<8 x i16>) nounwind readnone 1081declare <2 x i32> @llvm.aarch64.neon.abs.v2i32(<2 x i32>) nounwind readnone 1082declare <4 x i32> @llvm.aarch64.neon.abs.v4i32(<4 x i32>) nounwind readnone 1083declare <1 x i64> @llvm.aarch64.neon.abs.v1i64(<1 x i64>) nounwind readnone 1084declare i64 @llvm.aarch64.neon.abs.i64(i64) nounwind readnone 1085 1086define <8 x i16> @sabal8h(ptr %A, ptr %B, ptr %C) nounwind { 1087; CHECK-LABEL: sabal8h: 1088; CHECK: // %bb.0: 1089; CHECK-NEXT: ldr d1, [x0] 1090; CHECK-NEXT: ldr d2, [x1] 1091; CHECK-NEXT: ldr q0, [x2] 1092; CHECK-NEXT: sabal.8h v0, v1, v2 1093; CHECK-NEXT: ret 1094 %tmp1 = load <8 x i8>, ptr %A 1095 %tmp2 = load <8 x i8>, ptr %B 1096 %tmp3 = load <8 x i16>, ptr %C 1097 %tmp4 = call <8 x i8> @llvm.aarch64.neon.sabd.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2) 1098 %tmp4.1 = zext <8 x i8> %tmp4 to <8 x i16> 1099 %tmp5 = add <8 x i16> %tmp3, %tmp4.1 1100 ret <8 x i16> %tmp5 1101} 1102 1103define <4 x i32> @sabal4s(ptr %A, ptr %B, ptr %C) nounwind { 1104; CHECK-LABEL: sabal4s: 1105; CHECK: // %bb.0: 1106; CHECK-NEXT: ldr d1, [x0] 1107; CHECK-NEXT: ldr d2, [x1] 1108; CHECK-NEXT: ldr q0, [x2] 1109; CHECK-NEXT: sabal.4s v0, v1, v2 1110; CHECK-NEXT: ret 1111 %tmp1 = load <4 x i16>, ptr %A 1112 %tmp2 = load <4 x i16>, ptr %B 1113 %tmp3 = load <4 x i32>, ptr %C 1114 %tmp4 = call <4 x i16> @llvm.aarch64.neon.sabd.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2) 1115 %tmp4.1 = zext <4 x i16> %tmp4 to <4 x i32> 1116 %tmp5 = add <4 x i32> %tmp3, %tmp4.1 1117 ret <4 x i32> %tmp5 1118} 1119 1120define <2 x i64> @sabal2d(ptr %A, ptr %B, ptr %C) nounwind { 1121; CHECK-LABEL: sabal2d: 1122; CHECK: // %bb.0: 1123; CHECK-NEXT: ldr d1, [x0] 1124; CHECK-NEXT: ldr d2, [x1] 1125; CHECK-NEXT: ldr q0, [x2] 1126; CHECK-NEXT: sabal.2d v0, v1, v2 1127; CHECK-NEXT: ret 1128 %tmp1 = load <2 x i32>, ptr %A 1129 %tmp2 = load <2 x i32>, ptr %B 1130 %tmp3 = load <2 x i64>, ptr %C 1131 %tmp4 = call <2 x i32> @llvm.aarch64.neon.sabd.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2) 1132 %tmp4.1 = zext <2 x i32> %tmp4 to <2 x i64> 1133 %tmp4.1.1 = zext <2 x i32> %tmp4 to <2 x i64> 1134 %tmp5 = add <2 x i64> %tmp3, %tmp4.1 1135 ret <2 x i64> %tmp5 1136} 1137 1138define <8 x i16> @sabal2_8h(ptr %A, ptr %B, ptr %C) nounwind { 1139; CHECK-SD-LABEL: sabal2_8h: 1140; CHECK-SD: // %bb.0: 1141; CHECK-SD-NEXT: ldr q0, [x2] 1142; CHECK-SD-NEXT: ldr d1, [x0, #8] 1143; CHECK-SD-NEXT: ldr d2, [x1, #8] 1144; CHECK-SD-NEXT: sabal.8h v0, v1, v2 1145; CHECK-SD-NEXT: ret 1146; 1147; CHECK-GI-LABEL: sabal2_8h: 1148; CHECK-GI: // %bb.0: 1149; CHECK-GI-NEXT: ldr q1, [x0] 1150; CHECK-GI-NEXT: ldr q2, [x1] 1151; CHECK-GI-NEXT: ldr q0, [x2] 1152; CHECK-GI-NEXT: sabal2.8h v0, v1, v2 1153; CHECK-GI-NEXT: ret 1154 %load1 = load <16 x i8>, ptr %A 1155 %load2 = load <16 x i8>, ptr %B 1156 %tmp3 = load <8 x i16>, ptr %C 1157 %tmp1 = shufflevector <16 x i8> %load1, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> 1158 %tmp2 = shufflevector <16 x i8> %load2, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> 1159 %tmp4 = call <8 x i8> @llvm.aarch64.neon.sabd.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2) 1160 %tmp4.1 = zext <8 x i8> %tmp4 to <8 x i16> 1161 %tmp5 = add <8 x i16> %tmp3, %tmp4.1 1162 ret <8 x i16> %tmp5 1163} 1164 1165define <4 x i32> @sabal2_4s(ptr %A, ptr %B, ptr %C) nounwind { 1166; CHECK-SD-LABEL: sabal2_4s: 1167; CHECK-SD: // %bb.0: 1168; CHECK-SD-NEXT: ldr q0, [x2] 1169; CHECK-SD-NEXT: ldr d1, [x0, #8] 1170; CHECK-SD-NEXT: ldr d2, [x1, #8] 1171; CHECK-SD-NEXT: sabal.4s v0, v1, v2 1172; CHECK-SD-NEXT: ret 1173; 1174; CHECK-GI-LABEL: sabal2_4s: 1175; CHECK-GI: // %bb.0: 1176; CHECK-GI-NEXT: ldr q1, [x0] 1177; CHECK-GI-NEXT: ldr q2, [x1] 1178; CHECK-GI-NEXT: ldr q0, [x2] 1179; CHECK-GI-NEXT: sabal2.4s v0, v1, v2 1180; CHECK-GI-NEXT: ret 1181 %load1 = load <8 x i16>, ptr %A 1182 %load2 = load <8 x i16>, ptr %B 1183 %tmp3 = load <4 x i32>, ptr %C 1184 %tmp1 = shufflevector <8 x i16> %load1, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7> 1185 %tmp2 = shufflevector <8 x i16> %load2, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7> 1186 %tmp4 = call <4 x i16> @llvm.aarch64.neon.sabd.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2) 1187 %tmp4.1 = zext <4 x i16> %tmp4 to <4 x i32> 1188 %tmp5 = add <4 x i32> %tmp3, %tmp4.1 1189 ret <4 x i32> %tmp5 1190} 1191 1192define <2 x i64> @sabal2_2d(ptr %A, ptr %B, ptr %C) nounwind { 1193; CHECK-SD-LABEL: sabal2_2d: 1194; CHECK-SD: // %bb.0: 1195; CHECK-SD-NEXT: ldr q0, [x2] 1196; CHECK-SD-NEXT: ldr d1, [x0, #8] 1197; CHECK-SD-NEXT: ldr d2, [x1, #8] 1198; CHECK-SD-NEXT: sabal.2d v0, v1, v2 1199; CHECK-SD-NEXT: ret 1200; 1201; CHECK-GI-LABEL: sabal2_2d: 1202; CHECK-GI: // %bb.0: 1203; CHECK-GI-NEXT: ldr q1, [x0] 1204; CHECK-GI-NEXT: ldr q2, [x1] 1205; CHECK-GI-NEXT: ldr q0, [x2] 1206; CHECK-GI-NEXT: sabal2.2d v0, v1, v2 1207; CHECK-GI-NEXT: ret 1208 %load1 = load <4 x i32>, ptr %A 1209 %load2 = load <4 x i32>, ptr %B 1210 %tmp3 = load <2 x i64>, ptr %C 1211 %tmp1 = shufflevector <4 x i32> %load1, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 1212 %tmp2 = shufflevector <4 x i32> %load2, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 1213 %tmp4 = call <2 x i32> @llvm.aarch64.neon.sabd.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2) 1214 %tmp4.1 = zext <2 x i32> %tmp4 to <2 x i64> 1215 %tmp5 = add <2 x i64> %tmp3, %tmp4.1 1216 ret <2 x i64> %tmp5 1217} 1218 1219define <8 x i16> @uabal8h(ptr %A, ptr %B, ptr %C) nounwind { 1220; CHECK-LABEL: uabal8h: 1221; CHECK: // %bb.0: 1222; CHECK-NEXT: ldr d1, [x0] 1223; CHECK-NEXT: ldr d2, [x1] 1224; CHECK-NEXT: ldr q0, [x2] 1225; CHECK-NEXT: uabal.8h v0, v1, v2 1226; CHECK-NEXT: ret 1227 %tmp1 = load <8 x i8>, ptr %A 1228 %tmp2 = load <8 x i8>, ptr %B 1229 %tmp3 = load <8 x i16>, ptr %C 1230 %tmp4 = call <8 x i8> @llvm.aarch64.neon.uabd.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2) 1231 %tmp4.1 = zext <8 x i8> %tmp4 to <8 x i16> 1232 %tmp5 = add <8 x i16> %tmp3, %tmp4.1 1233 ret <8 x i16> %tmp5 1234} 1235 1236define <4 x i32> @uabal4s(ptr %A, ptr %B, ptr %C) nounwind { 1237; CHECK-LABEL: uabal4s: 1238; CHECK: // %bb.0: 1239; CHECK-NEXT: ldr d1, [x0] 1240; CHECK-NEXT: ldr d2, [x1] 1241; CHECK-NEXT: ldr q0, [x2] 1242; CHECK-NEXT: uabal.4s v0, v1, v2 1243; CHECK-NEXT: ret 1244 %tmp1 = load <4 x i16>, ptr %A 1245 %tmp2 = load <4 x i16>, ptr %B 1246 %tmp3 = load <4 x i32>, ptr %C 1247 %tmp4 = call <4 x i16> @llvm.aarch64.neon.uabd.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2) 1248 %tmp4.1 = zext <4 x i16> %tmp4 to <4 x i32> 1249 %tmp5 = add <4 x i32> %tmp3, %tmp4.1 1250 ret <4 x i32> %tmp5 1251} 1252 1253define <2 x i64> @uabal2d(ptr %A, ptr %B, ptr %C) nounwind { 1254; CHECK-LABEL: uabal2d: 1255; CHECK: // %bb.0: 1256; CHECK-NEXT: ldr d1, [x0] 1257; CHECK-NEXT: ldr d2, [x1] 1258; CHECK-NEXT: ldr q0, [x2] 1259; CHECK-NEXT: uabal.2d v0, v1, v2 1260; CHECK-NEXT: ret 1261 %tmp1 = load <2 x i32>, ptr %A 1262 %tmp2 = load <2 x i32>, ptr %B 1263 %tmp3 = load <2 x i64>, ptr %C 1264 %tmp4 = call <2 x i32> @llvm.aarch64.neon.uabd.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2) 1265 %tmp4.1 = zext <2 x i32> %tmp4 to <2 x i64> 1266 %tmp5 = add <2 x i64> %tmp3, %tmp4.1 1267 ret <2 x i64> %tmp5 1268} 1269 1270define <8 x i16> @uabal2_8h(ptr %A, ptr %B, ptr %C) nounwind { 1271; CHECK-SD-LABEL: uabal2_8h: 1272; CHECK-SD: // %bb.0: 1273; CHECK-SD-NEXT: ldr q0, [x2] 1274; CHECK-SD-NEXT: ldr d1, [x0, #8] 1275; CHECK-SD-NEXT: ldr d2, [x1, #8] 1276; CHECK-SD-NEXT: uabal.8h v0, v1, v2 1277; CHECK-SD-NEXT: ret 1278; 1279; CHECK-GI-LABEL: uabal2_8h: 1280; CHECK-GI: // %bb.0: 1281; CHECK-GI-NEXT: ldr q1, [x0] 1282; CHECK-GI-NEXT: ldr q2, [x1] 1283; CHECK-GI-NEXT: ldr q0, [x2] 1284; CHECK-GI-NEXT: uabal2.8h v0, v1, v2 1285; CHECK-GI-NEXT: ret 1286 %load1 = load <16 x i8>, ptr %A 1287 %load2 = load <16 x i8>, ptr %B 1288 %tmp3 = load <8 x i16>, ptr %C 1289 %tmp1 = shufflevector <16 x i8> %load1, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> 1290 %tmp2 = shufflevector <16 x i8> %load2, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> 1291 %tmp4 = call <8 x i8> @llvm.aarch64.neon.uabd.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2) 1292 %tmp4.1 = zext <8 x i8> %tmp4 to <8 x i16> 1293 %tmp5 = add <8 x i16> %tmp3, %tmp4.1 1294 ret <8 x i16> %tmp5 1295} 1296 1297define <4 x i32> @uabal2_4s(ptr %A, ptr %B, ptr %C) nounwind { 1298; CHECK-SD-LABEL: uabal2_4s: 1299; CHECK-SD: // %bb.0: 1300; CHECK-SD-NEXT: ldr q0, [x2] 1301; CHECK-SD-NEXT: ldr d1, [x0, #8] 1302; CHECK-SD-NEXT: ldr d2, [x1, #8] 1303; CHECK-SD-NEXT: uabal.4s v0, v1, v2 1304; CHECK-SD-NEXT: ret 1305; 1306; CHECK-GI-LABEL: uabal2_4s: 1307; CHECK-GI: // %bb.0: 1308; CHECK-GI-NEXT: ldr q1, [x0] 1309; CHECK-GI-NEXT: ldr q2, [x1] 1310; CHECK-GI-NEXT: ldr q0, [x2] 1311; CHECK-GI-NEXT: uabal2.4s v0, v1, v2 1312; CHECK-GI-NEXT: ret 1313 %load1 = load <8 x i16>, ptr %A 1314 %load2 = load <8 x i16>, ptr %B 1315 %tmp3 = load <4 x i32>, ptr %C 1316 %tmp1 = shufflevector <8 x i16> %load1, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7> 1317 %tmp2 = shufflevector <8 x i16> %load2, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7> 1318 %tmp4 = call <4 x i16> @llvm.aarch64.neon.uabd.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2) 1319 %tmp4.1 = zext <4 x i16> %tmp4 to <4 x i32> 1320 %tmp5 = add <4 x i32> %tmp3, %tmp4.1 1321 ret <4 x i32> %tmp5 1322} 1323 1324define <2 x i64> @uabal2_2d(ptr %A, ptr %B, ptr %C) nounwind { 1325; CHECK-SD-LABEL: uabal2_2d: 1326; CHECK-SD: // %bb.0: 1327; CHECK-SD-NEXT: ldr q0, [x2] 1328; CHECK-SD-NEXT: ldr d1, [x0, #8] 1329; CHECK-SD-NEXT: ldr d2, [x1, #8] 1330; CHECK-SD-NEXT: uabal.2d v0, v1, v2 1331; CHECK-SD-NEXT: ret 1332; 1333; CHECK-GI-LABEL: uabal2_2d: 1334; CHECK-GI: // %bb.0: 1335; CHECK-GI-NEXT: ldr q1, [x0] 1336; CHECK-GI-NEXT: ldr q2, [x1] 1337; CHECK-GI-NEXT: ldr q0, [x2] 1338; CHECK-GI-NEXT: uabal2.2d v0, v1, v2 1339; CHECK-GI-NEXT: ret 1340 %load1 = load <4 x i32>, ptr %A 1341 %load2 = load <4 x i32>, ptr %B 1342 %tmp3 = load <2 x i64>, ptr %C 1343 %tmp1 = shufflevector <4 x i32> %load1, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 1344 %tmp2 = shufflevector <4 x i32> %load2, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 1345 %tmp4 = call <2 x i32> @llvm.aarch64.neon.uabd.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2) 1346 %tmp4.1 = zext <2 x i32> %tmp4 to <2 x i64> 1347 %tmp5 = add <2 x i64> %tmp3, %tmp4.1 1348 ret <2 x i64> %tmp5 1349} 1350 1351define <8 x i8> @saba_8b(ptr %A, ptr %B, ptr %C) nounwind { 1352; CHECK-LABEL: saba_8b: 1353; CHECK: // %bb.0: 1354; CHECK-NEXT: ldr d1, [x0] 1355; CHECK-NEXT: ldr d2, [x1] 1356; CHECK-NEXT: ldr d0, [x2] 1357; CHECK-NEXT: saba.8b v0, v1, v2 1358; CHECK-NEXT: ret 1359 %tmp1 = load <8 x i8>, ptr %A 1360 %tmp2 = load <8 x i8>, ptr %B 1361 %tmp3 = call <8 x i8> @llvm.aarch64.neon.sabd.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2) 1362 %tmp4 = load <8 x i8>, ptr %C 1363 %tmp5 = add <8 x i8> %tmp3, %tmp4 1364 ret <8 x i8> %tmp5 1365} 1366 1367define <16 x i8> @saba_16b(ptr %A, ptr %B, ptr %C) nounwind { 1368; CHECK-LABEL: saba_16b: 1369; CHECK: // %bb.0: 1370; CHECK-NEXT: ldr q1, [x0] 1371; CHECK-NEXT: ldr q2, [x1] 1372; CHECK-NEXT: ldr q0, [x2] 1373; CHECK-NEXT: saba.16b v0, v1, v2 1374; CHECK-NEXT: ret 1375 %tmp1 = load <16 x i8>, ptr %A 1376 %tmp2 = load <16 x i8>, ptr %B 1377 %tmp3 = call <16 x i8> @llvm.aarch64.neon.sabd.v16i8(<16 x i8> %tmp1, <16 x i8> %tmp2) 1378 %tmp4 = load <16 x i8>, ptr %C 1379 %tmp5 = add <16 x i8> %tmp3, %tmp4 1380 ret <16 x i8> %tmp5 1381} 1382 1383define <4 x i16> @saba_4h(ptr %A, ptr %B, ptr %C) nounwind { 1384; CHECK-LABEL: saba_4h: 1385; CHECK: // %bb.0: 1386; CHECK-NEXT: ldr d1, [x0] 1387; CHECK-NEXT: ldr d2, [x1] 1388; CHECK-NEXT: ldr d0, [x2] 1389; CHECK-NEXT: saba.4h v0, v1, v2 1390; CHECK-NEXT: ret 1391 %tmp1 = load <4 x i16>, ptr %A 1392 %tmp2 = load <4 x i16>, ptr %B 1393 %tmp3 = call <4 x i16> @llvm.aarch64.neon.sabd.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2) 1394 %tmp4 = load <4 x i16>, ptr %C 1395 %tmp5 = add <4 x i16> %tmp3, %tmp4 1396 ret <4 x i16> %tmp5 1397} 1398 1399define <8 x i16> @saba_8h(ptr %A, ptr %B, ptr %C) nounwind { 1400; CHECK-LABEL: saba_8h: 1401; CHECK: // %bb.0: 1402; CHECK-NEXT: ldr q1, [x0] 1403; CHECK-NEXT: ldr q2, [x1] 1404; CHECK-NEXT: ldr q0, [x2] 1405; CHECK-NEXT: saba.8h v0, v1, v2 1406; CHECK-NEXT: ret 1407 %tmp1 = load <8 x i16>, ptr %A 1408 %tmp2 = load <8 x i16>, ptr %B 1409 %tmp3 = call <8 x i16> @llvm.aarch64.neon.sabd.v8i16(<8 x i16> %tmp1, <8 x i16> %tmp2) 1410 %tmp4 = load <8 x i16>, ptr %C 1411 %tmp5 = add <8 x i16> %tmp3, %tmp4 1412 ret <8 x i16> %tmp5 1413} 1414 1415define <2 x i32> @saba_2s(ptr %A, ptr %B, ptr %C) nounwind { 1416; CHECK-LABEL: saba_2s: 1417; CHECK: // %bb.0: 1418; CHECK-NEXT: ldr d1, [x0] 1419; CHECK-NEXT: ldr d2, [x1] 1420; CHECK-NEXT: ldr d0, [x2] 1421; CHECK-NEXT: saba.2s v0, v1, v2 1422; CHECK-NEXT: ret 1423 %tmp1 = load <2 x i32>, ptr %A 1424 %tmp2 = load <2 x i32>, ptr %B 1425 %tmp3 = call <2 x i32> @llvm.aarch64.neon.sabd.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2) 1426 %tmp4 = load <2 x i32>, ptr %C 1427 %tmp5 = add <2 x i32> %tmp3, %tmp4 1428 ret <2 x i32> %tmp5 1429} 1430 1431define <4 x i32> @saba_4s(ptr %A, ptr %B, ptr %C) nounwind { 1432; CHECK-LABEL: saba_4s: 1433; CHECK: // %bb.0: 1434; CHECK-NEXT: ldr q1, [x0] 1435; CHECK-NEXT: ldr q2, [x1] 1436; CHECK-NEXT: ldr q0, [x2] 1437; CHECK-NEXT: saba.4s v0, v1, v2 1438; CHECK-NEXT: ret 1439 %tmp1 = load <4 x i32>, ptr %A 1440 %tmp2 = load <4 x i32>, ptr %B 1441 %tmp3 = call <4 x i32> @llvm.aarch64.neon.sabd.v4i32(<4 x i32> %tmp1, <4 x i32> %tmp2) 1442 %tmp4 = load <4 x i32>, ptr %C 1443 %tmp5 = add <4 x i32> %tmp3, %tmp4 1444 ret <4 x i32> %tmp5 1445} 1446 1447define <8 x i8> @uaba_8b(ptr %A, ptr %B, ptr %C) nounwind { 1448; CHECK-LABEL: uaba_8b: 1449; CHECK: // %bb.0: 1450; CHECK-NEXT: ldr d1, [x0] 1451; CHECK-NEXT: ldr d2, [x1] 1452; CHECK-NEXT: ldr d0, [x2] 1453; CHECK-NEXT: uaba.8b v0, v1, v2 1454; CHECK-NEXT: ret 1455 %tmp1 = load <8 x i8>, ptr %A 1456 %tmp2 = load <8 x i8>, ptr %B 1457 %tmp3 = call <8 x i8> @llvm.aarch64.neon.uabd.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2) 1458 %tmp4 = load <8 x i8>, ptr %C 1459 %tmp5 = add <8 x i8> %tmp3, %tmp4 1460 ret <8 x i8> %tmp5 1461} 1462 1463define <16 x i8> @uaba_16b(ptr %A, ptr %B, ptr %C) nounwind { 1464; CHECK-LABEL: uaba_16b: 1465; CHECK: // %bb.0: 1466; CHECK-NEXT: ldr q1, [x0] 1467; CHECK-NEXT: ldr q2, [x1] 1468; CHECK-NEXT: ldr q0, [x2] 1469; CHECK-NEXT: uaba.16b v0, v1, v2 1470; CHECK-NEXT: ret 1471 %tmp1 = load <16 x i8>, ptr %A 1472 %tmp2 = load <16 x i8>, ptr %B 1473 %tmp3 = call <16 x i8> @llvm.aarch64.neon.uabd.v16i8(<16 x i8> %tmp1, <16 x i8> %tmp2) 1474 %tmp4 = load <16 x i8>, ptr %C 1475 %tmp5 = add <16 x i8> %tmp3, %tmp4 1476 ret <16 x i8> %tmp5 1477} 1478 1479define <4 x i16> @uaba_4h(ptr %A, ptr %B, ptr %C) nounwind { 1480; CHECK-LABEL: uaba_4h: 1481; CHECK: // %bb.0: 1482; CHECK-NEXT: ldr d1, [x0] 1483; CHECK-NEXT: ldr d2, [x1] 1484; CHECK-NEXT: ldr d0, [x2] 1485; CHECK-NEXT: uaba.4h v0, v1, v2 1486; CHECK-NEXT: ret 1487 %tmp1 = load <4 x i16>, ptr %A 1488 %tmp2 = load <4 x i16>, ptr %B 1489 %tmp3 = call <4 x i16> @llvm.aarch64.neon.uabd.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2) 1490 %tmp4 = load <4 x i16>, ptr %C 1491 %tmp5 = add <4 x i16> %tmp3, %tmp4 1492 ret <4 x i16> %tmp5 1493} 1494 1495define <8 x i16> @uaba_8h(ptr %A, ptr %B, ptr %C) nounwind { 1496; CHECK-LABEL: uaba_8h: 1497; CHECK: // %bb.0: 1498; CHECK-NEXT: ldr q1, [x0] 1499; CHECK-NEXT: ldr q2, [x1] 1500; CHECK-NEXT: ldr q0, [x2] 1501; CHECK-NEXT: uaba.8h v0, v1, v2 1502; CHECK-NEXT: ret 1503 %tmp1 = load <8 x i16>, ptr %A 1504 %tmp2 = load <8 x i16>, ptr %B 1505 %tmp3 = call <8 x i16> @llvm.aarch64.neon.uabd.v8i16(<8 x i16> %tmp1, <8 x i16> %tmp2) 1506 %tmp4 = load <8 x i16>, ptr %C 1507 %tmp5 = add <8 x i16> %tmp3, %tmp4 1508 ret <8 x i16> %tmp5 1509} 1510 1511define <2 x i32> @uaba_2s(ptr %A, ptr %B, ptr %C) nounwind { 1512; CHECK-LABEL: uaba_2s: 1513; CHECK: // %bb.0: 1514; CHECK-NEXT: ldr d1, [x0] 1515; CHECK-NEXT: ldr d2, [x1] 1516; CHECK-NEXT: ldr d0, [x2] 1517; CHECK-NEXT: uaba.2s v0, v1, v2 1518; CHECK-NEXT: ret 1519 %tmp1 = load <2 x i32>, ptr %A 1520 %tmp2 = load <2 x i32>, ptr %B 1521 %tmp3 = call <2 x i32> @llvm.aarch64.neon.uabd.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2) 1522 %tmp4 = load <2 x i32>, ptr %C 1523 %tmp5 = add <2 x i32> %tmp3, %tmp4 1524 ret <2 x i32> %tmp5 1525} 1526 1527define <4 x i32> @uaba_4s(ptr %A, ptr %B, ptr %C) nounwind { 1528; CHECK-LABEL: uaba_4s: 1529; CHECK: // %bb.0: 1530; CHECK-NEXT: ldr q1, [x0] 1531; CHECK-NEXT: ldr q2, [x1] 1532; CHECK-NEXT: ldr q0, [x2] 1533; CHECK-NEXT: uaba.4s v0, v1, v2 1534; CHECK-NEXT: ret 1535 %tmp1 = load <4 x i32>, ptr %A 1536 %tmp2 = load <4 x i32>, ptr %B 1537 %tmp3 = call <4 x i32> @llvm.aarch64.neon.uabd.v4i32(<4 x i32> %tmp1, <4 x i32> %tmp2) 1538 %tmp4 = load <4 x i32>, ptr %C 1539 %tmp5 = add <4 x i32> %tmp3, %tmp4 1540 ret <4 x i32> %tmp5 1541} 1542 1543; Scalar FABD 1544define float @fabds(float %a, float %b) nounwind { 1545; CHECK-LABEL: fabds: 1546; CHECK: // %bb.0: 1547; CHECK-NEXT: fabd s0, s0, s1 1548; CHECK-NEXT: ret 1549 %vabd.i = tail call float @llvm.aarch64.sisd.fabd.f32(float %a, float %b) nounwind 1550 ret float %vabd.i 1551} 1552 1553define double @fabdd(double %a, double %b) nounwind { 1554; CHECK-LABEL: fabdd: 1555; CHECK: // %bb.0: 1556; CHECK-NEXT: fabd d0, d0, d1 1557; CHECK-NEXT: ret 1558 %vabd.i = tail call double @llvm.aarch64.sisd.fabd.f64(double %a, double %b) nounwind 1559 ret double %vabd.i 1560} 1561 1562declare double @llvm.aarch64.sisd.fabd.f64(double, double) nounwind readnone 1563declare float @llvm.aarch64.sisd.fabd.f32(float, float) nounwind readnone 1564 1565define float @fabds_from_fsub_fabs(float %a, float %b) nounwind { 1566; CHECK-LABEL: fabds_from_fsub_fabs: 1567; CHECK: // %bb.0: 1568; CHECK-NEXT: fabd s0, s0, s1 1569; CHECK-NEXT: ret 1570 %sub = fsub float %a, %b 1571 %abs = tail call float @llvm.fabs.f32(float %sub) 1572 ret float %abs 1573} 1574 1575define double @fabdd_from_fsub_fabs(double %a, double %b) nounwind { 1576; CHECK-LABEL: fabdd_from_fsub_fabs: 1577; CHECK: // %bb.0: 1578; CHECK-NEXT: fabd d0, d0, d1 1579; CHECK-NEXT: ret 1580 %sub = fsub double %a, %b 1581 %abs = tail call double @llvm.fabs.f64(double %sub) 1582 ret double %abs 1583} 1584 1585declare float @llvm.fabs.f32(float) nounwind readnone 1586declare double @llvm.fabs.f64(double) nounwind readnone 1587 1588define <2 x i64> @uabdl_from_extract_dup(<4 x i32> %lhs, i32 %rhs) { 1589; CHECK-LABEL: uabdl_from_extract_dup: 1590; CHECK: // %bb.0: 1591; CHECK-NEXT: dup.2s v1, w0 1592; CHECK-NEXT: uabdl.2d v0, v0, v1 1593; CHECK-NEXT: ret 1594 %rhsvec.tmp = insertelement <2 x i32> undef, i32 %rhs, i32 0 1595 %rhsvec = insertelement <2 x i32> %rhsvec.tmp, i32 %rhs, i32 1 1596 %lhs.high = shufflevector <4 x i32> %lhs, <4 x i32> undef, <2 x i32> <i32 0, i32 1> 1597 %res = tail call <2 x i32> @llvm.aarch64.neon.uabd.v2i32(<2 x i32> %lhs.high, <2 x i32> %rhsvec) nounwind 1598 %res1 = zext <2 x i32> %res to <2 x i64> 1599 ret <2 x i64> %res1 1600} 1601 1602define <2 x i64> @uabdl2_from_extract_dup(<4 x i32> %lhs, i32 %rhs) { 1603; CHECK-SD-LABEL: uabdl2_from_extract_dup: 1604; CHECK-SD: // %bb.0: 1605; CHECK-SD-NEXT: dup.4s v1, w0 1606; CHECK-SD-NEXT: uabdl2.2d v0, v0, v1 1607; CHECK-SD-NEXT: ret 1608; 1609; CHECK-GI-LABEL: uabdl2_from_extract_dup: 1610; CHECK-GI: // %bb.0: 1611; CHECK-GI-NEXT: dup.2s v1, w0 1612; CHECK-GI-NEXT: mov d0, v0[1] 1613; CHECK-GI-NEXT: uabdl.2d v0, v0, v1 1614; CHECK-GI-NEXT: ret 1615 %rhsvec.tmp = insertelement <2 x i32> undef, i32 %rhs, i32 0 1616 %rhsvec = insertelement <2 x i32> %rhsvec.tmp, i32 %rhs, i32 1 1617 %lhs.high = shufflevector <4 x i32> %lhs, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 1618 %res = tail call <2 x i32> @llvm.aarch64.neon.uabd.v2i32(<2 x i32> %lhs.high, <2 x i32> %rhsvec) nounwind 1619 %res1 = zext <2 x i32> %res to <2 x i64> 1620 ret <2 x i64> %res1 1621} 1622 1623define <2 x i64> @sabdl_from_extract_dup(<4 x i32> %lhs, i32 %rhs) { 1624; CHECK-LABEL: sabdl_from_extract_dup: 1625; CHECK: // %bb.0: 1626; CHECK-NEXT: dup.2s v1, w0 1627; CHECK-NEXT: sabdl.2d v0, v0, v1 1628; CHECK-NEXT: ret 1629 %rhsvec.tmp = insertelement <2 x i32> undef, i32 %rhs, i32 0 1630 %rhsvec = insertelement <2 x i32> %rhsvec.tmp, i32 %rhs, i32 1 1631 %lhs.high = shufflevector <4 x i32> %lhs, <4 x i32> undef, <2 x i32> <i32 0, i32 1> 1632 %res = tail call <2 x i32> @llvm.aarch64.neon.sabd.v2i32(<2 x i32> %lhs.high, <2 x i32> %rhsvec) nounwind 1633 %res1 = zext <2 x i32> %res to <2 x i64> 1634 ret <2 x i64> %res1 1635} 1636 1637define <2 x i64> @sabdl2_from_extract_dup(<4 x i32> %lhs, i32 %rhs) { 1638; CHECK-SD-LABEL: sabdl2_from_extract_dup: 1639; CHECK-SD: // %bb.0: 1640; CHECK-SD-NEXT: dup.4s v1, w0 1641; CHECK-SD-NEXT: sabdl2.2d v0, v0, v1 1642; CHECK-SD-NEXT: ret 1643; 1644; CHECK-GI-LABEL: sabdl2_from_extract_dup: 1645; CHECK-GI: // %bb.0: 1646; CHECK-GI-NEXT: dup.2s v1, w0 1647; CHECK-GI-NEXT: mov d0, v0[1] 1648; CHECK-GI-NEXT: sabdl.2d v0, v0, v1 1649; CHECK-GI-NEXT: ret 1650 %rhsvec.tmp = insertelement <2 x i32> undef, i32 %rhs, i32 0 1651 %rhsvec = insertelement <2 x i32> %rhsvec.tmp, i32 %rhs, i32 1 1652 %lhs.high = shufflevector <4 x i32> %lhs, <4 x i32> undef, <2 x i32> <i32 2, i32 3> 1653 %res = tail call <2 x i32> @llvm.aarch64.neon.sabd.v2i32(<2 x i32> %lhs.high, <2 x i32> %rhsvec) nounwind 1654 %res1 = zext <2 x i32> %res to <2 x i64> 1655 ret <2 x i64> %res1 1656} 1657 1658define <2 x i32> @abspattern1(<2 x i32> %a) nounwind { 1659; CHECK-SD-LABEL: abspattern1: 1660; CHECK-SD: // %bb.0: 1661; CHECK-SD-NEXT: abs.2s v0, v0 1662; CHECK-SD-NEXT: ret 1663; 1664; CHECK-GI-LABEL: abspattern1: 1665; CHECK-GI: // %bb.0: 1666; CHECK-GI-NEXT: neg.2s v1, v0 1667; CHECK-GI-NEXT: cmge.2s v2, v0, #0 1668; CHECK-GI-NEXT: bif.8b v0, v1, v2 1669; CHECK-GI-NEXT: ret 1670 %tmp1neg = sub <2 x i32> zeroinitializer, %a 1671 %b = icmp sge <2 x i32> %a, zeroinitializer 1672 %abs = select <2 x i1> %b, <2 x i32> %a, <2 x i32> %tmp1neg 1673 ret <2 x i32> %abs 1674} 1675 1676; For GlobalISel, this generates terrible code until we can pattern match this to abs. 1677define <4 x i16> @abspattern2(<4 x i16> %a) nounwind { 1678; CHECK-SD-LABEL: abspattern2: 1679; CHECK-SD: // %bb.0: 1680; CHECK-SD-NEXT: abs.4h v0, v0 1681; CHECK-SD-NEXT: ret 1682; 1683; CHECK-GI-LABEL: abspattern2: 1684; CHECK-GI: // %bb.0: 1685; CHECK-GI-NEXT: neg.4h v1, v0 1686; CHECK-GI-NEXT: cmgt.4h v2, v0, #0 1687; CHECK-GI-NEXT: bif.8b v0, v1, v2 1688; CHECK-GI-NEXT: ret 1689 %tmp1neg = sub <4 x i16> zeroinitializer, %a 1690 %b = icmp sgt <4 x i16> %a, zeroinitializer 1691 %abs = select <4 x i1> %b, <4 x i16> %a, <4 x i16> %tmp1neg 1692 ret <4 x i16> %abs 1693} 1694 1695define <8 x i8> @abspattern3(<8 x i8> %a) nounwind { 1696; CHECK-SD-LABEL: abspattern3: 1697; CHECK-SD: // %bb.0: 1698; CHECK-SD-NEXT: abs.8b v0, v0 1699; CHECK-SD-NEXT: ret 1700; 1701; CHECK-GI-LABEL: abspattern3: 1702; CHECK-GI: // %bb.0: 1703; CHECK-GI-NEXT: neg.8b v1, v0 1704; CHECK-GI-NEXT: cmlt.8b v2, v0, #0 1705; CHECK-GI-NEXT: bit.8b v0, v1, v2 1706; CHECK-GI-NEXT: ret 1707 %tmp1neg = sub <8 x i8> zeroinitializer, %a 1708 %b = icmp slt <8 x i8> %a, zeroinitializer 1709 %abs = select <8 x i1> %b, <8 x i8> %tmp1neg, <8 x i8> %a 1710 ret <8 x i8> %abs 1711} 1712 1713define <4 x i32> @abspattern4(<4 x i32> %a) nounwind { 1714; CHECK-SD-LABEL: abspattern4: 1715; CHECK-SD: // %bb.0: 1716; CHECK-SD-NEXT: abs.4s v0, v0 1717; CHECK-SD-NEXT: ret 1718; 1719; CHECK-GI-LABEL: abspattern4: 1720; CHECK-GI: // %bb.0: 1721; CHECK-GI-NEXT: neg.4s v1, v0 1722; CHECK-GI-NEXT: cmge.4s v2, v0, #0 1723; CHECK-GI-NEXT: bif.16b v0, v1, v2 1724; CHECK-GI-NEXT: ret 1725 %tmp1neg = sub <4 x i32> zeroinitializer, %a 1726 %b = icmp sge <4 x i32> %a, zeroinitializer 1727 %abs = select <4 x i1> %b, <4 x i32> %a, <4 x i32> %tmp1neg 1728 ret <4 x i32> %abs 1729} 1730 1731define <8 x i16> @abspattern5(<8 x i16> %a) nounwind { 1732; CHECK-SD-LABEL: abspattern5: 1733; CHECK-SD: // %bb.0: 1734; CHECK-SD-NEXT: abs.8h v0, v0 1735; CHECK-SD-NEXT: ret 1736; 1737; CHECK-GI-LABEL: abspattern5: 1738; CHECK-GI: // %bb.0: 1739; CHECK-GI-NEXT: neg.8h v1, v0 1740; CHECK-GI-NEXT: cmgt.8h v2, v0, #0 1741; CHECK-GI-NEXT: bif.16b v0, v1, v2 1742; CHECK-GI-NEXT: ret 1743 %tmp1neg = sub <8 x i16> zeroinitializer, %a 1744 %b = icmp sgt <8 x i16> %a, zeroinitializer 1745 %abs = select <8 x i1> %b, <8 x i16> %a, <8 x i16> %tmp1neg 1746 ret <8 x i16> %abs 1747} 1748 1749define <16 x i8> @abspattern6(<16 x i8> %a) nounwind { 1750; CHECK-SD-LABEL: abspattern6: 1751; CHECK-SD: // %bb.0: 1752; CHECK-SD-NEXT: abs.16b v0, v0 1753; CHECK-SD-NEXT: ret 1754; 1755; CHECK-GI-LABEL: abspattern6: 1756; CHECK-GI: // %bb.0: 1757; CHECK-GI-NEXT: neg.16b v1, v0 1758; CHECK-GI-NEXT: cmlt.16b v2, v0, #0 1759; CHECK-GI-NEXT: bit.16b v0, v1, v2 1760; CHECK-GI-NEXT: ret 1761 %tmp1neg = sub <16 x i8> zeroinitializer, %a 1762 %b = icmp slt <16 x i8> %a, zeroinitializer 1763 %abs = select <16 x i1> %b, <16 x i8> %tmp1neg, <16 x i8> %a 1764 ret <16 x i8> %abs 1765} 1766 1767define <2 x i64> @abspattern7(<2 x i64> %a) nounwind { 1768; CHECK-SD-LABEL: abspattern7: 1769; CHECK-SD: // %bb.0: 1770; CHECK-SD-NEXT: abs.2d v0, v0 1771; CHECK-SD-NEXT: ret 1772; 1773; CHECK-GI-LABEL: abspattern7: 1774; CHECK-GI: // %bb.0: 1775; CHECK-GI-NEXT: neg.2d v1, v0 1776; CHECK-GI-NEXT: cmle.2d v2, v0, #0 1777; CHECK-GI-NEXT: bit.16b v0, v1, v2 1778; CHECK-GI-NEXT: ret 1779 %tmp1neg = sub <2 x i64> zeroinitializer, %a 1780 %b = icmp sle <2 x i64> %a, zeroinitializer 1781 %abs = select <2 x i1> %b, <2 x i64> %tmp1neg, <2 x i64> %a 1782 ret <2 x i64> %abs 1783} 1784 1785define <2 x i64> @uabd_i32(<2 x i32> %a, <2 x i32> %b) { 1786; CHECK-SD-LABEL: uabd_i32: 1787; CHECK-SD: // %bb.0: 1788; CHECK-SD-NEXT: sabdl.2d v0, v0, v1 1789; CHECK-SD-NEXT: ret 1790; 1791; CHECK-GI-LABEL: uabd_i32: 1792; CHECK-GI: // %bb.0: 1793; CHECK-GI-NEXT: ssubl.2d v0, v0, v1 1794; CHECK-GI-NEXT: cmlt.2d v1, v0, #0 1795; CHECK-GI-NEXT: neg.2d v2, v0 1796; CHECK-GI-NEXT: bit.16b v0, v2, v1 1797; CHECK-GI-NEXT: ret 1798 %aext = sext <2 x i32> %a to <2 x i64> 1799 %bext = sext <2 x i32> %b to <2 x i64> 1800 %abdiff = sub nsw <2 x i64> %aext, %bext 1801 %abcmp = icmp slt <2 x i64> %abdiff, zeroinitializer 1802 %ababs = sub nsw <2 x i64> zeroinitializer, %abdiff 1803 %absel = select <2 x i1> %abcmp, <2 x i64> %ababs, <2 x i64> %abdiff 1804 ret <2 x i64> %absel 1805} 1806 1807define <2 x i128> @uabd_i64(<2 x i64> %a, <2 x i64> %b) { 1808; CHECK-LABEL: uabd_i64: 1809; CHECK: // %bb.0: 1810; CHECK-NEXT: cmgt.2d v2, v0, v1 1811; CHECK-NEXT: sub.2d v0, v0, v1 1812; CHECK-NEXT: mov x1, xzr 1813; CHECK-NEXT: mov x3, xzr 1814; CHECK-NEXT: eor.16b v0, v0, v2 1815; CHECK-NEXT: sub.2d v0, v2, v0 1816; CHECK-NEXT: mov.d x2, v0[1] 1817; CHECK-NEXT: fmov x0, d0 1818; CHECK-NEXT: ret 1819 %aext = sext <2 x i64> %a to <2 x i128> 1820 %bext = sext <2 x i64> %b to <2 x i128> 1821 %abdiff = sub nsw <2 x i128> %aext, %bext 1822 %abcmp = icmp slt <2 x i128> %abdiff, zeroinitializer 1823 %ababs = sub nsw <2 x i128> zeroinitializer, %abdiff 1824 %absel = select <2 x i1> %abcmp, <2 x i128> %ababs, <2 x i128> %abdiff 1825 ret <2 x i128> %absel 1826} 1827 1828define <8 x i16> @pr88784(<8 x i8> %l0, <8 x i8> %l1, <8 x i16> %l2) { 1829; CHECK-SD-LABEL: pr88784: 1830; CHECK-SD: // %bb.0: 1831; CHECK-SD-NEXT: usubl.8h v0, v0, v1 1832; CHECK-SD-NEXT: cmlt.8h v1, v2, #0 1833; CHECK-SD-NEXT: ssra.8h v0, v2, #15 1834; CHECK-SD-NEXT: eor.16b v0, v1, v0 1835; CHECK-SD-NEXT: ret 1836; 1837; CHECK-GI-LABEL: pr88784: 1838; CHECK-GI: // %bb.0: 1839; CHECK-GI-NEXT: usubl.8h v0, v0, v1 1840; CHECK-GI-NEXT: sshr.8h v1, v2, #15 1841; CHECK-GI-NEXT: ssra.8h v0, v2, #15 1842; CHECK-GI-NEXT: eor.16b v0, v1, v0 1843; CHECK-GI-NEXT: ret 1844 %l4 = zext <8 x i8> %l0 to <8 x i16> 1845 %l5 = ashr <8 x i16> %l2, <i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15> 1846 %l6 = zext <8 x i8> %l1 to <8 x i16> 1847 %l7 = sub <8 x i16> %l4, %l6 1848 %l8 = add <8 x i16> %l5, %l7 1849 %l9 = xor <8 x i16> %l5, %l8 1850 ret <8 x i16> %l9 1851} 1852 1853define <8 x i16> @pr88784_fixed(<8 x i8> %l0, <8 x i8> %l1, <8 x i16> %l2) { 1854; CHECK-SD-LABEL: pr88784_fixed: 1855; CHECK-SD: // %bb.0: 1856; CHECK-SD-NEXT: uabdl.8h v0, v0, v1 1857; CHECK-SD-NEXT: ret 1858; 1859; CHECK-GI-LABEL: pr88784_fixed: 1860; CHECK-GI: // %bb.0: 1861; CHECK-GI-NEXT: usubl.8h v0, v0, v1 1862; CHECK-GI-NEXT: sshr.8h v1, v0, #15 1863; CHECK-GI-NEXT: ssra.8h v0, v0, #15 1864; CHECK-GI-NEXT: eor.16b v0, v1, v0 1865; CHECK-GI-NEXT: ret 1866 %l4 = zext <8 x i8> %l0 to <8 x i16> 1867 %l6 = zext <8 x i8> %l1 to <8 x i16> 1868 %l7 = sub <8 x i16> %l4, %l6 1869 %l5 = ashr <8 x i16> %l7, <i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15> 1870 %l8 = add <8 x i16> %l5, %l7 1871 %l9 = xor <8 x i16> %l5, %l8 1872 ret <8 x i16> %l9 1873} 1874 1875