diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index 31eb2a92b57f1..4b17e5ed326bd 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -1308,17 +1308,13 @@ bool AArch64InstrInfo::optimizePTestInstr( bool PredIsPTestLike = isPTestLikeOpcode(PredOpcode); bool PredIsWhileLike = isWhileOpcode(PredOpcode); - if (isPTrueOpcode(MaskOpcode) && (PredIsPTestLike || PredIsWhileLike)) { - // For PTEST(PTRUE_ALL, WHILE), if the element size matches the PTEST is + if (isPTrueOpcode(MaskOpcode) && (PredIsPTestLike || PredIsWhileLike) && + getElementSizeForOpcode(MaskOpcode) == + getElementSizeForOpcode(PredOpcode) && + Mask->getOperand(1).getImm() == 31) { + // For PTEST(PTRUE_ALL, WHILE), if the element size matches, the PTEST is // redundant since WHILE performs an implicit PTEST with an all active - // mask. - uint64_t MaskElementSize = getElementSizeForOpcode(MaskOpcode); - uint64_t PredElementSize = getElementSizeForOpcode(PredOpcode); - - // Must be an all active predicate of matching element size. - if ((PredElementSize != MaskElementSize) || - (Mask->getOperand(1).getImm() != 31)) - return false; + // mask. Must be an all active predicate of matching element size. // For PTEST(PTRUE_ALL, PTEST_LIKE), the PTEST is redundant if the // PTEST_LIKE instruction uses the same all active mask and the element diff --git a/llvm/test/CodeGen/AArch64/sve-ptest-removal-cmple.ll b/llvm/test/CodeGen/AArch64/sve-ptest-removal-cmple.ll index 7f664b878998d..9cd9c30d3865d 100644 --- a/llvm/test/CodeGen/AArch64/sve-ptest-removal-cmple.ll +++ b/llvm/test/CodeGen/AArch64/sve-ptest-removal-cmple.ll @@ -110,6 +110,23 @@ define i1 @cmp8_ptest_any_px( %pg, %a, %a, %b) { +; CHECK-LABEL: cmp8_ptest_any_px_bad_ptrue: +; CHECK: // %bb.0: +; CHECK-NEXT: ptrue p0.s +; CHECK-NEXT: cmpge p0.b, p0/z, z0.b, z1.b +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret + %1 = tail call @llvm.aarch64.sve.ptrue.nxv4i1(i32 31) + %2 = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( %1) + %3 = tail call @llvm.aarch64.sve.cmpge.nxv16i8( %2, %a, %b) + %4 = tail call i1 @llvm.aarch64.sve.ptest.any.nxv16i1( %2, %3) + ret i1 %4 +} + ; ; PTEST_FIRST(PG, CMP32(PG, A, B)). Can't remove PTEST since PTEST.B vs CMP.S. ; @@ -160,6 +177,24 @@ define i1 @cmp32_ptest_any_px( %pg, %a, %a, %b) { +; CHECK-LABEL: cmp32_ptest_any_px_bad_ptrue: +; CHECK: // %bb.0: +; CHECK-NEXT: ptrue p0.b +; CHECK-NEXT: cmpge p0.s, p0/z, z0.s, z1.s +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret + %1 = tail call @llvm.aarch64.sve.ptrue.nxv16i1(i32 31) + %2 = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( %1) + %3 = tail call @llvm.aarch64.sve.cmpge.nxv4i32( %2, %a, %b) + %4 = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( %3) + %5 = tail call i1 @llvm.aarch64.sve.ptest.any.nxv16i1( %1, %4) + ret i1 %5 +} + ; ============================================================================== ; PTEST_OP(X=CMP(PG, ...), X) ; ==============================================================================