diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h @@ -323,6 +323,7 @@ INSR, PTEST, PTRUE, + PFALSE, BITREVERSE_MERGE_PASSTHRU, BSWAP_MERGE_PASSTHRU, 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 @@ -2200,6 +2200,7 @@ MAKE_CASE(AArch64ISD::INSR) MAKE_CASE(AArch64ISD::PTEST) MAKE_CASE(AArch64ISD::PTRUE) + MAKE_CASE(AArch64ISD::PFALSE) MAKE_CASE(AArch64ISD::LD1_MERGE_ZERO) MAKE_CASE(AArch64ISD::LD1S_MERGE_ZERO) MAKE_CASE(AArch64ISD::LDNF1_MERGE_ZERO) @@ -9984,7 +9985,7 @@ // lowering code. if (auto *ConstVal = dyn_cast(SplatVal)) { if (ConstVal->isZero()) - return SDValue(DAG.getMachineNode(AArch64::PFALSE, dl, VT), 0); + return DAG.getNode(AArch64ISD::PFALSE, dl, VT); if (ConstVal->isOne()) return getPTrue(DAG, dl, VT, AArch64SVEPredPattern::all); } diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -730,7 +730,7 @@ defm BRKBS_PPzP : sve_int_break_z<0b110, "brkbs", null_frag>; def PTEST_PP : sve_int_ptest<0b010000, "ptest">; - def PFALSE : sve_int_pfalse<0b000000, "pfalse">; + defm PFALSE : sve_int_pfalse<0b000000, "pfalse">; defm PFIRST : sve_int_pfirst<0b00000, "pfirst", int_aarch64_sve_pfirst>; defm PNEXT : sve_int_pnext<0b00110, "pnext", int_aarch64_sve_pnext>; 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 @@ -334,6 +334,8 @@ def SDT_AArch64PTrue : SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisVT<1, i32>]>; def AArch64ptrue : SDNode<"AArch64ISD::PTRUE", SDT_AArch64PTrue>; +def SDT_AArch64PFalse : SDTypeProfile<1, 0, [SDTCisVec<0>, SDTCVecEltisVT<0, i1>]>; +def AArch64pfalse : SDNode<"AArch64ISD::PFALSE", SDT_AArch64PFalse>; let Predicates = [HasSVEorStreamingSVE] in { defm PTRUE : sve_int_ptrue<0b000, "ptrue", AArch64ptrue>; @@ -609,6 +611,15 @@ let isReMaterializable = 1; } +multiclass sve_int_pfalse opc, string asm> { + def NAME : sve_int_pfalse; + + def : Pat<(nxv16i1 (AArch64pfalse)), (!cast(NAME))>; + def : Pat<(nxv8i1 (AArch64pfalse)), (!cast(NAME))>; + def : Pat<(nxv4i1 (AArch64pfalse)), (!cast(NAME))>; + def : Pat<(nxv2i1 (AArch64pfalse)), (!cast(NAME))>; +} + class sve_int_ptest opc, string asm> : I<(outs), (ins PPRAny:$Pg, PPR8:$Pn), asm, "\t$Pg, $Pn", diff --git a/llvm/test/CodeGen/AArch64/sve-pfalse-machine-cse.mir b/llvm/test/CodeGen/AArch64/sve-pfalse-machine-cse.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/sve-pfalse-machine-cse.mir @@ -0,0 +1,26 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -run-pass=machine-cse -mtriple=aarch64 -mattr=+sve -o - %s | FileCheck %s +--- +name: pfalse +tracksRegLiveness: true +body: | + bb.0: + liveins: $p0 + + ; CHECK-LABEL: name: pfalse + ; CHECK: liveins: $p0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:ppr = COPY $p0 + ; CHECK-NEXT: [[PFALSE:%[0-9]+]]:ppr = PFALSE + ; CHECK-NEXT: [[UZP1_PPP_B:%[0-9]+]]:ppr = UZP1_PPP_B [[COPY]], [[PFALSE]] + ; CHECK-NEXT: [[UZP1_PPP_B1:%[0-9]+]]:ppr = UZP1_PPP_B killed [[UZP1_PPP_B]], [[PFALSE]] + ; CHECK-NEXT: $p0 = COPY [[UZP1_PPP_B1]] + ; CHECK-NEXT: RET_ReallyLR implicit $p0 + %0:ppr = COPY $p0 + %2:ppr = PFALSE + %3:ppr = UZP1_PPP_B %0, %2 + %4:ppr = PFALSE + %5:ppr = UZP1_PPP_B killed %3, %4 + $p0 = COPY %5 + RET_ReallyLR implicit $p0 +...