; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 ; RUN: opt -S --passes=complex-deinterleaving %s --mattr=+sve2 -o - | FileCheck %s --check-prefix=CHECK-SVE2 ; RUN: opt -S --passes=complex-deinterleaving %s --mattr=+sve -o - | FileCheck %s --check-prefix=CHECK-SVE ; RUN: opt -S --passes=complex-deinterleaving %s -o - | FileCheck %s --check-prefix=CHECK-NOSVE target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" target triple = "aarch64-none-unknown-elf" define i32 @cdotp_i8_rot0( %a, %b) { ; CHECK-SVE2-LABEL: define i32 @cdotp_i8_rot0( ; CHECK-SVE2-SAME: [[A:%.*]], [[B:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-SVE2-NEXT: [[ENTRY:.*]]: ; CHECK-SVE2-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-SVE2: [[VECTOR_BODY]]: ; CHECK-SVE2-NEXT: [[TMP11:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[TMP10:%.*]], %[[VECTOR_BODY]] ] ; CHECK-SVE2-NEXT: [[TMP1:%.*]] = call @llvm.vector.extract.nxv16i8.nxv32i8( [[A]], i64 0) ; CHECK-SVE2-NEXT: [[TMP2:%.*]] = call @llvm.vector.extract.nxv16i8.nxv32i8( [[B]], i64 0) ; CHECK-SVE2-NEXT: [[TMP3:%.*]] = call @llvm.vector.extract.nxv16i8.nxv32i8( [[A]], i64 16) ; CHECK-SVE2-NEXT: [[TMP4:%.*]] = call @llvm.vector.extract.nxv16i8.nxv32i8( [[B]], i64 16) ; CHECK-SVE2-NEXT: [[TMP5:%.*]] = call @llvm.vector.extract.nxv4i32.nxv8i32( [[TMP11]], i64 0) ; CHECK-SVE2-NEXT: [[TMP6:%.*]] = call @llvm.vector.extract.nxv4i32.nxv8i32( [[TMP11]], i64 4) ; CHECK-SVE2-NEXT: [[TMP7:%.*]] = call @llvm.aarch64.sve.cdot.nxv4i32( [[TMP5]], [[TMP1]], [[TMP2]], i32 0) ; CHECK-SVE2-NEXT: [[TMP8:%.*]] = call @llvm.aarch64.sve.cdot.nxv4i32( [[TMP6]], [[TMP3]], [[TMP4]], i32 0) ; CHECK-SVE2-NEXT: [[TMP9:%.*]] = call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP7]], i64 0) ; CHECK-SVE2-NEXT: [[TMP10]] = call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP9]], [[TMP8]], i64 4) ; CHECK-SVE2-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-SVE2: [[MIDDLE_BLOCK]]: ; CHECK-SVE2-NEXT: [[TMP0:%.*]] = call i32 @llvm.vector.reduce.add.nxv8i32( [[TMP10]]) ; CHECK-SVE2-NEXT: ret i32 [[TMP0]] ; ; CHECK-SVE-LABEL: define i32 @cdotp_i8_rot0( ; CHECK-SVE-SAME: [[A:%.*]], [[B:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-SVE-NEXT: [[ENTRY:.*]]: ; CHECK-SVE-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-SVE: [[VECTOR_BODY]]: ; CHECK-SVE-NEXT: [[VEC_PHI:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[PARTIAL_REDUCE_SUB:%.*]], %[[VECTOR_BODY]] ] ; CHECK-SVE-NEXT: [[A_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[A]]) ; CHECK-SVE-NEXT: [[B_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[B]]) ; CHECK-SVE-NEXT: [[A_REAL:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 0 ; CHECK-SVE-NEXT: [[A_IMAG:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 1 ; CHECK-SVE-NEXT: [[B_REAL:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 0 ; CHECK-SVE-NEXT: [[B_IMAG:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 1 ; CHECK-SVE-NEXT: [[A_REAL_EXT:%.*]] = sext [[A_REAL]] to ; CHECK-SVE-NEXT: [[A_IMAG_EXT:%.*]] = sext [[A_IMAG]] to ; CHECK-SVE-NEXT: [[B_REAL_EXT:%.*]] = sext [[B_REAL]] to ; CHECK-SVE-NEXT: [[B_IMAG_EXT:%.*]] = sext [[B_IMAG]] to ; CHECK-SVE-NEXT: [[REAL_MUL:%.*]] = mul [[B_REAL_EXT]], [[A_REAL_EXT]] ; CHECK-SVE-NEXT: [[REAL_MUL_REDUCED:%.*]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[VEC_PHI]], [[REAL_MUL]]) ; CHECK-SVE-NEXT: [[IMAG_MUL:%.*]] = mul [[B_IMAG_EXT]], [[A_IMAG_EXT]] ; CHECK-SVE-NEXT: [[IMAG_MUL_NEG:%.*]] = sub zeroinitializer, [[IMAG_MUL]] ; CHECK-SVE-NEXT: [[PARTIAL_REDUCE_SUB]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[REAL_MUL_REDUCED]], [[IMAG_MUL_NEG]]) ; CHECK-SVE-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-SVE: [[MIDDLE_BLOCK]]: ; CHECK-SVE-NEXT: [[TMP11:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE_SUB]]) ; CHECK-SVE-NEXT: ret i32 [[TMP11]] ; ; CHECK-NOSVE-LABEL: define i32 @cdotp_i8_rot0( ; CHECK-NOSVE-SAME: [[A:%.*]], [[B:%.*]]) { ; CHECK-NOSVE-NEXT: [[ENTRY:.*]]: ; CHECK-NOSVE-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-NOSVE: [[VECTOR_BODY]]: ; CHECK-NOSVE-NEXT: [[VEC_PHI:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[PARTIAL_REDUCE_SUB:%.*]], %[[VECTOR_BODY]] ] ; CHECK-NOSVE-NEXT: [[A_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[A]]) ; CHECK-NOSVE-NEXT: [[B_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[B]]) ; CHECK-NOSVE-NEXT: [[A_REAL:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 0 ; CHECK-NOSVE-NEXT: [[A_IMAG:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 1 ; CHECK-NOSVE-NEXT: [[B_REAL:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 0 ; CHECK-NOSVE-NEXT: [[B_IMAG:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 1 ; CHECK-NOSVE-NEXT: [[A_REAL_EXT:%.*]] = sext [[A_REAL]] to ; CHECK-NOSVE-NEXT: [[A_IMAG_EXT:%.*]] = sext [[A_IMAG]] to ; CHECK-NOSVE-NEXT: [[B_REAL_EXT:%.*]] = sext [[B_REAL]] to ; CHECK-NOSVE-NEXT: [[B_IMAG_EXT:%.*]] = sext [[B_IMAG]] to ; CHECK-NOSVE-NEXT: [[REAL_MUL:%.*]] = mul [[B_REAL_EXT]], [[A_REAL_EXT]] ; CHECK-NOSVE-NEXT: [[REAL_MUL_REDUCED:%.*]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[VEC_PHI]], [[REAL_MUL]]) ; CHECK-NOSVE-NEXT: [[IMAG_MUL:%.*]] = mul [[B_IMAG_EXT]], [[A_IMAG_EXT]] ; CHECK-NOSVE-NEXT: [[IMAG_MUL_NEG:%.*]] = sub zeroinitializer, [[IMAG_MUL]] ; CHECK-NOSVE-NEXT: [[PARTIAL_REDUCE_SUB]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[REAL_MUL_REDUCED]], [[IMAG_MUL_NEG]]) ; CHECK-NOSVE-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-NOSVE: [[MIDDLE_BLOCK]]: ; CHECK-NOSVE-NEXT: [[TMP0:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE_SUB]]) ; CHECK-NOSVE-NEXT: ret i32 [[TMP0]] ; entry: br label %vector.body vector.body: ; preds = %vector.body, %entry %vec.phi = phi [ zeroinitializer, %entry ], [ %partial.reduce.sub, %vector.body ] %a.deinterleaved = call { , } @llvm.vector.deinterleave2.v32i8( %a) %b.deinterleaved = call { , } @llvm.vector.deinterleave2.v32i8( %b) %a.real = extractvalue { , } %a.deinterleaved, 0 %a.imag = extractvalue { , } %a.deinterleaved, 1 %b.real = extractvalue { , } %b.deinterleaved, 0 %b.imag = extractvalue { , } %b.deinterleaved, 1 %a.real.ext = sext %a.real to %a.imag.ext = sext %a.imag to %b.real.ext = sext %b.real to %b.imag.ext = sext %b.imag to %real.mul = mul %b.real.ext, %a.real.ext %real.mul.reduced = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( %vec.phi, %real.mul) %imag.mul = mul %b.imag.ext, %a.imag.ext %imag.mul.neg = sub zeroinitializer, %imag.mul %partial.reduce.sub = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( %real.mul.reduced, %imag.mul.neg) br i1 true, label %middle.block, label %vector.body middle.block: ; preds = %vector.body %0 = call i32 @llvm.vector.reduce.add.nxv4i32( %partial.reduce.sub) ret i32 %0 } define i32 @cdotp_i8_rot90( %a, %b) { ; CHECK-SVE2-LABEL: define i32 @cdotp_i8_rot90( ; CHECK-SVE2-SAME: [[A:%.*]], [[B:%.*]]) #[[ATTR0]] { ; CHECK-SVE2-NEXT: [[ENTRY:.*]]: ; CHECK-SVE2-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-SVE2: [[VECTOR_BODY]]: ; CHECK-SVE2-NEXT: [[TMP11:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[TMP10:%.*]], %[[VECTOR_BODY]] ] ; CHECK-SVE2-NEXT: [[TMP1:%.*]] = call @llvm.vector.extract.nxv16i8.nxv32i8( [[A]], i64 0) ; CHECK-SVE2-NEXT: [[TMP2:%.*]] = call @llvm.vector.extract.nxv16i8.nxv32i8( [[B]], i64 0) ; CHECK-SVE2-NEXT: [[TMP3:%.*]] = call @llvm.vector.extract.nxv16i8.nxv32i8( [[A]], i64 16) ; CHECK-SVE2-NEXT: [[TMP4:%.*]] = call @llvm.vector.extract.nxv16i8.nxv32i8( [[B]], i64 16) ; CHECK-SVE2-NEXT: [[TMP5:%.*]] = call @llvm.vector.extract.nxv4i32.nxv8i32( [[TMP11]], i64 0) ; CHECK-SVE2-NEXT: [[TMP6:%.*]] = call @llvm.vector.extract.nxv4i32.nxv8i32( [[TMP11]], i64 4) ; CHECK-SVE2-NEXT: [[TMP7:%.*]] = call @llvm.aarch64.sve.cdot.nxv4i32( [[TMP5]], [[TMP1]], [[TMP2]], i32 90) ; CHECK-SVE2-NEXT: [[TMP8:%.*]] = call @llvm.aarch64.sve.cdot.nxv4i32( [[TMP6]], [[TMP3]], [[TMP4]], i32 90) ; CHECK-SVE2-NEXT: [[TMP9:%.*]] = call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP7]], i64 0) ; CHECK-SVE2-NEXT: [[TMP10]] = call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP9]], [[TMP8]], i64 4) ; CHECK-SVE2-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-SVE2: [[MIDDLE_BLOCK]]: ; CHECK-SVE2-NEXT: [[TMP0:%.*]] = call i32 @llvm.vector.reduce.add.nxv8i32( [[TMP10]]) ; CHECK-SVE2-NEXT: ret i32 [[TMP0]] ; ; CHECK-SVE-LABEL: define i32 @cdotp_i8_rot90( ; CHECK-SVE-SAME: [[A:%.*]], [[B:%.*]]) #[[ATTR0]] { ; CHECK-SVE-NEXT: [[ENTRY:.*]]: ; CHECK-SVE-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-SVE: [[VECTOR_BODY]]: ; CHECK-SVE-NEXT: [[VEC_PHI:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[PARTIAL_REDUCE_SUB:%.*]], %[[VECTOR_BODY]] ] ; CHECK-SVE-NEXT: [[A_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[A]]) ; CHECK-SVE-NEXT: [[B_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[B]]) ; CHECK-SVE-NEXT: [[A_REAL:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 0 ; CHECK-SVE-NEXT: [[A_IMAG:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 1 ; CHECK-SVE-NEXT: [[B_REAL:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 0 ; CHECK-SVE-NEXT: [[B_IMAG:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 1 ; CHECK-SVE-NEXT: [[A_REAL_EXT:%.*]] = sext [[A_REAL]] to ; CHECK-SVE-NEXT: [[A_IMAG_EXT:%.*]] = sext [[A_IMAG]] to ; CHECK-SVE-NEXT: [[B_REAL_EXT:%.*]] = sext [[B_REAL]] to ; CHECK-SVE-NEXT: [[B_IMAG_EXT:%.*]] = sext [[B_IMAG]] to ; CHECK-SVE-NEXT: [[REAL_MUL:%.*]] = mul [[B_REAL_EXT]], [[A_IMAG_EXT]] ; CHECK-SVE-NEXT: [[REAL_MUL_REDUCED:%.*]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[VEC_PHI]], [[REAL_MUL]]) ; CHECK-SVE-NEXT: [[IMAG_MUL:%.*]] = mul [[B_IMAG_EXT]], [[A_REAL_EXT]] ; CHECK-SVE-NEXT: [[PARTIAL_REDUCE_SUB]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[REAL_MUL_REDUCED]], [[IMAG_MUL]]) ; CHECK-SVE-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-SVE: [[MIDDLE_BLOCK]]: ; CHECK-SVE-NEXT: [[TMP11:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE_SUB]]) ; CHECK-SVE-NEXT: ret i32 [[TMP11]] ; ; CHECK-NOSVE-LABEL: define i32 @cdotp_i8_rot90( ; CHECK-NOSVE-SAME: [[A:%.*]], [[B:%.*]]) { ; CHECK-NOSVE-NEXT: [[ENTRY:.*]]: ; CHECK-NOSVE-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-NOSVE: [[VECTOR_BODY]]: ; CHECK-NOSVE-NEXT: [[VEC_PHI:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[PARTIAL_REDUCE_SUB:%.*]], %[[VECTOR_BODY]] ] ; CHECK-NOSVE-NEXT: [[A_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[A]]) ; CHECK-NOSVE-NEXT: [[B_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[B]]) ; CHECK-NOSVE-NEXT: [[A_REAL:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 0 ; CHECK-NOSVE-NEXT: [[A_IMAG:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 1 ; CHECK-NOSVE-NEXT: [[B_REAL:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 0 ; CHECK-NOSVE-NEXT: [[B_IMAG:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 1 ; CHECK-NOSVE-NEXT: [[A_REAL_EXT:%.*]] = sext [[A_REAL]] to ; CHECK-NOSVE-NEXT: [[A_IMAG_EXT:%.*]] = sext [[A_IMAG]] to ; CHECK-NOSVE-NEXT: [[B_REAL_EXT:%.*]] = sext [[B_REAL]] to ; CHECK-NOSVE-NEXT: [[B_IMAG_EXT:%.*]] = sext [[B_IMAG]] to ; CHECK-NOSVE-NEXT: [[REAL_MUL:%.*]] = mul [[B_REAL_EXT]], [[A_IMAG_EXT]] ; CHECK-NOSVE-NEXT: [[REAL_MUL_REDUCED:%.*]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[VEC_PHI]], [[REAL_MUL]]) ; CHECK-NOSVE-NEXT: [[IMAG_MUL:%.*]] = mul [[B_IMAG_EXT]], [[A_REAL_EXT]] ; CHECK-NOSVE-NEXT: [[PARTIAL_REDUCE_SUB]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[REAL_MUL_REDUCED]], [[IMAG_MUL]]) ; CHECK-NOSVE-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-NOSVE: [[MIDDLE_BLOCK]]: ; CHECK-NOSVE-NEXT: [[TMP0:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE_SUB]]) ; CHECK-NOSVE-NEXT: ret i32 [[TMP0]] ; entry: br label %vector.body vector.body: ; preds = %vector.body, %entry %vec.phi = phi [ zeroinitializer, %entry ], [ %partial.reduce.sub, %vector.body ] %a.deinterleaved = call { , } @llvm.vector.deinterleave2.v32i8( %a) %b.deinterleaved = call { , } @llvm.vector.deinterleave2.v32i8( %b) %a.real = extractvalue { , } %a.deinterleaved, 0 %a.imag = extractvalue { , } %a.deinterleaved, 1 %b.real = extractvalue { , } %b.deinterleaved, 0 %b.imag = extractvalue { , } %b.deinterleaved, 1 %a.real.ext = sext %a.real to %a.imag.ext = sext %a.imag to %b.real.ext = sext %b.real to %b.imag.ext = sext %b.imag to %real.mul = mul %b.real.ext, %a.imag.ext %real.mul.reduced = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( %vec.phi, %real.mul) %imag.mul = mul %b.imag.ext, %a.real.ext %partial.reduce.sub = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( %real.mul.reduced, %imag.mul) br i1 true, label %middle.block, label %vector.body middle.block: ; preds = %vector.body %0 = call i32 @llvm.vector.reduce.add.nxv4i32( %partial.reduce.sub) ret i32 %0 } define i32 @cdotp_i8_rot180( %a, %b) { ; CHECK-SVE2-LABEL: define i32 @cdotp_i8_rot180( ; CHECK-SVE2-SAME: [[A:%.*]], [[B:%.*]]) #[[ATTR0]] { ; CHECK-SVE2-NEXT: [[ENTRY:.*]]: ; CHECK-SVE2-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-SVE2: [[VECTOR_BODY]]: ; CHECK-SVE2-NEXT: [[TMP11:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[TMP10:%.*]], %[[VECTOR_BODY]] ] ; CHECK-SVE2-NEXT: [[TMP1:%.*]] = call @llvm.vector.extract.nxv16i8.nxv32i8( [[A]], i64 0) ; CHECK-SVE2-NEXT: [[TMP2:%.*]] = call @llvm.vector.extract.nxv16i8.nxv32i8( [[B]], i64 0) ; CHECK-SVE2-NEXT: [[TMP3:%.*]] = call @llvm.vector.extract.nxv16i8.nxv32i8( [[A]], i64 16) ; CHECK-SVE2-NEXT: [[TMP4:%.*]] = call @llvm.vector.extract.nxv16i8.nxv32i8( [[B]], i64 16) ; CHECK-SVE2-NEXT: [[TMP5:%.*]] = call @llvm.vector.extract.nxv4i32.nxv8i32( [[TMP11]], i64 0) ; CHECK-SVE2-NEXT: [[TMP6:%.*]] = call @llvm.vector.extract.nxv4i32.nxv8i32( [[TMP11]], i64 4) ; CHECK-SVE2-NEXT: [[TMP7:%.*]] = call @llvm.aarch64.sve.cdot.nxv4i32( [[TMP5]], [[TMP1]], [[TMP2]], i32 180) ; CHECK-SVE2-NEXT: [[TMP8:%.*]] = call @llvm.aarch64.sve.cdot.nxv4i32( [[TMP6]], [[TMP3]], [[TMP4]], i32 180) ; CHECK-SVE2-NEXT: [[TMP9:%.*]] = call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP7]], i64 0) ; CHECK-SVE2-NEXT: [[TMP10]] = call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP9]], [[TMP8]], i64 4) ; CHECK-SVE2-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-SVE2: [[MIDDLE_BLOCK]]: ; CHECK-SVE2-NEXT: [[TMP0:%.*]] = call i32 @llvm.vector.reduce.add.nxv8i32( [[TMP10]]) ; CHECK-SVE2-NEXT: ret i32 [[TMP0]] ; ; CHECK-SVE-LABEL: define i32 @cdotp_i8_rot180( ; CHECK-SVE-SAME: [[A:%.*]], [[B:%.*]]) #[[ATTR0]] { ; CHECK-SVE-NEXT: [[ENTRY:.*]]: ; CHECK-SVE-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-SVE: [[VECTOR_BODY]]: ; CHECK-SVE-NEXT: [[VEC_PHI:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[PARTIAL_REDUCE_SUB:%.*]], %[[VECTOR_BODY]] ] ; CHECK-SVE-NEXT: [[A_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[A]]) ; CHECK-SVE-NEXT: [[B_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[B]]) ; CHECK-SVE-NEXT: [[A_REAL:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 0 ; CHECK-SVE-NEXT: [[A_IMAG:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 1 ; CHECK-SVE-NEXT: [[B_REAL:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 0 ; CHECK-SVE-NEXT: [[B_IMAG:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 1 ; CHECK-SVE-NEXT: [[A_REAL_EXT:%.*]] = sext [[A_REAL]] to ; CHECK-SVE-NEXT: [[A_IMAG_EXT:%.*]] = sext [[A_IMAG]] to ; CHECK-SVE-NEXT: [[B_REAL_EXT:%.*]] = sext [[B_REAL]] to ; CHECK-SVE-NEXT: [[B_IMAG_EXT:%.*]] = sext [[B_IMAG]] to ; CHECK-SVE-NEXT: [[REAL_MUL:%.*]] = mul [[B_REAL_EXT]], [[A_REAL_EXT]] ; CHECK-SVE-NEXT: [[REAL_MUL_REDUCED:%.*]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[VEC_PHI]], [[REAL_MUL]]) ; CHECK-SVE-NEXT: [[IMAG_MUL:%.*]] = mul [[B_IMAG_EXT]], [[A_IMAG_EXT]] ; CHECK-SVE-NEXT: [[PARTIAL_REDUCE_SUB]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[REAL_MUL_REDUCED]], [[IMAG_MUL]]) ; CHECK-SVE-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-SVE: [[MIDDLE_BLOCK]]: ; CHECK-SVE-NEXT: [[TMP11:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE_SUB]]) ; CHECK-SVE-NEXT: ret i32 [[TMP11]] ; ; CHECK-NOSVE-LABEL: define i32 @cdotp_i8_rot180( ; CHECK-NOSVE-SAME: [[A:%.*]], [[B:%.*]]) { ; CHECK-NOSVE-NEXT: [[ENTRY:.*]]: ; CHECK-NOSVE-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-NOSVE: [[VECTOR_BODY]]: ; CHECK-NOSVE-NEXT: [[VEC_PHI:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[PARTIAL_REDUCE_SUB:%.*]], %[[VECTOR_BODY]] ] ; CHECK-NOSVE-NEXT: [[A_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[A]]) ; CHECK-NOSVE-NEXT: [[B_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[B]]) ; CHECK-NOSVE-NEXT: [[A_REAL:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 0 ; CHECK-NOSVE-NEXT: [[A_IMAG:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 1 ; CHECK-NOSVE-NEXT: [[B_REAL:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 0 ; CHECK-NOSVE-NEXT: [[B_IMAG:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 1 ; CHECK-NOSVE-NEXT: [[A_REAL_EXT:%.*]] = sext [[A_REAL]] to ; CHECK-NOSVE-NEXT: [[A_IMAG_EXT:%.*]] = sext [[A_IMAG]] to ; CHECK-NOSVE-NEXT: [[B_REAL_EXT:%.*]] = sext [[B_REAL]] to ; CHECK-NOSVE-NEXT: [[B_IMAG_EXT:%.*]] = sext [[B_IMAG]] to ; CHECK-NOSVE-NEXT: [[REAL_MUL:%.*]] = mul [[B_REAL_EXT]], [[A_REAL_EXT]] ; CHECK-NOSVE-NEXT: [[REAL_MUL_REDUCED:%.*]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[VEC_PHI]], [[REAL_MUL]]) ; CHECK-NOSVE-NEXT: [[IMAG_MUL:%.*]] = mul [[B_IMAG_EXT]], [[A_IMAG_EXT]] ; CHECK-NOSVE-NEXT: [[PARTIAL_REDUCE_SUB]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[REAL_MUL_REDUCED]], [[IMAG_MUL]]) ; CHECK-NOSVE-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-NOSVE: [[MIDDLE_BLOCK]]: ; CHECK-NOSVE-NEXT: [[TMP0:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE_SUB]]) ; CHECK-NOSVE-NEXT: ret i32 [[TMP0]] ; entry: br label %vector.body vector.body: ; preds = %vector.body, %entry %vec.phi = phi [ zeroinitializer, %entry ], [ %partial.reduce.sub, %vector.body ] %a.deinterleaved = call { , } @llvm.vector.deinterleave2.v32i8( %a) %b.deinterleaved = call { , } @llvm.vector.deinterleave2.v32i8( %b) %a.real = extractvalue { , } %a.deinterleaved, 0 %a.imag = extractvalue { , } %a.deinterleaved, 1 %b.real = extractvalue { , } %b.deinterleaved, 0 %b.imag = extractvalue { , } %b.deinterleaved, 1 %a.real.ext = sext %a.real to %a.imag.ext = sext %a.imag to %b.real.ext = sext %b.real to %b.imag.ext = sext %b.imag to %real.mul = mul %b.real.ext, %a.real.ext %real.mul.reduced = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( %vec.phi, %real.mul) %imag.mul = mul %b.imag.ext, %a.imag.ext %partial.reduce.sub = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( %real.mul.reduced, %imag.mul) br i1 true, label %middle.block, label %vector.body middle.block: ; preds = %vector.body %0 = call i32 @llvm.vector.reduce.add.nxv4i32( %partial.reduce.sub) ret i32 %0 } define i32 @cdotp_i8_rot270( %a, %b) { ; CHECK-SVE2-LABEL: define i32 @cdotp_i8_rot270( ; CHECK-SVE2-SAME: [[A:%.*]], [[B:%.*]]) #[[ATTR0]] { ; CHECK-SVE2-NEXT: [[ENTRY:.*]]: ; CHECK-SVE2-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-SVE2: [[VECTOR_BODY]]: ; CHECK-SVE2-NEXT: [[TMP11:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[TMP10:%.*]], %[[VECTOR_BODY]] ] ; CHECK-SVE2-NEXT: [[TMP1:%.*]] = call @llvm.vector.extract.nxv16i8.nxv32i8( [[A]], i64 0) ; CHECK-SVE2-NEXT: [[TMP2:%.*]] = call @llvm.vector.extract.nxv16i8.nxv32i8( [[B]], i64 0) ; CHECK-SVE2-NEXT: [[TMP3:%.*]] = call @llvm.vector.extract.nxv16i8.nxv32i8( [[A]], i64 16) ; CHECK-SVE2-NEXT: [[TMP4:%.*]] = call @llvm.vector.extract.nxv16i8.nxv32i8( [[B]], i64 16) ; CHECK-SVE2-NEXT: [[TMP5:%.*]] = call @llvm.vector.extract.nxv4i32.nxv8i32( [[TMP11]], i64 0) ; CHECK-SVE2-NEXT: [[TMP6:%.*]] = call @llvm.vector.extract.nxv4i32.nxv8i32( [[TMP11]], i64 4) ; CHECK-SVE2-NEXT: [[TMP7:%.*]] = call @llvm.aarch64.sve.cdot.nxv4i32( [[TMP5]], [[TMP1]], [[TMP2]], i32 270) ; CHECK-SVE2-NEXT: [[TMP8:%.*]] = call @llvm.aarch64.sve.cdot.nxv4i32( [[TMP6]], [[TMP3]], [[TMP4]], i32 270) ; CHECK-SVE2-NEXT: [[TMP9:%.*]] = call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP7]], i64 0) ; CHECK-SVE2-NEXT: [[TMP10]] = call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP9]], [[TMP8]], i64 4) ; CHECK-SVE2-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-SVE2: [[MIDDLE_BLOCK]]: ; CHECK-SVE2-NEXT: [[TMP0:%.*]] = call i32 @llvm.vector.reduce.add.nxv8i32( [[TMP10]]) ; CHECK-SVE2-NEXT: ret i32 [[TMP0]] ; ; CHECK-SVE-LABEL: define i32 @cdotp_i8_rot270( ; CHECK-SVE-SAME: [[A:%.*]], [[B:%.*]]) #[[ATTR0]] { ; CHECK-SVE-NEXT: [[ENTRY:.*]]: ; CHECK-SVE-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-SVE: [[VECTOR_BODY]]: ; CHECK-SVE-NEXT: [[VEC_PHI:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[PARTIAL_REDUCE_SUB:%.*]], %[[VECTOR_BODY]] ] ; CHECK-SVE-NEXT: [[A_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[A]]) ; CHECK-SVE-NEXT: [[B_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[B]]) ; CHECK-SVE-NEXT: [[A_REAL:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 0 ; CHECK-SVE-NEXT: [[A_IMAG:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 1 ; CHECK-SVE-NEXT: [[B_REAL:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 0 ; CHECK-SVE-NEXT: [[B_IMAG:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 1 ; CHECK-SVE-NEXT: [[A_REAL_EXT:%.*]] = sext [[A_REAL]] to ; CHECK-SVE-NEXT: [[A_IMAG_EXT:%.*]] = sext [[A_IMAG]] to ; CHECK-SVE-NEXT: [[B_REAL_EXT:%.*]] = sext [[B_REAL]] to ; CHECK-SVE-NEXT: [[B_IMAG_EXT:%.*]] = sext [[B_IMAG]] to ; CHECK-SVE-NEXT: [[REAL_MUL:%.*]] = mul [[B_REAL_EXT]], [[A_IMAG_EXT]] ; CHECK-SVE-NEXT: [[REAL_MUL_NEG:%.*]] = sub zeroinitializer, [[REAL_MUL]] ; CHECK-SVE-NEXT: [[REAL_MUL_REDUCED:%.*]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[VEC_PHI]], [[REAL_MUL_NEG]]) ; CHECK-SVE-NEXT: [[IMAG_MUL:%.*]] = mul [[B_IMAG_EXT]], [[A_REAL_EXT]] ; CHECK-SVE-NEXT: [[PARTIAL_REDUCE_SUB]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[REAL_MUL_REDUCED]], [[IMAG_MUL]]) ; CHECK-SVE-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-SVE: [[MIDDLE_BLOCK]]: ; CHECK-SVE-NEXT: [[TMP11:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE_SUB]]) ; CHECK-SVE-NEXT: ret i32 [[TMP11]] ; ; CHECK-NOSVE-LABEL: define i32 @cdotp_i8_rot270( ; CHECK-NOSVE-SAME: [[A:%.*]], [[B:%.*]]) { ; CHECK-NOSVE-NEXT: [[ENTRY:.*]]: ; CHECK-NOSVE-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-NOSVE: [[VECTOR_BODY]]: ; CHECK-NOSVE-NEXT: [[VEC_PHI:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[PARTIAL_REDUCE_SUB:%.*]], %[[VECTOR_BODY]] ] ; CHECK-NOSVE-NEXT: [[A_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[A]]) ; CHECK-NOSVE-NEXT: [[B_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[B]]) ; CHECK-NOSVE-NEXT: [[A_REAL:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 0 ; CHECK-NOSVE-NEXT: [[A_IMAG:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 1 ; CHECK-NOSVE-NEXT: [[B_REAL:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 0 ; CHECK-NOSVE-NEXT: [[B_IMAG:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 1 ; CHECK-NOSVE-NEXT: [[A_REAL_EXT:%.*]] = sext [[A_REAL]] to ; CHECK-NOSVE-NEXT: [[A_IMAG_EXT:%.*]] = sext [[A_IMAG]] to ; CHECK-NOSVE-NEXT: [[B_REAL_EXT:%.*]] = sext [[B_REAL]] to ; CHECK-NOSVE-NEXT: [[B_IMAG_EXT:%.*]] = sext [[B_IMAG]] to ; CHECK-NOSVE-NEXT: [[REAL_MUL:%.*]] = mul [[B_REAL_EXT]], [[A_IMAG_EXT]] ; CHECK-NOSVE-NEXT: [[REAL_MUL_NEG:%.*]] = sub zeroinitializer, [[REAL_MUL]] ; CHECK-NOSVE-NEXT: [[REAL_MUL_REDUCED:%.*]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[VEC_PHI]], [[REAL_MUL_NEG]]) ; CHECK-NOSVE-NEXT: [[IMAG_MUL:%.*]] = mul [[B_IMAG_EXT]], [[A_REAL_EXT]] ; CHECK-NOSVE-NEXT: [[PARTIAL_REDUCE_SUB]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[REAL_MUL_REDUCED]], [[IMAG_MUL]]) ; CHECK-NOSVE-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-NOSVE: [[MIDDLE_BLOCK]]: ; CHECK-NOSVE-NEXT: [[TMP0:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE_SUB]]) ; CHECK-NOSVE-NEXT: ret i32 [[TMP0]] ; entry: br label %vector.body vector.body: ; preds = %vector.body, %entry %vec.phi = phi [ zeroinitializer, %entry ], [ %partial.reduce.sub, %vector.body ] %a.deinterleaved = call { , } @llvm.vector.deinterleave2.v32i8( %a) %b.deinterleaved = call { , } @llvm.vector.deinterleave2.v32i8( %b) %a.real = extractvalue { , } %a.deinterleaved, 0 %a.imag = extractvalue { , } %a.deinterleaved, 1 %b.real = extractvalue { , } %b.deinterleaved, 0 %b.imag = extractvalue { , } %b.deinterleaved, 1 %a.real.ext = sext %a.real to %a.imag.ext = sext %a.imag to %b.real.ext = sext %b.real to %b.imag.ext = sext %b.imag to %real.mul = mul %b.real.ext, %a.imag.ext %real.mul.neg = sub zeroinitializer, %real.mul %real.mul.reduced = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( %vec.phi, %real.mul.neg) %imag.mul = mul %b.imag.ext, %a.real.ext %partial.reduce.sub = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( %real.mul.reduced, %imag.mul) br i1 true, label %middle.block, label %vector.body middle.block: ; preds = %vector.body %0 = call i32 @llvm.vector.reduce.add.nxv4i32( %partial.reduce.sub) ret i32 %0 } define i64 @cdotp_i16_rot0( %a, %b) { ; CHECK-SVE2-LABEL: define i64 @cdotp_i16_rot0( ; CHECK-SVE2-SAME: [[A:%.*]], [[B:%.*]]) #[[ATTR0]] { ; CHECK-SVE2-NEXT: [[ENTRY:.*]]: ; CHECK-SVE2-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-SVE2: [[VECTOR_BODY]]: ; CHECK-SVE2-NEXT: [[TMP11:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[TMP10:%.*]], %[[VECTOR_BODY]] ] ; CHECK-SVE2-NEXT: [[TMP1:%.*]] = call @llvm.vector.extract.nxv8i16.nxv16i16( [[A]], i64 0) ; CHECK-SVE2-NEXT: [[TMP2:%.*]] = call @llvm.vector.extract.nxv8i16.nxv16i16( [[B]], i64 0) ; CHECK-SVE2-NEXT: [[TMP3:%.*]] = call @llvm.vector.extract.nxv8i16.nxv16i16( [[A]], i64 8) ; CHECK-SVE2-NEXT: [[TMP4:%.*]] = call @llvm.vector.extract.nxv8i16.nxv16i16( [[B]], i64 8) ; CHECK-SVE2-NEXT: [[TMP5:%.*]] = call @llvm.vector.extract.nxv2i64.nxv4i64( [[TMP11]], i64 0) ; CHECK-SVE2-NEXT: [[TMP6:%.*]] = call @llvm.vector.extract.nxv2i64.nxv4i64( [[TMP11]], i64 2) ; CHECK-SVE2-NEXT: [[TMP7:%.*]] = call @llvm.aarch64.sve.cdot.nxv2i64( [[TMP5]], [[TMP1]], [[TMP2]], i32 0) ; CHECK-SVE2-NEXT: [[TMP8:%.*]] = call @llvm.aarch64.sve.cdot.nxv2i64( [[TMP6]], [[TMP3]], [[TMP4]], i32 0) ; CHECK-SVE2-NEXT: [[TMP9:%.*]] = call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP7]], i64 0) ; CHECK-SVE2-NEXT: [[TMP10]] = call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP9]], [[TMP8]], i64 2) ; CHECK-SVE2-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-SVE2: [[MIDDLE_BLOCK]]: ; CHECK-SVE2-NEXT: [[TMP0:%.*]] = call i64 @llvm.vector.reduce.add.nxv4i64( [[TMP10]]) ; CHECK-SVE2-NEXT: ret i64 [[TMP0]] ; ; CHECK-SVE-LABEL: define i64 @cdotp_i16_rot0( ; CHECK-SVE-SAME: [[A:%.*]], [[B:%.*]]) #[[ATTR0]] { ; CHECK-SVE-NEXT: [[ENTRY:.*]]: ; CHECK-SVE-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-SVE: [[VECTOR_BODY]]: ; CHECK-SVE-NEXT: [[VEC_PHI:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[PARTIAL_REDUCE_SUB:%.*]], %[[VECTOR_BODY]] ] ; CHECK-SVE-NEXT: [[A_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv16i16( [[A]]) ; CHECK-SVE-NEXT: [[B_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv16i16( [[B]]) ; CHECK-SVE-NEXT: [[A_REAL:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 0 ; CHECK-SVE-NEXT: [[A_IMAG:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 1 ; CHECK-SVE-NEXT: [[B_REAL:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 0 ; CHECK-SVE-NEXT: [[B_IMAG:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 1 ; CHECK-SVE-NEXT: [[A_REAL_EXT:%.*]] = sext [[A_REAL]] to ; CHECK-SVE-NEXT: [[A_IMAG_EXT:%.*]] = sext [[A_IMAG]] to ; CHECK-SVE-NEXT: [[B_REAL_EXT:%.*]] = sext [[B_REAL]] to ; CHECK-SVE-NEXT: [[B_IMAG_EXT:%.*]] = sext [[B_IMAG]] to ; CHECK-SVE-NEXT: [[REAL_MUL:%.*]] = mul [[B_REAL_EXT]], [[A_REAL_EXT]] ; CHECK-SVE-NEXT: [[REAL_MUL_REDUCED:%.*]] = call @llvm.vector.partial.reduce.add.nxv2i64.nxv8i64( [[VEC_PHI]], [[REAL_MUL]]) ; CHECK-SVE-NEXT: [[IMAG_MUL:%.*]] = mul [[B_IMAG_EXT]], [[A_IMAG_EXT]] ; CHECK-SVE-NEXT: [[IMAG_MUL_NEG:%.*]] = sub zeroinitializer, [[IMAG_MUL]] ; CHECK-SVE-NEXT: [[PARTIAL_REDUCE_SUB]] = call @llvm.vector.partial.reduce.add.nxv2i64.nxv8i64( [[REAL_MUL_REDUCED]], [[IMAG_MUL_NEG]]) ; CHECK-SVE-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-SVE: [[MIDDLE_BLOCK]]: ; CHECK-SVE-NEXT: [[TMP11:%.*]] = call i64 @llvm.vector.reduce.add.nxv2i64( [[PARTIAL_REDUCE_SUB]]) ; CHECK-SVE-NEXT: ret i64 [[TMP11]] ; ; CHECK-NOSVE-LABEL: define i64 @cdotp_i16_rot0( ; CHECK-NOSVE-SAME: [[A:%.*]], [[B:%.*]]) { ; CHECK-NOSVE-NEXT: [[ENTRY:.*]]: ; CHECK-NOSVE-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-NOSVE: [[VECTOR_BODY]]: ; CHECK-NOSVE-NEXT: [[VEC_PHI:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[PARTIAL_REDUCE_SUB:%.*]], %[[VECTOR_BODY]] ] ; CHECK-NOSVE-NEXT: [[A_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv16i16( [[A]]) ; CHECK-NOSVE-NEXT: [[B_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv16i16( [[B]]) ; CHECK-NOSVE-NEXT: [[A_REAL:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 0 ; CHECK-NOSVE-NEXT: [[A_IMAG:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 1 ; CHECK-NOSVE-NEXT: [[B_REAL:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 0 ; CHECK-NOSVE-NEXT: [[B_IMAG:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 1 ; CHECK-NOSVE-NEXT: [[A_REAL_EXT:%.*]] = sext [[A_REAL]] to ; CHECK-NOSVE-NEXT: [[A_IMAG_EXT:%.*]] = sext [[A_IMAG]] to ; CHECK-NOSVE-NEXT: [[B_REAL_EXT:%.*]] = sext [[B_REAL]] to ; CHECK-NOSVE-NEXT: [[B_IMAG_EXT:%.*]] = sext [[B_IMAG]] to ; CHECK-NOSVE-NEXT: [[REAL_MUL:%.*]] = mul [[B_REAL_EXT]], [[A_REAL_EXT]] ; CHECK-NOSVE-NEXT: [[REAL_MUL_REDUCED:%.*]] = call @llvm.vector.partial.reduce.add.nxv2i64.nxv8i64( [[VEC_PHI]], [[REAL_MUL]]) ; CHECK-NOSVE-NEXT: [[IMAG_MUL:%.*]] = mul [[B_IMAG_EXT]], [[A_IMAG_EXT]] ; CHECK-NOSVE-NEXT: [[IMAG_MUL_NEG:%.*]] = sub zeroinitializer, [[IMAG_MUL]] ; CHECK-NOSVE-NEXT: [[PARTIAL_REDUCE_SUB]] = call @llvm.vector.partial.reduce.add.nxv2i64.nxv8i64( [[REAL_MUL_REDUCED]], [[IMAG_MUL_NEG]]) ; CHECK-NOSVE-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-NOSVE: [[MIDDLE_BLOCK]]: ; CHECK-NOSVE-NEXT: [[TMP0:%.*]] = call i64 @llvm.vector.reduce.add.nxv2i64( [[PARTIAL_REDUCE_SUB]]) ; CHECK-NOSVE-NEXT: ret i64 [[TMP0]] ; entry: br label %vector.body vector.body: ; preds = %vector.body, %entry %vec.phi = phi [ zeroinitializer, %entry ], [ %partial.reduce.sub, %vector.body ] %a.deinterleaved = call { , } @llvm.vector.deinterleave2.v16i16( %a) %b.deinterleaved = call { , } @llvm.vector.deinterleave2.v16i16( %b) %a.real = extractvalue { , } %a.deinterleaved, 0 %a.imag = extractvalue { , } %a.deinterleaved, 1 %b.real = extractvalue { , } %b.deinterleaved, 0 %b.imag = extractvalue { , } %b.deinterleaved, 1 %a.real.ext = sext %a.real to %a.imag.ext = sext %a.imag to %b.real.ext = sext %b.real to %b.imag.ext = sext %b.imag to %real.mul = mul %b.real.ext, %a.real.ext %real.mul.reduced = call @llvm.vector.partial.reduce.add.nxv2i64.nxv8i64( %vec.phi, %real.mul) %imag.mul = mul %b.imag.ext, %a.imag.ext %imag.mul.neg = sub zeroinitializer, %imag.mul %partial.reduce.sub = call @llvm.vector.partial.reduce.add.nxv2i64.nxv8i64( %real.mul.reduced, %imag.mul.neg) br i1 true, label %middle.block, label %vector.body middle.block: ; preds = %vector.body %0 = call i64 @llvm.vector.reduce.add.nxv2i64( %partial.reduce.sub) ret i64 %0 } define i64 @cdotp_i16_rot90( %a, %b) { ; CHECK-SVE2-LABEL: define i64 @cdotp_i16_rot90( ; CHECK-SVE2-SAME: [[A:%.*]], [[B:%.*]]) #[[ATTR0]] { ; CHECK-SVE2-NEXT: [[ENTRY:.*]]: ; CHECK-SVE2-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-SVE2: [[VECTOR_BODY]]: ; CHECK-SVE2-NEXT: [[TMP11:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[TMP10:%.*]], %[[VECTOR_BODY]] ] ; CHECK-SVE2-NEXT: [[TMP1:%.*]] = call @llvm.vector.extract.nxv8i16.nxv16i16( [[A]], i64 0) ; CHECK-SVE2-NEXT: [[TMP2:%.*]] = call @llvm.vector.extract.nxv8i16.nxv16i16( [[B]], i64 0) ; CHECK-SVE2-NEXT: [[TMP3:%.*]] = call @llvm.vector.extract.nxv8i16.nxv16i16( [[A]], i64 8) ; CHECK-SVE2-NEXT: [[TMP4:%.*]] = call @llvm.vector.extract.nxv8i16.nxv16i16( [[B]], i64 8) ; CHECK-SVE2-NEXT: [[TMP5:%.*]] = call @llvm.vector.extract.nxv2i64.nxv4i64( [[TMP11]], i64 0) ; CHECK-SVE2-NEXT: [[TMP6:%.*]] = call @llvm.vector.extract.nxv2i64.nxv4i64( [[TMP11]], i64 2) ; CHECK-SVE2-NEXT: [[TMP7:%.*]] = call @llvm.aarch64.sve.cdot.nxv2i64( [[TMP5]], [[TMP1]], [[TMP2]], i32 90) ; CHECK-SVE2-NEXT: [[TMP8:%.*]] = call @llvm.aarch64.sve.cdot.nxv2i64( [[TMP6]], [[TMP3]], [[TMP4]], i32 90) ; CHECK-SVE2-NEXT: [[TMP9:%.*]] = call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP7]], i64 0) ; CHECK-SVE2-NEXT: [[TMP10]] = call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP9]], [[TMP8]], i64 2) ; CHECK-SVE2-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-SVE2: [[MIDDLE_BLOCK]]: ; CHECK-SVE2-NEXT: [[TMP0:%.*]] = call i64 @llvm.vector.reduce.add.nxv4i64( [[TMP10]]) ; CHECK-SVE2-NEXT: ret i64 [[TMP0]] ; ; CHECK-SVE-LABEL: define i64 @cdotp_i16_rot90( ; CHECK-SVE-SAME: [[A:%.*]], [[B:%.*]]) #[[ATTR0]] { ; CHECK-SVE-NEXT: [[ENTRY:.*]]: ; CHECK-SVE-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-SVE: [[VECTOR_BODY]]: ; CHECK-SVE-NEXT: [[VEC_PHI:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[PARTIAL_REDUCE_SUB:%.*]], %[[VECTOR_BODY]] ] ; CHECK-SVE-NEXT: [[A_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv16i16( [[A]]) ; CHECK-SVE-NEXT: [[B_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv16i16( [[B]]) ; CHECK-SVE-NEXT: [[A_REAL:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 0 ; CHECK-SVE-NEXT: [[A_IMAG:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 1 ; CHECK-SVE-NEXT: [[B_REAL:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 0 ; CHECK-SVE-NEXT: [[B_IMAG:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 1 ; CHECK-SVE-NEXT: [[A_REAL_EXT:%.*]] = sext [[A_REAL]] to ; CHECK-SVE-NEXT: [[A_IMAG_EXT:%.*]] = sext [[A_IMAG]] to ; CHECK-SVE-NEXT: [[B_REAL_EXT:%.*]] = sext [[B_REAL]] to ; CHECK-SVE-NEXT: [[B_IMAG_EXT:%.*]] = sext [[B_IMAG]] to ; CHECK-SVE-NEXT: [[REAL_MUL:%.*]] = mul [[B_REAL_EXT]], [[A_IMAG_EXT]] ; CHECK-SVE-NEXT: [[REAL_MUL_REDUCED:%.*]] = call @llvm.vector.partial.reduce.add.nxv2i64.nxv8i64( [[VEC_PHI]], [[REAL_MUL]]) ; CHECK-SVE-NEXT: [[IMAG_MUL:%.*]] = mul [[B_IMAG_EXT]], [[A_REAL_EXT]] ; CHECK-SVE-NEXT: [[PARTIAL_REDUCE_SUB]] = call @llvm.vector.partial.reduce.add.nxv2i64.nxv8i64( [[REAL_MUL_REDUCED]], [[IMAG_MUL]]) ; CHECK-SVE-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-SVE: [[MIDDLE_BLOCK]]: ; CHECK-SVE-NEXT: [[TMP11:%.*]] = call i64 @llvm.vector.reduce.add.nxv2i64( [[PARTIAL_REDUCE_SUB]]) ; CHECK-SVE-NEXT: ret i64 [[TMP11]] ; ; CHECK-NOSVE-LABEL: define i64 @cdotp_i16_rot90( ; CHECK-NOSVE-SAME: [[A:%.*]], [[B:%.*]]) { ; CHECK-NOSVE-NEXT: [[ENTRY:.*]]: ; CHECK-NOSVE-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-NOSVE: [[VECTOR_BODY]]: ; CHECK-NOSVE-NEXT: [[VEC_PHI:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[PARTIAL_REDUCE_SUB:%.*]], %[[VECTOR_BODY]] ] ; CHECK-NOSVE-NEXT: [[A_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv16i16( [[A]]) ; CHECK-NOSVE-NEXT: [[B_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv16i16( [[B]]) ; CHECK-NOSVE-NEXT: [[A_REAL:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 0 ; CHECK-NOSVE-NEXT: [[A_IMAG:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 1 ; CHECK-NOSVE-NEXT: [[B_REAL:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 0 ; CHECK-NOSVE-NEXT: [[B_IMAG:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 1 ; CHECK-NOSVE-NEXT: [[A_REAL_EXT:%.*]] = sext [[A_REAL]] to ; CHECK-NOSVE-NEXT: [[A_IMAG_EXT:%.*]] = sext [[A_IMAG]] to ; CHECK-NOSVE-NEXT: [[B_REAL_EXT:%.*]] = sext [[B_REAL]] to ; CHECK-NOSVE-NEXT: [[B_IMAG_EXT:%.*]] = sext [[B_IMAG]] to ; CHECK-NOSVE-NEXT: [[REAL_MUL:%.*]] = mul [[B_REAL_EXT]], [[A_IMAG_EXT]] ; CHECK-NOSVE-NEXT: [[REAL_MUL_REDUCED:%.*]] = call @llvm.vector.partial.reduce.add.nxv2i64.nxv8i64( [[VEC_PHI]], [[REAL_MUL]]) ; CHECK-NOSVE-NEXT: [[IMAG_MUL:%.*]] = mul [[B_IMAG_EXT]], [[A_REAL_EXT]] ; CHECK-NOSVE-NEXT: [[PARTIAL_REDUCE_SUB]] = call @llvm.vector.partial.reduce.add.nxv2i64.nxv8i64( [[REAL_MUL_REDUCED]], [[IMAG_MUL]]) ; CHECK-NOSVE-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-NOSVE: [[MIDDLE_BLOCK]]: ; CHECK-NOSVE-NEXT: [[TMP0:%.*]] = call i64 @llvm.vector.reduce.add.nxv2i64( [[PARTIAL_REDUCE_SUB]]) ; CHECK-NOSVE-NEXT: ret i64 [[TMP0]] ; entry: br label %vector.body vector.body: ; preds = %vector.body, %entry %vec.phi = phi [ zeroinitializer, %entry ], [ %partial.reduce.sub, %vector.body ] %a.deinterleaved = call { , } @llvm.vector.deinterleave2.v16i16( %a) %b.deinterleaved = call { , } @llvm.vector.deinterleave2.v16i16( %b) %a.real = extractvalue { , } %a.deinterleaved, 0 %a.imag = extractvalue { , } %a.deinterleaved, 1 %b.real = extractvalue { , } %b.deinterleaved, 0 %b.imag = extractvalue { , } %b.deinterleaved, 1 %a.real.ext = sext %a.real to %a.imag.ext = sext %a.imag to %b.real.ext = sext %b.real to %b.imag.ext = sext %b.imag to %real.mul = mul %b.real.ext, %a.imag.ext %real.mul.reduced = call @llvm.vector.partial.reduce.add.nxv2i64.nxv8i64( %vec.phi, %real.mul) %imag.mul = mul %b.imag.ext, %a.real.ext %partial.reduce.sub = call @llvm.vector.partial.reduce.add.nxv2i64.nxv8i64( %real.mul.reduced, %imag.mul) br i1 true, label %middle.block, label %vector.body middle.block: ; preds = %vector.body %0 = call i64 @llvm.vector.reduce.add.nxv2i64( %partial.reduce.sub) ret i64 %0 } define i64 @cdotp_i16_rot180( %a, %b) { ; CHECK-SVE2-LABEL: define i64 @cdotp_i16_rot180( ; CHECK-SVE2-SAME: [[A:%.*]], [[B:%.*]]) #[[ATTR0]] { ; CHECK-SVE2-NEXT: [[ENTRY:.*]]: ; CHECK-SVE2-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-SVE2: [[VECTOR_BODY]]: ; CHECK-SVE2-NEXT: [[TMP11:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[TMP10:%.*]], %[[VECTOR_BODY]] ] ; CHECK-SVE2-NEXT: [[TMP1:%.*]] = call @llvm.vector.extract.nxv8i16.nxv16i16( [[A]], i64 0) ; CHECK-SVE2-NEXT: [[TMP2:%.*]] = call @llvm.vector.extract.nxv8i16.nxv16i16( [[B]], i64 0) ; CHECK-SVE2-NEXT: [[TMP3:%.*]] = call @llvm.vector.extract.nxv8i16.nxv16i16( [[A]], i64 8) ; CHECK-SVE2-NEXT: [[TMP4:%.*]] = call @llvm.vector.extract.nxv8i16.nxv16i16( [[B]], i64 8) ; CHECK-SVE2-NEXT: [[TMP5:%.*]] = call @llvm.vector.extract.nxv2i64.nxv4i64( [[TMP11]], i64 0) ; CHECK-SVE2-NEXT: [[TMP6:%.*]] = call @llvm.vector.extract.nxv2i64.nxv4i64( [[TMP11]], i64 2) ; CHECK-SVE2-NEXT: [[TMP7:%.*]] = call @llvm.aarch64.sve.cdot.nxv2i64( [[TMP5]], [[TMP1]], [[TMP2]], i32 180) ; CHECK-SVE2-NEXT: [[TMP8:%.*]] = call @llvm.aarch64.sve.cdot.nxv2i64( [[TMP6]], [[TMP3]], [[TMP4]], i32 180) ; CHECK-SVE2-NEXT: [[TMP9:%.*]] = call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP7]], i64 0) ; CHECK-SVE2-NEXT: [[TMP10]] = call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP9]], [[TMP8]], i64 2) ; CHECK-SVE2-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-SVE2: [[MIDDLE_BLOCK]]: ; CHECK-SVE2-NEXT: [[TMP0:%.*]] = call i64 @llvm.vector.reduce.add.nxv4i64( [[TMP10]]) ; CHECK-SVE2-NEXT: ret i64 [[TMP0]] ; ; CHECK-SVE-LABEL: define i64 @cdotp_i16_rot180( ; CHECK-SVE-SAME: [[A:%.*]], [[B:%.*]]) #[[ATTR0]] { ; CHECK-SVE-NEXT: [[ENTRY:.*]]: ; CHECK-SVE-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-SVE: [[VECTOR_BODY]]: ; CHECK-SVE-NEXT: [[VEC_PHI:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[PARTIAL_REDUCE_SUB:%.*]], %[[VECTOR_BODY]] ] ; CHECK-SVE-NEXT: [[A_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv16i16( [[A]]) ; CHECK-SVE-NEXT: [[B_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv16i16( [[B]]) ; CHECK-SVE-NEXT: [[A_REAL:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 0 ; CHECK-SVE-NEXT: [[A_IMAG:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 1 ; CHECK-SVE-NEXT: [[B_REAL:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 0 ; CHECK-SVE-NEXT: [[B_IMAG:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 1 ; CHECK-SVE-NEXT: [[A_REAL_EXT:%.*]] = sext [[A_REAL]] to ; CHECK-SVE-NEXT: [[A_IMAG_EXT:%.*]] = sext [[A_IMAG]] to ; CHECK-SVE-NEXT: [[B_REAL_EXT:%.*]] = sext [[B_REAL]] to ; CHECK-SVE-NEXT: [[B_IMAG_EXT:%.*]] = sext [[B_IMAG]] to ; CHECK-SVE-NEXT: [[REAL_MUL:%.*]] = mul [[B_REAL_EXT]], [[A_REAL_EXT]] ; CHECK-SVE-NEXT: [[REAL_MUL_REDUCED:%.*]] = call @llvm.vector.partial.reduce.add.nxv2i64.nxv8i64( [[VEC_PHI]], [[REAL_MUL]]) ; CHECK-SVE-NEXT: [[IMAG_MUL:%.*]] = mul [[B_IMAG_EXT]], [[A_IMAG_EXT]] ; CHECK-SVE-NEXT: [[PARTIAL_REDUCE_SUB]] = call @llvm.vector.partial.reduce.add.nxv2i64.nxv8i64( [[REAL_MUL_REDUCED]], [[IMAG_MUL]]) ; CHECK-SVE-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-SVE: [[MIDDLE_BLOCK]]: ; CHECK-SVE-NEXT: [[TMP11:%.*]] = call i64 @llvm.vector.reduce.add.nxv2i64( [[PARTIAL_REDUCE_SUB]]) ; CHECK-SVE-NEXT: ret i64 [[TMP11]] ; ; CHECK-NOSVE-LABEL: define i64 @cdotp_i16_rot180( ; CHECK-NOSVE-SAME: [[A:%.*]], [[B:%.*]]) { ; CHECK-NOSVE-NEXT: [[ENTRY:.*]]: ; CHECK-NOSVE-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-NOSVE: [[VECTOR_BODY]]: ; CHECK-NOSVE-NEXT: [[VEC_PHI:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[PARTIAL_REDUCE_SUB:%.*]], %[[VECTOR_BODY]] ] ; CHECK-NOSVE-NEXT: [[A_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv16i16( [[A]]) ; CHECK-NOSVE-NEXT: [[B_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv16i16( [[B]]) ; CHECK-NOSVE-NEXT: [[A_REAL:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 0 ; CHECK-NOSVE-NEXT: [[A_IMAG:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 1 ; CHECK-NOSVE-NEXT: [[B_REAL:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 0 ; CHECK-NOSVE-NEXT: [[B_IMAG:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 1 ; CHECK-NOSVE-NEXT: [[A_REAL_EXT:%.*]] = sext [[A_REAL]] to ; CHECK-NOSVE-NEXT: [[A_IMAG_EXT:%.*]] = sext [[A_IMAG]] to ; CHECK-NOSVE-NEXT: [[B_REAL_EXT:%.*]] = sext [[B_REAL]] to ; CHECK-NOSVE-NEXT: [[B_IMAG_EXT:%.*]] = sext [[B_IMAG]] to ; CHECK-NOSVE-NEXT: [[REAL_MUL:%.*]] = mul [[B_REAL_EXT]], [[A_REAL_EXT]] ; CHECK-NOSVE-NEXT: [[REAL_MUL_REDUCED:%.*]] = call @llvm.vector.partial.reduce.add.nxv2i64.nxv8i64( [[VEC_PHI]], [[REAL_MUL]]) ; CHECK-NOSVE-NEXT: [[IMAG_MUL:%.*]] = mul [[B_IMAG_EXT]], [[A_IMAG_EXT]] ; CHECK-NOSVE-NEXT: [[PARTIAL_REDUCE_SUB]] = call @llvm.vector.partial.reduce.add.nxv2i64.nxv8i64( [[REAL_MUL_REDUCED]], [[IMAG_MUL]]) ; CHECK-NOSVE-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-NOSVE: [[MIDDLE_BLOCK]]: ; CHECK-NOSVE-NEXT: [[TMP0:%.*]] = call i64 @llvm.vector.reduce.add.nxv2i64( [[PARTIAL_REDUCE_SUB]]) ; CHECK-NOSVE-NEXT: ret i64 [[TMP0]] ; entry: br label %vector.body vector.body: ; preds = %vector.body, %entry %vec.phi = phi [ zeroinitializer, %entry ], [ %partial.reduce.sub, %vector.body ] %a.deinterleaved = call { , } @llvm.vector.deinterleave2.v16i16( %a) %b.deinterleaved = call { , } @llvm.vector.deinterleave2.v16i16( %b) %a.real = extractvalue { , } %a.deinterleaved, 0 %a.imag = extractvalue { , } %a.deinterleaved, 1 %b.real = extractvalue { , } %b.deinterleaved, 0 %b.imag = extractvalue { , } %b.deinterleaved, 1 %a.real.ext = sext %a.real to %a.imag.ext = sext %a.imag to %b.real.ext = sext %b.real to %b.imag.ext = sext %b.imag to %real.mul = mul %b.real.ext, %a.real.ext %real.mul.reduced = call @llvm.vector.partial.reduce.add.nxv2i64.nxv8i64( %vec.phi, %real.mul) %imag.mul = mul %b.imag.ext, %a.imag.ext %partial.reduce.sub = call @llvm.vector.partial.reduce.add.nxv2i64.nxv8i64( %real.mul.reduced, %imag.mul) br i1 true, label %middle.block, label %vector.body middle.block: ; preds = %vector.body %0 = call i64 @llvm.vector.reduce.add.nxv2i64( %partial.reduce.sub) ret i64 %0 } define i64 @cdotp_i16_rot270( %a, %b) { ; CHECK-SVE2-LABEL: define i64 @cdotp_i16_rot270( ; CHECK-SVE2-SAME: [[A:%.*]], [[B:%.*]]) #[[ATTR0]] { ; CHECK-SVE2-NEXT: [[ENTRY:.*]]: ; CHECK-SVE2-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-SVE2: [[VECTOR_BODY]]: ; CHECK-SVE2-NEXT: [[TMP11:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[TMP10:%.*]], %[[VECTOR_BODY]] ] ; CHECK-SVE2-NEXT: [[TMP1:%.*]] = call @llvm.vector.extract.nxv8i16.nxv16i16( [[A]], i64 0) ; CHECK-SVE2-NEXT: [[TMP2:%.*]] = call @llvm.vector.extract.nxv8i16.nxv16i16( [[B]], i64 0) ; CHECK-SVE2-NEXT: [[TMP3:%.*]] = call @llvm.vector.extract.nxv8i16.nxv16i16( [[A]], i64 8) ; CHECK-SVE2-NEXT: [[TMP4:%.*]] = call @llvm.vector.extract.nxv8i16.nxv16i16( [[B]], i64 8) ; CHECK-SVE2-NEXT: [[TMP5:%.*]] = call @llvm.vector.extract.nxv2i64.nxv4i64( [[TMP11]], i64 0) ; CHECK-SVE2-NEXT: [[TMP6:%.*]] = call @llvm.vector.extract.nxv2i64.nxv4i64( [[TMP11]], i64 2) ; CHECK-SVE2-NEXT: [[TMP7:%.*]] = call @llvm.aarch64.sve.cdot.nxv2i64( [[TMP5]], [[TMP1]], [[TMP2]], i32 270) ; CHECK-SVE2-NEXT: [[TMP8:%.*]] = call @llvm.aarch64.sve.cdot.nxv2i64( [[TMP6]], [[TMP3]], [[TMP4]], i32 270) ; CHECK-SVE2-NEXT: [[TMP9:%.*]] = call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP7]], i64 0) ; CHECK-SVE2-NEXT: [[TMP10]] = call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP9]], [[TMP8]], i64 2) ; CHECK-SVE2-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-SVE2: [[MIDDLE_BLOCK]]: ; CHECK-SVE2-NEXT: [[TMP0:%.*]] = call i64 @llvm.vector.reduce.add.nxv4i64( [[TMP10]]) ; CHECK-SVE2-NEXT: ret i64 [[TMP0]] ; ; CHECK-SVE-LABEL: define i64 @cdotp_i16_rot270( ; CHECK-SVE-SAME: [[A:%.*]], [[B:%.*]]) #[[ATTR0]] { ; CHECK-SVE-NEXT: [[ENTRY:.*]]: ; CHECK-SVE-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-SVE: [[VECTOR_BODY]]: ; CHECK-SVE-NEXT: [[VEC_PHI:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[PARTIAL_REDUCE_SUB:%.*]], %[[VECTOR_BODY]] ] ; CHECK-SVE-NEXT: [[A_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv16i16( [[A]]) ; CHECK-SVE-NEXT: [[B_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv16i16( [[B]]) ; CHECK-SVE-NEXT: [[A_REAL:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 0 ; CHECK-SVE-NEXT: [[A_IMAG:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 1 ; CHECK-SVE-NEXT: [[B_REAL:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 0 ; CHECK-SVE-NEXT: [[B_IMAG:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 1 ; CHECK-SVE-NEXT: [[A_REAL_EXT:%.*]] = sext [[A_REAL]] to ; CHECK-SVE-NEXT: [[A_IMAG_EXT:%.*]] = sext [[A_IMAG]] to ; CHECK-SVE-NEXT: [[B_REAL_EXT:%.*]] = sext [[B_REAL]] to ; CHECK-SVE-NEXT: [[B_IMAG_EXT:%.*]] = sext [[B_IMAG]] to ; CHECK-SVE-NEXT: [[REAL_MUL:%.*]] = mul [[B_REAL_EXT]], [[A_IMAG_EXT]] ; CHECK-SVE-NEXT: [[REAL_MUL_NEG:%.*]] = sub zeroinitializer, [[REAL_MUL]] ; CHECK-SVE-NEXT: [[REAL_MUL_REDUCED:%.*]] = call @llvm.vector.partial.reduce.add.nxv2i64.nxv8i64( [[VEC_PHI]], [[REAL_MUL_NEG]]) ; CHECK-SVE-NEXT: [[IMAG_MUL:%.*]] = mul [[B_IMAG_EXT]], [[A_REAL_EXT]] ; CHECK-SVE-NEXT: [[PARTIAL_REDUCE_SUB]] = call @llvm.vector.partial.reduce.add.nxv2i64.nxv8i64( [[REAL_MUL_REDUCED]], [[IMAG_MUL]]) ; CHECK-SVE-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-SVE: [[MIDDLE_BLOCK]]: ; CHECK-SVE-NEXT: [[TMP11:%.*]] = call i64 @llvm.vector.reduce.add.nxv2i64( [[PARTIAL_REDUCE_SUB]]) ; CHECK-SVE-NEXT: ret i64 [[TMP11]] ; ; CHECK-NOSVE-LABEL: define i64 @cdotp_i16_rot270( ; CHECK-NOSVE-SAME: [[A:%.*]], [[B:%.*]]) { ; CHECK-NOSVE-NEXT: [[ENTRY:.*]]: ; CHECK-NOSVE-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-NOSVE: [[VECTOR_BODY]]: ; CHECK-NOSVE-NEXT: [[VEC_PHI:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[PARTIAL_REDUCE_SUB:%.*]], %[[VECTOR_BODY]] ] ; CHECK-NOSVE-NEXT: [[A_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv16i16( [[A]]) ; CHECK-NOSVE-NEXT: [[B_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv16i16( [[B]]) ; CHECK-NOSVE-NEXT: [[A_REAL:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 0 ; CHECK-NOSVE-NEXT: [[A_IMAG:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 1 ; CHECK-NOSVE-NEXT: [[B_REAL:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 0 ; CHECK-NOSVE-NEXT: [[B_IMAG:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 1 ; CHECK-NOSVE-NEXT: [[A_REAL_EXT:%.*]] = sext [[A_REAL]] to ; CHECK-NOSVE-NEXT: [[A_IMAG_EXT:%.*]] = sext [[A_IMAG]] to ; CHECK-NOSVE-NEXT: [[B_REAL_EXT:%.*]] = sext [[B_REAL]] to ; CHECK-NOSVE-NEXT: [[B_IMAG_EXT:%.*]] = sext [[B_IMAG]] to ; CHECK-NOSVE-NEXT: [[REAL_MUL:%.*]] = mul [[B_REAL_EXT]], [[A_IMAG_EXT]] ; CHECK-NOSVE-NEXT: [[REAL_MUL_NEG:%.*]] = sub zeroinitializer, [[REAL_MUL]] ; CHECK-NOSVE-NEXT: [[REAL_MUL_REDUCED:%.*]] = call @llvm.vector.partial.reduce.add.nxv2i64.nxv8i64( [[VEC_PHI]], [[REAL_MUL_NEG]]) ; CHECK-NOSVE-NEXT: [[IMAG_MUL:%.*]] = mul [[B_IMAG_EXT]], [[A_REAL_EXT]] ; CHECK-NOSVE-NEXT: [[PARTIAL_REDUCE_SUB]] = call @llvm.vector.partial.reduce.add.nxv2i64.nxv8i64( [[REAL_MUL_REDUCED]], [[IMAG_MUL]]) ; CHECK-NOSVE-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-NOSVE: [[MIDDLE_BLOCK]]: ; CHECK-NOSVE-NEXT: [[TMP0:%.*]] = call i64 @llvm.vector.reduce.add.nxv2i64( [[PARTIAL_REDUCE_SUB]]) ; CHECK-NOSVE-NEXT: ret i64 [[TMP0]] ; entry: br label %vector.body vector.body: ; preds = %vector.body, %entry %vec.phi = phi [ zeroinitializer, %entry ], [ %partial.reduce.sub, %vector.body ] %a.deinterleaved = call { , } @llvm.vector.deinterleave2.v16i16( %a) %b.deinterleaved = call { , } @llvm.vector.deinterleave2.v16i16( %b) %a.real = extractvalue { , } %a.deinterleaved, 0 %a.imag = extractvalue { , } %a.deinterleaved, 1 %b.real = extractvalue { , } %b.deinterleaved, 0 %b.imag = extractvalue { , } %b.deinterleaved, 1 %a.real.ext = sext %a.real to %a.imag.ext = sext %a.imag to %b.real.ext = sext %b.real to %b.imag.ext = sext %b.imag to %real.mul = mul %b.real.ext, %a.imag.ext %real.mul.neg = sub zeroinitializer, %real.mul %real.mul.reduced = call @llvm.vector.partial.reduce.add.nxv2i64.nxv8i64( %vec.phi, %real.mul.neg) %imag.mul = mul %b.imag.ext, %a.real.ext %partial.reduce.sub = call @llvm.vector.partial.reduce.add.nxv2i64.nxv8i64( %real.mul.reduced, %imag.mul) br i1 true, label %middle.block, label %vector.body middle.block: ; preds = %vector.body %0 = call i64 @llvm.vector.reduce.add.nxv2i64( %partial.reduce.sub) ret i64 %0 } define i32 @not_cdotp( %a, %b) { ; CHECK-SVE2-LABEL: define i32 @not_cdotp( ; CHECK-SVE2-SAME: [[A:%.*]], [[B:%.*]]) #[[ATTR0]] { ; CHECK-SVE2-NEXT: [[ENTRY:.*]]: ; CHECK-SVE2-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-SVE2: [[VECTOR_BODY]]: ; CHECK-SVE2-NEXT: [[VEC_PHI:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[PARTIAL_REDUCE_SUB:%.*]], %[[VECTOR_BODY]] ] ; CHECK-SVE2-NEXT: [[A_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[A]]) ; CHECK-SVE2-NEXT: [[B_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[B]]) ; CHECK-SVE2-NEXT: [[A_REAL:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 0 ; CHECK-SVE2-NEXT: [[A_IMAG:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 1 ; CHECK-SVE2-NEXT: [[B_REAL:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 0 ; CHECK-SVE2-NEXT: [[B_IMAG:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 1 ; CHECK-SVE2-NEXT: [[A_REAL_EXT:%.*]] = sext [[A_REAL]] to ; CHECK-SVE2-NEXT: [[A_IMAG_EXT:%.*]] = sext [[A_IMAG]] to ; CHECK-SVE2-NEXT: [[B_REAL_EXT:%.*]] = sext [[B_REAL]] to ; CHECK-SVE2-NEXT: [[B_IMAG_EXT:%.*]] = sext [[B_IMAG]] to ; CHECK-SVE2-NEXT: [[REAL_MUL:%.*]] = mul [[B_REAL_EXT]], [[A_REAL_EXT]] ; CHECK-SVE2-NEXT: [[REAL_MUL_NEG:%.*]] = sub zeroinitializer, [[REAL_MUL]] ; CHECK-SVE2-NEXT: [[REAL_MUL_REDUCED:%.*]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[VEC_PHI]], [[REAL_MUL_NEG]]) ; CHECK-SVE2-NEXT: [[IMAG_MUL:%.*]] = mul [[B_IMAG_EXT]], [[A_IMAG_EXT]] ; CHECK-SVE2-NEXT: [[IMAG_MUL_NEG:%.*]] = sub zeroinitializer, [[IMAG_MUL]] ; CHECK-SVE2-NEXT: [[PARTIAL_REDUCE_SUB]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[REAL_MUL_REDUCED]], [[IMAG_MUL_NEG]]) ; CHECK-SVE2-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-SVE2: [[MIDDLE_BLOCK]]: ; CHECK-SVE2-NEXT: [[TMP0:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE_SUB]]) ; CHECK-SVE2-NEXT: ret i32 [[TMP0]] ; ; CHECK-SVE-LABEL: define i32 @not_cdotp( ; CHECK-SVE-SAME: [[A:%.*]], [[B:%.*]]) #[[ATTR0]] { ; CHECK-SVE-NEXT: [[ENTRY:.*]]: ; CHECK-SVE-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-SVE: [[VECTOR_BODY]]: ; CHECK-SVE-NEXT: [[VEC_PHI:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[PARTIAL_REDUCE_SUB:%.*]], %[[VECTOR_BODY]] ] ; CHECK-SVE-NEXT: [[A_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[A]]) ; CHECK-SVE-NEXT: [[B_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[B]]) ; CHECK-SVE-NEXT: [[A_REAL:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 0 ; CHECK-SVE-NEXT: [[A_IMAG:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 1 ; CHECK-SVE-NEXT: [[B_REAL:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 0 ; CHECK-SVE-NEXT: [[B_IMAG:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 1 ; CHECK-SVE-NEXT: [[A_REAL_EXT:%.*]] = sext [[A_REAL]] to ; CHECK-SVE-NEXT: [[A_IMAG_EXT:%.*]] = sext [[A_IMAG]] to ; CHECK-SVE-NEXT: [[B_REAL_EXT:%.*]] = sext [[B_REAL]] to ; CHECK-SVE-NEXT: [[B_IMAG_EXT:%.*]] = sext [[B_IMAG]] to ; CHECK-SVE-NEXT: [[REAL_MUL:%.*]] = mul [[B_REAL_EXT]], [[A_REAL_EXT]] ; CHECK-SVE-NEXT: [[REAL_MUL_NEG:%.*]] = sub zeroinitializer, [[REAL_MUL]] ; CHECK-SVE-NEXT: [[REAL_MUL_REDUCED:%.*]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[VEC_PHI]], [[REAL_MUL_NEG]]) ; CHECK-SVE-NEXT: [[IMAG_MUL:%.*]] = mul [[B_IMAG_EXT]], [[A_IMAG_EXT]] ; CHECK-SVE-NEXT: [[IMAG_MUL_NEG:%.*]] = sub zeroinitializer, [[IMAG_MUL]] ; CHECK-SVE-NEXT: [[PARTIAL_REDUCE_SUB]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[REAL_MUL_REDUCED]], [[IMAG_MUL_NEG]]) ; CHECK-SVE-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-SVE: [[MIDDLE_BLOCK]]: ; CHECK-SVE-NEXT: [[TMP0:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE_SUB]]) ; CHECK-SVE-NEXT: ret i32 [[TMP0]] ; ; CHECK-NOSVE-LABEL: define i32 @not_cdotp( ; CHECK-NOSVE-SAME: [[A:%.*]], [[B:%.*]]) { ; CHECK-NOSVE-NEXT: [[ENTRY:.*]]: ; CHECK-NOSVE-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-NOSVE: [[VECTOR_BODY]]: ; CHECK-NOSVE-NEXT: [[VEC_PHI:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[PARTIAL_REDUCE_SUB:%.*]], %[[VECTOR_BODY]] ] ; CHECK-NOSVE-NEXT: [[A_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[A]]) ; CHECK-NOSVE-NEXT: [[B_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[B]]) ; CHECK-NOSVE-NEXT: [[A_REAL:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 0 ; CHECK-NOSVE-NEXT: [[A_IMAG:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 1 ; CHECK-NOSVE-NEXT: [[B_REAL:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 0 ; CHECK-NOSVE-NEXT: [[B_IMAG:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 1 ; CHECK-NOSVE-NEXT: [[A_REAL_EXT:%.*]] = sext [[A_REAL]] to ; CHECK-NOSVE-NEXT: [[A_IMAG_EXT:%.*]] = sext [[A_IMAG]] to ; CHECK-NOSVE-NEXT: [[B_REAL_EXT:%.*]] = sext [[B_REAL]] to ; CHECK-NOSVE-NEXT: [[B_IMAG_EXT:%.*]] = sext [[B_IMAG]] to ; CHECK-NOSVE-NEXT: [[REAL_MUL:%.*]] = mul [[B_REAL_EXT]], [[A_REAL_EXT]] ; CHECK-NOSVE-NEXT: [[REAL_MUL_NEG:%.*]] = sub zeroinitializer, [[REAL_MUL]] ; CHECK-NOSVE-NEXT: [[REAL_MUL_REDUCED:%.*]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[VEC_PHI]], [[REAL_MUL_NEG]]) ; CHECK-NOSVE-NEXT: [[IMAG_MUL:%.*]] = mul [[B_IMAG_EXT]], [[A_IMAG_EXT]] ; CHECK-NOSVE-NEXT: [[IMAG_MUL_NEG:%.*]] = sub zeroinitializer, [[IMAG_MUL]] ; CHECK-NOSVE-NEXT: [[PARTIAL_REDUCE_SUB]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[REAL_MUL_REDUCED]], [[IMAG_MUL_NEG]]) ; CHECK-NOSVE-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-NOSVE: [[MIDDLE_BLOCK]]: ; CHECK-NOSVE-NEXT: [[TMP0:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE_SUB]]) ; CHECK-NOSVE-NEXT: ret i32 [[TMP0]] ; entry: br label %vector.body vector.body: ; preds = %vector.body, %entry %vec.phi = phi [ zeroinitializer, %entry ], [ %partial.reduce.sub, %vector.body ] %a.deinterleaved = call { , } @llvm.vector.deinterleave2.v32i8( %a) %b.deinterleaved = call { , } @llvm.vector.deinterleave2.v32i8( %b) %a.real = extractvalue { , } %a.deinterleaved, 0 %a.imag = extractvalue { , } %a.deinterleaved, 1 %b.real = extractvalue { , } %b.deinterleaved, 0 %b.imag = extractvalue { , } %b.deinterleaved, 1 %a.real.ext = sext %a.real to %a.imag.ext = sext %a.imag to %b.real.ext = sext %b.real to %b.imag.ext = sext %b.imag to %real.mul = mul %b.real.ext, %a.real.ext %real.mul.neg = sub zeroinitializer, %real.mul %real.mul.reduced = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( %vec.phi, %real.mul.neg) %imag.mul = mul %b.imag.ext, %a.imag.ext %imag.mul.neg = sub zeroinitializer, %imag.mul %partial.reduce.sub = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( %real.mul.reduced, %imag.mul.neg) br i1 true, label %middle.block, label %vector.body middle.block: ; preds = %vector.body %0 = call i32 @llvm.vector.reduce.add.nxv4i32( %partial.reduce.sub) ret i32 %0 } define i16 @invalid_type( %a, %b) { ; CHECK-SVE2-LABEL: define i16 @invalid_type( ; CHECK-SVE2-SAME: [[A:%.*]], [[B:%.*]]) #[[ATTR0]] { ; CHECK-SVE2-NEXT: [[ENTRY:.*]]: ; CHECK-SVE2-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-SVE2: [[VECTOR_BODY]]: ; CHECK-SVE2-NEXT: [[VEC_PHI:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[PARTIAL_REDUCE_SUB:%.*]], %[[VECTOR_BODY]] ] ; CHECK-SVE2-NEXT: [[A_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[A]]) ; CHECK-SVE2-NEXT: [[B_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[B]]) ; CHECK-SVE2-NEXT: [[A_REAL:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 0 ; CHECK-SVE2-NEXT: [[A_IMAG:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 1 ; CHECK-SVE2-NEXT: [[B_REAL:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 0 ; CHECK-SVE2-NEXT: [[B_IMAG:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 1 ; CHECK-SVE2-NEXT: [[A_REAL_EXT:%.*]] = sext [[A_REAL]] to ; CHECK-SVE2-NEXT: [[A_IMAG_EXT:%.*]] = sext [[A_IMAG]] to ; CHECK-SVE2-NEXT: [[B_REAL_EXT:%.*]] = sext [[B_REAL]] to ; CHECK-SVE2-NEXT: [[B_IMAG_EXT:%.*]] = sext [[B_IMAG]] to ; CHECK-SVE2-NEXT: [[REAL_MUL:%.*]] = mul [[B_REAL_EXT]], [[A_REAL_EXT]] ; CHECK-SVE2-NEXT: [[REAL_MUL_REDUCED:%.*]] = call @llvm.vector.partial.reduce.add.nxv8i16.nxv16i32( [[VEC_PHI]], [[REAL_MUL]]) ; CHECK-SVE2-NEXT: [[IMAG_MUL:%.*]] = mul [[B_IMAG_EXT]], [[A_IMAG_EXT]] ; CHECK-SVE2-NEXT: [[IMAG_MUL_NEG:%.*]] = sub zeroinitializer, [[IMAG_MUL]] ; CHECK-SVE2-NEXT: [[PARTIAL_REDUCE_SUB]] = call @llvm.vector.partial.reduce.add.nxv8i16.nxv16i32( [[REAL_MUL_REDUCED]], [[IMAG_MUL_NEG]]) ; CHECK-SVE2-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-SVE2: [[MIDDLE_BLOCK]]: ; CHECK-SVE2-NEXT: [[TMP0:%.*]] = call i16 @llvm.vector.reduce.add.nxv8i16( [[PARTIAL_REDUCE_SUB]]) ; CHECK-SVE2-NEXT: ret i16 [[TMP0]] ; ; CHECK-SVE-LABEL: define i16 @invalid_type( ; CHECK-SVE-SAME: [[A:%.*]], [[B:%.*]]) #[[ATTR0]] { ; CHECK-SVE-NEXT: [[ENTRY:.*]]: ; CHECK-SVE-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-SVE: [[VECTOR_BODY]]: ; CHECK-SVE-NEXT: [[VEC_PHI:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[PARTIAL_REDUCE_SUB:%.*]], %[[VECTOR_BODY]] ] ; CHECK-SVE-NEXT: [[A_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[A]]) ; CHECK-SVE-NEXT: [[B_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[B]]) ; CHECK-SVE-NEXT: [[A_REAL:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 0 ; CHECK-SVE-NEXT: [[A_IMAG:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 1 ; CHECK-SVE-NEXT: [[B_REAL:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 0 ; CHECK-SVE-NEXT: [[B_IMAG:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 1 ; CHECK-SVE-NEXT: [[A_REAL_EXT:%.*]] = sext [[A_REAL]] to ; CHECK-SVE-NEXT: [[A_IMAG_EXT:%.*]] = sext [[A_IMAG]] to ; CHECK-SVE-NEXT: [[B_REAL_EXT:%.*]] = sext [[B_REAL]] to ; CHECK-SVE-NEXT: [[B_IMAG_EXT:%.*]] = sext [[B_IMAG]] to ; CHECK-SVE-NEXT: [[REAL_MUL:%.*]] = mul [[B_REAL_EXT]], [[A_REAL_EXT]] ; CHECK-SVE-NEXT: [[REAL_MUL_REDUCED:%.*]] = call @llvm.vector.partial.reduce.add.nxv8i16.nxv16i32( [[VEC_PHI]], [[REAL_MUL]]) ; CHECK-SVE-NEXT: [[IMAG_MUL:%.*]] = mul [[B_IMAG_EXT]], [[A_IMAG_EXT]] ; CHECK-SVE-NEXT: [[IMAG_MUL_NEG:%.*]] = sub zeroinitializer, [[IMAG_MUL]] ; CHECK-SVE-NEXT: [[PARTIAL_REDUCE_SUB]] = call @llvm.vector.partial.reduce.add.nxv8i16.nxv16i32( [[REAL_MUL_REDUCED]], [[IMAG_MUL_NEG]]) ; CHECK-SVE-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-SVE: [[MIDDLE_BLOCK]]: ; CHECK-SVE-NEXT: [[TMP0:%.*]] = call i16 @llvm.vector.reduce.add.nxv8i16( [[PARTIAL_REDUCE_SUB]]) ; CHECK-SVE-NEXT: ret i16 [[TMP0]] ; ; CHECK-NOSVE-LABEL: define i16 @invalid_type( ; CHECK-NOSVE-SAME: [[A:%.*]], [[B:%.*]]) { ; CHECK-NOSVE-NEXT: [[ENTRY:.*]]: ; CHECK-NOSVE-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-NOSVE: [[VECTOR_BODY]]: ; CHECK-NOSVE-NEXT: [[VEC_PHI:%.*]] = phi [ zeroinitializer, %[[ENTRY]] ], [ [[PARTIAL_REDUCE_SUB:%.*]], %[[VECTOR_BODY]] ] ; CHECK-NOSVE-NEXT: [[A_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[A]]) ; CHECK-NOSVE-NEXT: [[B_DEINTERLEAVED:%.*]] = call { , } @llvm.vector.deinterleave2.nxv32i8( [[B]]) ; CHECK-NOSVE-NEXT: [[A_REAL:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 0 ; CHECK-NOSVE-NEXT: [[A_IMAG:%.*]] = extractvalue { , } [[A_DEINTERLEAVED]], 1 ; CHECK-NOSVE-NEXT: [[B_REAL:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 0 ; CHECK-NOSVE-NEXT: [[B_IMAG:%.*]] = extractvalue { , } [[B_DEINTERLEAVED]], 1 ; CHECK-NOSVE-NEXT: [[A_REAL_EXT:%.*]] = sext [[A_REAL]] to ; CHECK-NOSVE-NEXT: [[A_IMAG_EXT:%.*]] = sext [[A_IMAG]] to ; CHECK-NOSVE-NEXT: [[B_REAL_EXT:%.*]] = sext [[B_REAL]] to ; CHECK-NOSVE-NEXT: [[B_IMAG_EXT:%.*]] = sext [[B_IMAG]] to ; CHECK-NOSVE-NEXT: [[REAL_MUL:%.*]] = mul [[B_REAL_EXT]], [[A_REAL_EXT]] ; CHECK-NOSVE-NEXT: [[REAL_MUL_REDUCED:%.*]] = call @llvm.vector.partial.reduce.add.nxv8i16.nxv16i32( [[VEC_PHI]], [[REAL_MUL]]) ; CHECK-NOSVE-NEXT: [[IMAG_MUL:%.*]] = mul [[B_IMAG_EXT]], [[A_IMAG_EXT]] ; CHECK-NOSVE-NEXT: [[IMAG_MUL_NEG:%.*]] = sub zeroinitializer, [[IMAG_MUL]] ; CHECK-NOSVE-NEXT: [[PARTIAL_REDUCE_SUB]] = call @llvm.vector.partial.reduce.add.nxv8i16.nxv16i32( [[REAL_MUL_REDUCED]], [[IMAG_MUL_NEG]]) ; CHECK-NOSVE-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-NOSVE: [[MIDDLE_BLOCK]]: ; CHECK-NOSVE-NEXT: [[TMP0:%.*]] = call i16 @llvm.vector.reduce.add.nxv8i16( [[PARTIAL_REDUCE_SUB]]) ; CHECK-NOSVE-NEXT: ret i16 [[TMP0]] ; entry: br label %vector.body vector.body: ; preds = %vector.body, %entry %vec.phi = phi [ zeroinitializer, %entry ], [ %partial.reduce.sub, %vector.body ] %a.deinterleaved = call { , } @llvm.vector.deinterleave2.v32i8( %a) %b.deinterleaved = call { , } @llvm.vector.deinterleave2.v32i8( %b) %a.real = extractvalue { , } %a.deinterleaved, 0 %a.imag = extractvalue { , } %a.deinterleaved, 1 %b.real = extractvalue { , } %b.deinterleaved, 0 %b.imag = extractvalue { , } %b.deinterleaved, 1 %a.real.ext = sext %a.real to %a.imag.ext = sext %a.imag to %b.real.ext = sext %b.real to %b.imag.ext = sext %b.imag to %real.mul = mul %b.real.ext, %a.real.ext %real.mul.reduced = call @llvm.vector.partial.reduce.add.nxv8i16.nxv16i32( %vec.phi, %real.mul) %imag.mul = mul %b.imag.ext, %a.imag.ext %imag.mul.neg = sub zeroinitializer, %imag.mul %partial.reduce.sub = call @llvm.vector.partial.reduce.add.nxv8i16.nxv16i32( %real.mul.reduced, %imag.mul.neg) br i1 true, label %middle.block, label %vector.body middle.block: ; preds = %vector.body %0 = call i16 @llvm.vector.reduce.add.nxv8i16( %partial.reduce.sub) ret i16 %0 } define i32 @not_cdotp_i8_rot0_fixed_length(<32 x i8> %a, <32 x i8> %b) { ; CHECK-SVE2-LABEL: define i32 @not_cdotp_i8_rot0_fixed_length( ; CHECK-SVE2-SAME: <32 x i8> [[A:%.*]], <32 x i8> [[B:%.*]]) #[[ATTR0]] { ; CHECK-SVE2-NEXT: [[ENTRY:.*]]: ; CHECK-SVE2-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-SVE2: [[VECTOR_BODY]]: ; CHECK-SVE2-NEXT: [[VEC_PHI:%.*]] = phi <4 x i32> [ zeroinitializer, %[[ENTRY]] ], [ [[PARTIAL_REDUCE_SUB:%.*]], %[[VECTOR_BODY]] ] ; CHECK-SVE2-NEXT: [[A_DEINTERLEAVED:%.*]] = call { <16 x i8>, <16 x i8> } @llvm.vector.deinterleave2.v32i8(<32 x i8> [[A]]) ; CHECK-SVE2-NEXT: [[B_DEINTERLEAVED:%.*]] = call { <16 x i8>, <16 x i8> } @llvm.vector.deinterleave2.v32i8(<32 x i8> [[B]]) ; CHECK-SVE2-NEXT: [[A_REAL:%.*]] = extractvalue { <16 x i8>, <16 x i8> } [[A_DEINTERLEAVED]], 0 ; CHECK-SVE2-NEXT: [[A_IMAG:%.*]] = extractvalue { <16 x i8>, <16 x i8> } [[A_DEINTERLEAVED]], 1 ; CHECK-SVE2-NEXT: [[B_REAL:%.*]] = extractvalue { <16 x i8>, <16 x i8> } [[B_DEINTERLEAVED]], 0 ; CHECK-SVE2-NEXT: [[B_IMAG:%.*]] = extractvalue { <16 x i8>, <16 x i8> } [[B_DEINTERLEAVED]], 1 ; CHECK-SVE2-NEXT: [[A_REAL_EXT:%.*]] = sext <16 x i8> [[A_REAL]] to <16 x i32> ; CHECK-SVE2-NEXT: [[A_IMAG_EXT:%.*]] = sext <16 x i8> [[A_IMAG]] to <16 x i32> ; CHECK-SVE2-NEXT: [[B_REAL_EXT:%.*]] = sext <16 x i8> [[B_REAL]] to <16 x i32> ; CHECK-SVE2-NEXT: [[B_IMAG_EXT:%.*]] = sext <16 x i8> [[B_IMAG]] to <16 x i32> ; CHECK-SVE2-NEXT: [[REAL_MUL:%.*]] = mul <16 x i32> [[B_REAL_EXT]], [[A_REAL_EXT]] ; CHECK-SVE2-NEXT: [[REAL_MUL_REDUCED:%.*]] = call <4 x i32> @llvm.vector.partial.reduce.add.v4i32.v16i32(<4 x i32> [[VEC_PHI]], <16 x i32> [[REAL_MUL]]) ; CHECK-SVE2-NEXT: [[IMAG_MUL:%.*]] = mul <16 x i32> [[B_IMAG_EXT]], [[A_IMAG_EXT]] ; CHECK-SVE2-NEXT: [[IMAG_MUL_NEG:%.*]] = sub <16 x i32> zeroinitializer, [[IMAG_MUL]] ; CHECK-SVE2-NEXT: [[PARTIAL_REDUCE_SUB]] = call <4 x i32> @llvm.vector.partial.reduce.add.v4i32.v16i32(<4 x i32> [[REAL_MUL_REDUCED]], <16 x i32> [[IMAG_MUL_NEG]]) ; CHECK-SVE2-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-SVE2: [[MIDDLE_BLOCK]]: ; CHECK-SVE2-NEXT: [[TMP0:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[PARTIAL_REDUCE_SUB]]) ; CHECK-SVE2-NEXT: ret i32 [[TMP0]] ; ; CHECK-SVE-LABEL: define i32 @not_cdotp_i8_rot0_fixed_length( ; CHECK-SVE-SAME: <32 x i8> [[A:%.*]], <32 x i8> [[B:%.*]]) #[[ATTR0]] { ; CHECK-SVE-NEXT: [[ENTRY:.*]]: ; CHECK-SVE-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-SVE: [[VECTOR_BODY]]: ; CHECK-SVE-NEXT: [[VEC_PHI:%.*]] = phi <4 x i32> [ zeroinitializer, %[[ENTRY]] ], [ [[PARTIAL_REDUCE_SUB:%.*]], %[[VECTOR_BODY]] ] ; CHECK-SVE-NEXT: [[A_DEINTERLEAVED:%.*]] = call { <16 x i8>, <16 x i8> } @llvm.vector.deinterleave2.v32i8(<32 x i8> [[A]]) ; CHECK-SVE-NEXT: [[B_DEINTERLEAVED:%.*]] = call { <16 x i8>, <16 x i8> } @llvm.vector.deinterleave2.v32i8(<32 x i8> [[B]]) ; CHECK-SVE-NEXT: [[A_REAL:%.*]] = extractvalue { <16 x i8>, <16 x i8> } [[A_DEINTERLEAVED]], 0 ; CHECK-SVE-NEXT: [[A_IMAG:%.*]] = extractvalue { <16 x i8>, <16 x i8> } [[A_DEINTERLEAVED]], 1 ; CHECK-SVE-NEXT: [[B_REAL:%.*]] = extractvalue { <16 x i8>, <16 x i8> } [[B_DEINTERLEAVED]], 0 ; CHECK-SVE-NEXT: [[B_IMAG:%.*]] = extractvalue { <16 x i8>, <16 x i8> } [[B_DEINTERLEAVED]], 1 ; CHECK-SVE-NEXT: [[A_REAL_EXT:%.*]] = sext <16 x i8> [[A_REAL]] to <16 x i32> ; CHECK-SVE-NEXT: [[A_IMAG_EXT:%.*]] = sext <16 x i8> [[A_IMAG]] to <16 x i32> ; CHECK-SVE-NEXT: [[B_REAL_EXT:%.*]] = sext <16 x i8> [[B_REAL]] to <16 x i32> ; CHECK-SVE-NEXT: [[B_IMAG_EXT:%.*]] = sext <16 x i8> [[B_IMAG]] to <16 x i32> ; CHECK-SVE-NEXT: [[REAL_MUL:%.*]] = mul <16 x i32> [[B_REAL_EXT]], [[A_REAL_EXT]] ; CHECK-SVE-NEXT: [[REAL_MUL_REDUCED:%.*]] = call <4 x i32> @llvm.vector.partial.reduce.add.v4i32.v16i32(<4 x i32> [[VEC_PHI]], <16 x i32> [[REAL_MUL]]) ; CHECK-SVE-NEXT: [[IMAG_MUL:%.*]] = mul <16 x i32> [[B_IMAG_EXT]], [[A_IMAG_EXT]] ; CHECK-SVE-NEXT: [[IMAG_MUL_NEG:%.*]] = sub <16 x i32> zeroinitializer, [[IMAG_MUL]] ; CHECK-SVE-NEXT: [[PARTIAL_REDUCE_SUB]] = call <4 x i32> @llvm.vector.partial.reduce.add.v4i32.v16i32(<4 x i32> [[REAL_MUL_REDUCED]], <16 x i32> [[IMAG_MUL_NEG]]) ; CHECK-SVE-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-SVE: [[MIDDLE_BLOCK]]: ; CHECK-SVE-NEXT: [[TMP0:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[PARTIAL_REDUCE_SUB]]) ; CHECK-SVE-NEXT: ret i32 [[TMP0]] ; ; CHECK-NOSVE-LABEL: define i32 @not_cdotp_i8_rot0_fixed_length( ; CHECK-NOSVE-SAME: <32 x i8> [[A:%.*]], <32 x i8> [[B:%.*]]) { ; CHECK-NOSVE-NEXT: [[ENTRY:.*]]: ; CHECK-NOSVE-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK-NOSVE: [[VECTOR_BODY]]: ; CHECK-NOSVE-NEXT: [[VEC_PHI:%.*]] = phi <4 x i32> [ zeroinitializer, %[[ENTRY]] ], [ [[PARTIAL_REDUCE_SUB:%.*]], %[[VECTOR_BODY]] ] ; CHECK-NOSVE-NEXT: [[A_DEINTERLEAVED:%.*]] = call { <16 x i8>, <16 x i8> } @llvm.vector.deinterleave2.v32i8(<32 x i8> [[A]]) ; CHECK-NOSVE-NEXT: [[B_DEINTERLEAVED:%.*]] = call { <16 x i8>, <16 x i8> } @llvm.vector.deinterleave2.v32i8(<32 x i8> [[B]]) ; CHECK-NOSVE-NEXT: [[A_REAL:%.*]] = extractvalue { <16 x i8>, <16 x i8> } [[A_DEINTERLEAVED]], 0 ; CHECK-NOSVE-NEXT: [[A_IMAG:%.*]] = extractvalue { <16 x i8>, <16 x i8> } [[A_DEINTERLEAVED]], 1 ; CHECK-NOSVE-NEXT: [[B_REAL:%.*]] = extractvalue { <16 x i8>, <16 x i8> } [[B_DEINTERLEAVED]], 0 ; CHECK-NOSVE-NEXT: [[B_IMAG:%.*]] = extractvalue { <16 x i8>, <16 x i8> } [[B_DEINTERLEAVED]], 1 ; CHECK-NOSVE-NEXT: [[A_REAL_EXT:%.*]] = sext <16 x i8> [[A_REAL]] to <16 x i32> ; CHECK-NOSVE-NEXT: [[A_IMAG_EXT:%.*]] = sext <16 x i8> [[A_IMAG]] to <16 x i32> ; CHECK-NOSVE-NEXT: [[B_REAL_EXT:%.*]] = sext <16 x i8> [[B_REAL]] to <16 x i32> ; CHECK-NOSVE-NEXT: [[B_IMAG_EXT:%.*]] = sext <16 x i8> [[B_IMAG]] to <16 x i32> ; CHECK-NOSVE-NEXT: [[REAL_MUL:%.*]] = mul <16 x i32> [[B_REAL_EXT]], [[A_REAL_EXT]] ; CHECK-NOSVE-NEXT: [[REAL_MUL_REDUCED:%.*]] = call <4 x i32> @llvm.vector.partial.reduce.add.v4i32.v16i32(<4 x i32> [[VEC_PHI]], <16 x i32> [[REAL_MUL]]) ; CHECK-NOSVE-NEXT: [[IMAG_MUL:%.*]] = mul <16 x i32> [[B_IMAG_EXT]], [[A_IMAG_EXT]] ; CHECK-NOSVE-NEXT: [[IMAG_MUL_NEG:%.*]] = sub <16 x i32> zeroinitializer, [[IMAG_MUL]] ; CHECK-NOSVE-NEXT: [[PARTIAL_REDUCE_SUB]] = call <4 x i32> @llvm.vector.partial.reduce.add.v4i32.v16i32(<4 x i32> [[REAL_MUL_REDUCED]], <16 x i32> [[IMAG_MUL_NEG]]) ; CHECK-NOSVE-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK-NOSVE: [[MIDDLE_BLOCK]]: ; CHECK-NOSVE-NEXT: [[TMP0:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[PARTIAL_REDUCE_SUB]]) ; CHECK-NOSVE-NEXT: ret i32 [[TMP0]] ; entry: br label %vector.body vector.body: ; preds = %vector.body, %entry %vec.phi = phi <4 x i32> [ zeroinitializer, %entry ], [ %partial.reduce.sub, %vector.body ] %a.deinterleaved = call { <16 x i8>, <16 x i8> } @llvm.vector.deinterleave2.v32i8(<32 x i8> %a) %b.deinterleaved = call { <16 x i8>, <16 x i8> } @llvm.vector.deinterleave2.v32i8(<32 x i8> %b) %a.real = extractvalue { <16 x i8>, <16 x i8> } %a.deinterleaved, 0 %a.imag = extractvalue { <16 x i8>, <16 x i8> } %a.deinterleaved, 1 %b.real = extractvalue { <16 x i8>, <16 x i8> } %b.deinterleaved, 0 %b.imag = extractvalue { <16 x i8>, <16 x i8> } %b.deinterleaved, 1 %a.real.ext = sext <16 x i8> %a.real to <16 x i32> %a.imag.ext = sext <16 x i8> %a.imag to <16 x i32> %b.real.ext = sext <16 x i8> %b.real to <16 x i32> %b.imag.ext = sext <16 x i8> %b.imag to <16 x i32> %real.mul = mul <16 x i32> %b.real.ext, %a.real.ext %real.mul.reduced = call <4 x i32> @llvm.vector.partial.reduce.add.v4i32.v16i32(<4 x i32> %vec.phi, <16 x i32> %real.mul) %imag.mul = mul <16 x i32> %b.imag.ext, %a.imag.ext %imag.mul.neg = sub <16 x i32> zeroinitializer, %imag.mul %partial.reduce.sub = call <4 x i32> @llvm.vector.partial.reduce.add.v4i32.v16i32(<4 x i32> %real.mul.reduced, <16 x i32> %imag.mul.neg) br i1 true, label %middle.block, label %vector.body middle.block: ; preds = %vector.body %0 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %partial.reduce.sub) ret i32 %0 } declare @llvm.vector.partial.reduce.add.nxv8i16.nxv16i32(, ) declare @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32(, ) declare @llvm.vector.partial.reduce.add.nxv2i64.nxv8i32(, ) declare <4 x i32> @llvm.vector.partial.reduce.add.v4i32.v16i32(<4 x i32>, <16 x i32>) declare i32 @llvm.vector.reduce.add.v4i32(<4 x i32>) declare i32 @llvm.vector.reduce.add.nxv4i32() declare i64 @llvm.vector.reduce.add.nxv2i64()