Index: llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -3156,23 +3156,28 @@ if (!N) return false; + unsigned EltWidth; APInt CVal; if (auto *CN = dyn_cast(N)) { CVal = CN->getAPIntValue(); + EltWidth = CVal.getBitWidth(); } else if (auto *BV = dyn_cast(N)) { auto *CN = BV->getConstantSplatNode(); if (!CN) return false; - - // If this is a truncating build vector, truncate the splat value. - // Otherwise, we may fail to match the expected values below. - unsigned BVEltWidth = BV->getValueType(0).getScalarSizeInBits(); + EltWidth = BV->getValueType(0).getScalarSizeInBits(); CVal = CN->getAPIntValue(); - if (BVEltWidth < CVal.getBitWidth()) - CVal = CVal.trunc(BVEltWidth); - } else { + } else if (N->getOpcode() == ISD::SPLAT_VECTOR && + isa(N->getOperand(0))) { + EltWidth = N->getValueType(0).getScalarSizeInBits(); + CVal = cast(N->getOperand(0))->getAPIntValue(); + } else return false; - } + + // If this is a truncating splat, truncate the splat value. + // Otherwise, we may fail to match the expected values below. + if (EltWidth < CVal.getBitWidth()) + CVal = CVal.trunc(EltWidth); switch (getBooleanContents(N->getValueType(0))) { case UndefinedBooleanContent: Index: llvm/test/CodeGen/AArch64/sve-cmp-folds.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AArch64/sve-cmp-folds.ll @@ -0,0 +1,54 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=aarch64-linux-unknown -mattr=+sve -o - < %s | FileCheck %s + +define @not_icmp_sle_nxv8i16( %a, %b) { +; CHECK-LABEL: not_icmp_sle_nxv8i16: +; CHECK: // %bb.0: +; CHECK-NEXT: ptrue p0.h +; CHECK-NEXT: cmpgt p0.h, p0/z, z0.h, z1.h +; CHECK-NEXT: ret + %icmp = icmp sle %a, %b + %tmp = insertelement undef, i1 true, i32 0 + %ones = shufflevector %tmp, undef, zeroinitializer + %not = xor %ones, %icmp + ret %not +} + +define @not_icmp_sgt_nxv4i32( %a, %b) { +; CHECK-LABEL: not_icmp_sgt_nxv4i32: +; CHECK: // %bb.0: +; CHECK-NEXT: ptrue p0.s +; CHECK-NEXT: cmpge p0.s, p0/z, z1.s, z0.s +; CHECK-NEXT: ret + %icmp = icmp sgt %a, %b + %tmp = insertelement undef, i1 true, i32 0 + %ones = shufflevector %tmp, undef, zeroinitializer + %not = xor %icmp, %ones + ret %not +} + +define @not_fcmp_une_nxv2f64( %a, %b) { +; CHECK-LABEL: not_fcmp_une_nxv2f64: +; CHECK: // %bb.0: +; CHECK-NEXT: ptrue p0.d +; CHECK-NEXT: fcmeq p0.d, p0/z, z0.d, z1.d +; CHECK-NEXT: ret + %icmp = fcmp une %a, %b + %tmp = insertelement undef, i1 true, i32 0 + %ones = shufflevector %tmp, undef, zeroinitializer + %not = xor %icmp, %ones + ret %not +} + +define @not_fcmp_uge_nxv4f32( %a, %b) { +; CHECK-LABEL: not_fcmp_uge_nxv4f32: +; CHECK: // %bb.0: +; CHECK-NEXT: ptrue p0.s +; CHECK-NEXT: fcmgt p0.s, p0/z, z1.s, z0.s +; CHECK-NEXT: ret + %icmp = fcmp uge %a, %b + %tmp = insertelement undef, i1 true, i32 0 + %ones = shufflevector %tmp, undef, zeroinitializer + %not = xor %icmp, %ones + ret %not +} Index: llvm/test/CodeGen/RISCV/rvv/cmp-folds.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/RISCV/rvv/cmp-folds.ll @@ -0,0 +1,57 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv32 -mattr=+d,+experimental-zfh,+experimental-v \ +; RUN: -verify-machineinstrs < %s | FileCheck %s +; RUN: llc -mtriple=riscv64 -mattr=+d,+experimental-zfh,+experimental-v \ +; RUN: -verify-machineinstrs < %s | FileCheck %s + +define @not_icmp_sle_nxv8i16( %a, %b) { +; CHECK-LABEL: not_icmp_sle_nxv8i16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16, m2, ta, mu +; CHECK-NEXT: vmslt.vv v0, v10, v8 +; CHECK-NEXT: ret + %icmp = icmp sle %a, %b + %tmp = insertelement undef, i1 true, i32 0 + %ones = shufflevector %tmp, undef, zeroinitializer + %not = xor %ones, %icmp + ret %not +} + +define @not_icmp_sgt_nxv4i32( %a, %b) { +; CHECK-LABEL: not_icmp_sgt_nxv4i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, mu +; CHECK-NEXT: vmsle.vv v0, v8, v10 +; CHECK-NEXT: ret + %icmp = icmp sgt %a, %b + %tmp = insertelement undef, i1 true, i32 0 + %ones = shufflevector %tmp, undef, zeroinitializer + %not = xor %icmp, %ones + ret %not +} + +define @not_fcmp_une_nxv2f64( %a, %b) { +; CHECK-LABEL: not_fcmp_une_nxv2f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64, m2, ta, mu +; CHECK-NEXT: vmfeq.vv v0, v8, v10 +; CHECK-NEXT: ret + %icmp = fcmp une %a, %b + %tmp = insertelement undef, i1 true, i32 0 + %ones = shufflevector %tmp, undef, zeroinitializer + %not = xor %icmp, %ones + ret %not +} + +define @not_fcmp_uge_nxv4f32( %a, %b) { +; CHECK-LABEL: not_fcmp_uge_nxv4f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, mu +; CHECK-NEXT: vmflt.vv v0, v8, v10 +; CHECK-NEXT: ret + %icmp = fcmp uge %a, %b + %tmp = insertelement undef, i1 true, i32 0 + %ones = shufflevector %tmp, undef, zeroinitializer + %not = xor %icmp, %ones + ret %not +}