; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s --mattr=+complxnum,+neon,+fullfp16 -o - | FileCheck %s ; RUN: llc < %s --mattr=+complxnum,+neon,+fullfp16,+sve -o - | FileCheck %s ; RUN: llc < %s --mattr=+complxnum,+neon,+fullfp16,+sve2 -o - | FileCheck %s target triple = "aarch64" ; Expected to not transform define <2 x half> @complex_add_v2f16(<2 x half> %a, <2 x half> %b) { ; CHECK-LABEL: complex_add_v2f16: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: // kill: def $d1 killed $d1 def $q1 ; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0 ; CHECK-NEXT: mov h2, v0.h[1] ; CHECK-NEXT: mov h3, v1.h[1] ; CHECK-NEXT: fsub h1, h1, h2 ; CHECK-NEXT: fadd h0, h3, h0 ; CHECK-NEXT: mov v1.h[1], v0.h[0] ; CHECK-NEXT: fmov d0, d1 ; CHECK-NEXT: ret entry: %a.real = shufflevector <2 x half> %a, <2 x half> zeroinitializer, <1 x i32> %a.imag = shufflevector <2 x half> %a, <2 x half> zeroinitializer, <1 x i32> %b.real = shufflevector <2 x half> %b, <2 x half> zeroinitializer, <1 x i32> %b.imag = shufflevector <2 x half> %b, <2 x half> zeroinitializer, <1 x i32> %0 = fsub fast <1 x half> %b.real, %a.imag %1 = fadd fast <1 x half> %b.imag, %a.real %interleaved.vec = shufflevector <1 x half> %0, <1 x half> %1, <2 x i32> ret <2 x half> %interleaved.vec } ; Expected to transform define <4 x half> @complex_add_v4f16(<4 x half> %a, <4 x half> %b) { ; CHECK-LABEL: complex_add_v4f16: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: fcadd v0.4h, v1.4h, v0.4h, #90 ; CHECK-NEXT: ret entry: %a.real = shufflevector <4 x half> %a, <4 x half> zeroinitializer, <2 x i32> %a.imag = shufflevector <4 x half> %a, <4 x half> zeroinitializer, <2 x i32> %b.real = shufflevector <4 x half> %b, <4 x half> zeroinitializer, <2 x i32> %b.imag = shufflevector <4 x half> %b, <4 x half> zeroinitializer, <2 x i32> %0 = fsub fast <2 x half> %b.real, %a.imag %1 = fadd fast <2 x half> %b.imag, %a.real %interleaved.vec = shufflevector <2 x half> %0, <2 x half> %1, <4 x i32> ret <4 x half> %interleaved.vec } ; Expected to transform define <8 x half> @complex_add_v8f16(<8 x half> %a, <8 x half> %b) { ; CHECK-LABEL: complex_add_v8f16: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: fcadd v0.8h, v1.8h, v0.8h, #90 ; CHECK-NEXT: ret entry: %a.real = shufflevector <8 x half> %a, <8 x half> zeroinitializer, <4 x i32> %a.imag = shufflevector <8 x half> %a, <8 x half> zeroinitializer, <4 x i32> %b.real = shufflevector <8 x half> %b, <8 x half> zeroinitializer, <4 x i32> %b.imag = shufflevector <8 x half> %b, <8 x half> zeroinitializer, <4 x i32> %0 = fsub fast <4 x half> %b.real, %a.imag %1 = fadd fast <4 x half> %b.imag, %a.real %interleaved.vec = shufflevector <4 x half> %0, <4 x half> %1, <8 x i32> ret <8 x half> %interleaved.vec } ; Expected to transform define <16 x half> @complex_add_v16f16(<16 x half> %a, <16 x half> %b) { ; CHECK-LABEL: complex_add_v16f16: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: fcadd v1.8h, v3.8h, v1.8h, #90 ; CHECK-NEXT: fcadd v0.8h, v2.8h, v0.8h, #90 ; CHECK-NEXT: ret entry: %a.real = shufflevector <16 x half> %a, <16 x half> zeroinitializer, <8 x i32> %a.imag = shufflevector <16 x half> %a, <16 x half> zeroinitializer, <8 x i32> %b.real = shufflevector <16 x half> %b, <16 x half> zeroinitializer, <8 x i32> %b.imag = shufflevector <16 x half> %b, <16 x half> zeroinitializer, <8 x i32> %0 = fsub fast <8 x half> %b.real, %a.imag %1 = fadd fast <8 x half> %b.imag, %a.real %interleaved.vec = shufflevector <8 x half> %0, <8 x half> %1, <16 x i32> ret <16 x half> %interleaved.vec } ; Expected to transform define <32 x half> @complex_add_v32f16(<32 x half> %a, <32 x half> %b) { ; CHECK-LABEL: complex_add_v32f16: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: fcadd v2.8h, v6.8h, v2.8h, #90 ; CHECK-NEXT: fcadd v0.8h, v4.8h, v0.8h, #90 ; CHECK-NEXT: fcadd v1.8h, v5.8h, v1.8h, #90 ; CHECK-NEXT: fcadd v3.8h, v7.8h, v3.8h, #90 ; CHECK-NEXT: ret entry: %a.real = shufflevector <32 x half> %a, <32 x half> zeroinitializer, <16 x i32> %a.imag = shufflevector <32 x half> %a, <32 x half> zeroinitializer, <16 x i32> %b.real = shufflevector <32 x half> %b, <32 x half> zeroinitializer, <16 x i32> %b.imag = shufflevector <32 x half> %b, <32 x half> zeroinitializer, <16 x i32> %0 = fsub fast <16 x half> %b.real, %a.imag %1 = fadd fast <16 x half> %b.imag, %a.real %interleaved.vec = shufflevector <16 x half> %0, <16 x half> %1, <32 x i32> ret <32 x half> %interleaved.vec } ; Expected to transform define <4 x half> @complex_add_v4f16_with_intrinsic(<4 x half> %a, <4 x half> %b) { ; CHECK-LABEL: complex_add_v4f16_with_intrinsic: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: fcadd v0.4h, v1.4h, v0.4h, #90 ; CHECK-NEXT: ret entry: %a.deinterleaved = tail call { <2 x half>, <2 x half> } @llvm.experimental.vector.deinterleave2.v4f16(<4 x half> %a) %a.real = extractvalue { <2 x half>, <2 x half> } %a.deinterleaved, 0 %a.imag = extractvalue { <2 x half>, <2 x half> } %a.deinterleaved, 1 %b.deinterleaved = tail call { <2 x half>, <2 x half> } @llvm.experimental.vector.deinterleave2.v4f16(<4 x half> %b) %b.real = extractvalue { <2 x half>, <2 x half> } %b.deinterleaved, 0 %b.imag = extractvalue { <2 x half>, <2 x half> } %b.deinterleaved, 1 %0 = fsub fast <2 x half> %b.real, %a.imag %1 = fadd fast <2 x half> %b.imag, %a.real %interleaved.vec = tail call <4 x half> @llvm.experimental.vector.interleave2.v4f16(<2 x half> %0, <2 x half> %1) ret <4 x half> %interleaved.vec } ; Expected to transform define <8 x half> @complex_add_v8f16_with_intrinsic(<8 x half> %a, <8 x half> %b) { ; CHECK-LABEL: complex_add_v8f16_with_intrinsic: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: fcadd v0.8h, v1.8h, v0.8h, #90 ; CHECK-NEXT: ret entry: %a.deinterleaved = tail call { <4 x half>, <4 x half> } @llvm.experimental.vector.deinterleave2.v8f16(<8 x half> %a) %a.real = extractvalue { <4 x half>, <4 x half> } %a.deinterleaved, 0 %a.imag = extractvalue { <4 x half>, <4 x half> } %a.deinterleaved, 1 %b.deinterleaved = tail call { <4 x half>, <4 x half> } @llvm.experimental.vector.deinterleave2.v8f16(<8 x half> %b) %b.real = extractvalue { <4 x half>, <4 x half> } %b.deinterleaved, 0 %b.imag = extractvalue { <4 x half>, <4 x half> } %b.deinterleaved, 1 %0 = fsub fast <4 x half> %b.real, %a.imag %1 = fadd fast <4 x half> %b.imag, %a.real %interleaved.vec = tail call <8 x half> @llvm.experimental.vector.interleave2.v8f16(<4 x half> %0, <4 x half> %1) ret <8 x half> %interleaved.vec } ; Expected to transform define <16 x half> @complex_add_v16f16_with_intrinsic(<16 x half> %a, <16 x half> %b) { ; CHECK-LABEL: complex_add_v16f16_with_intrinsic: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: fcadd v1.8h, v3.8h, v1.8h, #90 ; CHECK-NEXT: fcadd v0.8h, v2.8h, v0.8h, #90 ; CHECK-NEXT: ret entry: %a.deinterleaved = tail call { <8 x half>, <8 x half> } @llvm.experimental.vector.deinterleave2.v16f16(<16 x half> %a) %a.real = extractvalue { <8 x half>, <8 x half> } %a.deinterleaved, 0 %a.imag = extractvalue { <8 x half>, <8 x half> } %a.deinterleaved, 1 %b.deinterleaved = tail call { <8 x half>, <8 x half> } @llvm.experimental.vector.deinterleave2.v16f16(<16 x half> %b) %b.real = extractvalue { <8 x half>, <8 x half> } %b.deinterleaved, 0 %b.imag = extractvalue { <8 x half>, <8 x half> } %b.deinterleaved, 1 %0 = fsub fast <8 x half> %b.real, %a.imag %1 = fadd fast <8 x half> %b.imag, %a.real %interleaved.vec = tail call <16 x half> @llvm.experimental.vector.interleave2.v16f16(<8 x half> %0, <8 x half> %1) ret <16 x half> %interleaved.vec } ; Expected not to transform as it is integer define <16 x i16> @complex_add_v16i16(<16 x i16> %a, <16 x i16> %b) { ; CHECK-LABEL: complex_add_v16i16: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: uzp1 v4.8h, v2.8h, v3.8h ; CHECK-NEXT: uzp1 v5.8h, v0.8h, v1.8h ; CHECK-NEXT: uzp2 v0.8h, v0.8h, v1.8h ; CHECK-NEXT: uzp2 v1.8h, v2.8h, v3.8h ; CHECK-NEXT: sub v2.8h, v4.8h, v0.8h ; CHECK-NEXT: add v1.8h, v1.8h, v5.8h ; CHECK-NEXT: zip1 v0.8h, v2.8h, v1.8h ; CHECK-NEXT: zip2 v1.8h, v2.8h, v1.8h ; CHECK-NEXT: ret entry: %a.real = shufflevector <16 x i16> %a, <16 x i16> zeroinitializer, <8 x i32> %a.imag = shufflevector <16 x i16> %a, <16 x i16> zeroinitializer, <8 x i32> %b.real = shufflevector <16 x i16> %b, <16 x i16> zeroinitializer, <8 x i32> %b.imag = shufflevector <16 x i16> %b, <16 x i16> zeroinitializer, <8 x i32> %0 = sub <8 x i16> %b.real, %a.imag %1 = add <8 x i16> %b.imag, %a.real %interleaved.vec = shufflevector <8 x i16> %0, <8 x i16> %1, <16 x i32> ret <16 x i16> %interleaved.vec } declare { <2 x half>, <2 x half> } @llvm.experimental.vector.deinterleave2.v4f16(<4 x half>) declare <4 x half> @llvm.experimental.vector.interleave2.v4f16(<2 x half>, <2 x half>) declare { <4 x half>, <4 x half> } @llvm.experimental.vector.deinterleave2.v8f16(<8 x half>) declare <8 x half> @llvm.experimental.vector.interleave2.v8f16(<4 x half>, <4 x half>) declare { <8 x half>, <8 x half> } @llvm.experimental.vector.deinterleave2.v16f16(<16 x half>) declare <16 x half> @llvm.experimental.vector.interleave2.v16f16(<8 x half>, <8 x half>)