diff --git a/llvm/include/llvm/CodeGen/ValueTypes.h b/llvm/include/llvm/CodeGen/ValueTypes.h --- a/llvm/include/llvm/CodeGen/ValueTypes.h +++ b/llvm/include/llvm/CodeGen/ValueTypes.h @@ -298,6 +298,7 @@ } /// Given a vector type, return the number of elements it contains. + /// This assumes a fixed-vector type. unsigned getVectorNumElements() const { #ifdef STRICT_FIXED_SIZE_VECTORS assert(isFixedLengthVector() && "Invalid vector type!"); @@ -323,7 +324,8 @@ return getExtendedVectorElementCount(); } - /// Given a vector type, return the minimum number of elements it contains. + /// Given a (possibly scalable) vector type, return the minimum number of + /// elements it contains. unsigned getVectorMinNumElements() const { return getVectorElementCount().getKnownMinValue(); } diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -15112,7 +15112,7 @@ } } - if (N0.getOpcode() != ISD::SETCC || CCVT.getVectorNumElements() != 1 || + if (N0.getOpcode() != ISD::SETCC || CCVT.getVectorMinNumElements() != 1 || CCVT.getVectorElementType() != MVT::i1) return SDValue(); diff --git a/llvm/test/CodeGen/AArch64/sve-vselect-interface-warnings.ll b/llvm/test/CodeGen/AArch64/sve-vselect-interface-warnings.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/sve-vselect-interface-warnings.ll @@ -0,0 +1,49 @@ +; RUN: llc -mtriple=aarch64-linux-unknown -mattr=+sve -o - < %s 2>%t | FileCheck %s +; RUN: FileCheck --check-prefix="WARN" --allow-empty %s <%t + +; If this check fails please read test/CodeGen/AArch64/README for instructions on how to resolve it. +; WARN-NOT: warning + +define @vselect_cmp_ne( %a, %b, %c) { + ; CHECK-LABEL: vselect_cmp_ne + ; CHECK: // %bb.0 + ; CHECK-NEXT: mov z3.d, z1.d + ; CHECK-NEXT: and z3.h, z3.h, #0xff + ; CHECK-NEXT: and z0.h, z0.h, #0xff + ; CHECK-NEXT: ptrue p0.h + ; CHECK-NEXT: cmpne p0.h, p0/z, z0.h, z3.h + ; CHECK-NEXT: sel z0.h, p0, z1.h, z2.h + ; CHECK-NEXT: ret + %cmp = icmp ne %a, %b + %d = select %cmp, %b, %c + ret %d +} + +define @vselect_cmp_sgt( %a, %b, %c) { + ; CHECK-LABEL: vselect_cmp_sgt + ; CHECK: // %bb.0 + ; CHECK-NEXT: ptrue p0.h + ; CHECK-NEXT: sxtb z3.h, p0/m, z1.h + ; CHECK-NEXT: sxtb z0.h, p0/m, z0.h + ; CHECK-NEXT: cmpgt p0.h, p0/z, z0.h, z3.h + ; CHECK-NEXT: sel z0.h, p0, z1.h, z2.h + ; CHECK-NEXT: ret + %cmp = icmp sgt %a, %b + %d = select %cmp, %b, %c + ret %d +} + +define @vselect_cmp_ugt( %a, %b, %c) { + ; CHECK-LABEL: vselect_cmp_ugt + ; CHECK: // %bb.0 + ; CHECK-NEXT: mov z3.d, z1.d + ; CHECK-NEXT: and z3.h, z3.h, #0xff + ; CHECK-NEXT: and z0.h, z0.h, #0xff + ; CHECK-NEXT: ptrue p0.h + ; CHECK-NEXT: cmphi p0.h, p0/z, z0.h, z3.h + ; CHECK-NEXT: sel z0.h, p0, z1.h, z2.h + ; CHECK-NEXT: ret + %cmp = icmp ugt %a, %b + %d = select %cmp, %b, %c + ret %d +}