diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td --- a/llvm/lib/Target/AArch64/SVEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -4641,6 +4641,10 @@ (cmp $Op1, $Op2, $Op3)>; def : Pat<(predvt (AArch64setcc_z predvt:$Op1, intvt:$Op2, intvt:$Op3, invcc)), (cmp $Op1, $Op3, $Op2)>; + def : Pat<(predvt (and predvt:$Pg, (AArch64setcc_z (predvt (AArch64ptrue 31)), intvt:$Op2, intvt:$Op3, cc))), + (cmp $Pg, $Op2, $Op3)>; + def : Pat<(predvt (and predvt:$Pg, (AArch64setcc_z (predvt (AArch64ptrue 31)), intvt:$Op2, intvt:$Op3, invcc))), + (cmp $Pg, $Op3, $Op2)>; } multiclass SVE_SETCC_Pat_With_Zero %out } +; Verify general predicate is folded into the compare +define @predicated_icmp( %a, %b, %c) { +; CHECK-LABEL: predicated_icmp: +; CHECK: // %bb.0: +; CHECK-NEXT: ptrue p0.s +; CHECK-NEXT: cmpgt p0.s, p0/z, z0.s, z1.s +; CHECK-NEXT: cmpge p0.s, p0/z, z2.s, z1.s +; CHECK-NEXT: ret + %icmp1 = icmp sgt %a, %b + %icmp2 = icmp sle %b, %c + %and = and %icmp1, %icmp2 + ret %and +} + +define @predicated_icmp_unknown_lhs( %a, %b, %c) { +; CHECK-LABEL: predicated_icmp_unknown_lhs: +; CHECK: // %bb.0: +; CHECK-NEXT: cmpge p0.s, p0/z, z1.s, z0.s +; CHECK-NEXT: ret + %icmp = icmp sle %b, %c + %and = and %a, %icmp + ret %and +} + +define @predicated_icmp_unknown_rhs( %a, %b, %c) { +; CHECK-LABEL: predicated_icmp_unknown_rhs: +; CHECK: // %bb.0: +; CHECK-NEXT: cmpge p0.s, p0/z, z1.s, z0.s +; CHECK-NEXT: ret + %icmp = icmp sle %b, %c + %and = and %icmp, %a + ret %and +} declare @llvm.aarch64.sve.cmpeq.nxv16i8(, , ) declare @llvm.aarch64.sve.cmpeq.nxv8i16(, , )