Index: llvm/include/llvm/IR/IntrinsicsAArch64.td =================================================================== --- llvm/include/llvm/IR/IntrinsicsAArch64.td +++ llvm/include/llvm/IR/IntrinsicsAArch64.td @@ -909,6 +909,11 @@ LLVMVectorElementType<0>], [IntrNoMem]>; + class AdvSIMD_SVE_PTRUE_Intrinsic + : Intrinsic<[llvm_anyvector_ty], + [llvm_i32_ty], + [IntrNoMem]>; + class AdvSIMD_SVE_PUNPKHI_Intrinsic : Intrinsic<[LLVMHalfElementsVectorType<0>], [llvm_anyvector_ty], @@ -1337,6 +1342,12 @@ def int_aarch64_sve_ucvtf_f64i32 : Builtin_SVCVT<"svcvt_f64_u32_m", llvm_nxv2f64_ty, llvm_nxv4i32_ty>; // +// Predicate creation +// + +def int_aarch64_sve_ptrue : AdvSIMD_SVE_PTRUE_Intrinsic; + +// // Predicate operations // Index: llvm/lib/Target/AArch64/AArch64ISelLowering.h =================================================================== --- llvm/lib/Target/AArch64/AArch64ISelLowering.h +++ llvm/lib/Target/AArch64/AArch64ISelLowering.h @@ -205,6 +205,7 @@ UUNPKLO, INSR, + PTRUE, // Unsigned gather loads. GLD1, Index: llvm/lib/Target/AArch64/AArch64ISelLowering.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -1343,6 +1343,7 @@ case AArch64ISD::UUNPKHI: return "AArch64ISD::UUNPKHI"; case AArch64ISD::UUNPKLO: return "AArch64ISD::UUNPKLO"; case AArch64ISD::INSR: return "AArch64ISD::INSR"; + case AArch64ISD::PTRUE: return "AArch64ISD::PTRUE"; case AArch64ISD::GLD1: return "AArch64ISD::GLD1"; case AArch64ISD::GLD1_SCALED: return "AArch64ISD::GLD1_SCALED"; case AArch64ISD::GLD1_SXTW: return "AArch64ISD::GLD1_SXTW"; @@ -2907,6 +2908,9 @@ case Intrinsic::aarch64_sve_uunpklo: return DAG.getNode(AArch64ISD::UUNPKLO, dl, Op.getValueType(), Op.getOperand(1)); + case Intrinsic::aarch64_sve_ptrue: + return DAG.getNode(AArch64ISD::PTRUE, dl, Op.getValueType(), + Op.getOperand(1)); case Intrinsic::aarch64_sve_insr: { SDValue Scalar = Op.getOperand(2); Index: llvm/lib/Target/AArch64/SVEInstrFormats.td =================================================================== --- llvm/lib/Target/AArch64/SVEInstrFormats.td +++ llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -238,11 +238,12 @@ // it's important we define them first. //===----------------------------------------------------------------------===// -class sve_int_ptrue sz8_64, bits<3> opc, string asm, PPRRegOp pprty> +class sve_int_ptrue sz8_64, bits<3> opc, string asm, PPRRegOp pprty, + ValueType vt, SDPatternOperator op> : I<(outs pprty:$Pd), (ins sve_pred_enum:$pattern), asm, "\t$Pd, $pattern", "", - []>, Sched<[]> { + [(set (vt pprty:$Pd), (op sve_pred_enum:$pattern))]>, Sched<[]> { bits<4> Pd; bits<5> pattern; let Inst{31-24} = 0b00100101; @@ -258,11 +259,11 @@ let Defs = !if(!eq (opc{0}, 1), [NZCV], []); } -multiclass sve_int_ptrue opc, string asm> { - def _B : sve_int_ptrue<0b00, opc, asm, PPR8>; - def _H : sve_int_ptrue<0b01, opc, asm, PPR16>; - def _S : sve_int_ptrue<0b10, opc, asm, PPR32>; - def _D : sve_int_ptrue<0b11, opc, asm, PPR64>; +multiclass sve_int_ptrue opc, string asm, SDPatternOperator op> { + def _B : sve_int_ptrue<0b00, opc, asm, PPR8, nxv16i1, op>; + def _H : sve_int_ptrue<0b01, opc, asm, PPR16, nxv8i1, op>; + def _S : sve_int_ptrue<0b10, opc, asm, PPR32, nxv4i1, op>; + def _D : sve_int_ptrue<0b11, opc, asm, PPR64, nxv2i1, op>; def : InstAlias(NAME # _B) PPR8:$Pd, 0b11111), 1>; @@ -274,9 +275,12 @@ (!cast(NAME # _D) PPR64:$Pd, 0b11111), 1>; } +def SDT_AArch64PTrue : SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisVT<1, i32>]>; +def AArch64ptrue : SDNode<"AArch64ISD::PTRUE", SDT_AArch64PTrue>; + let Predicates = [HasSVE] in { - defm PTRUE : sve_int_ptrue<0b000, "ptrue">; - defm PTRUES : sve_int_ptrue<0b001, "ptrues">; + defm PTRUE : sve_int_ptrue<0b000, "ptrue", AArch64ptrue>; + defm PTRUES : sve_int_ptrue<0b001, "ptrues", null_frag>; } //===----------------------------------------------------------------------===// Index: llvm/test/CodeGen/AArch64/sve-intrinsics-pred-creation.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AArch64/sve-intrinsics-pred-creation.ll @@ -0,0 +1,42 @@ +; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s + +; +; PTRUE +; + +define @ptrue_b8() { +; CHECK-LABEL: ptrue_b8: +; CHECK: ptrue p0.b, pow2 +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.ptrue.nxv16i1(i32 0) + ret %out +} + +define @ptrue_b16() { +; CHECK-LABEL: ptrue_b16: +; CHECK: ptrue p0.h, vl1 +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.ptrue.nxv8i1(i32 1) + ret %out +} + +define @ptrue_b32() { +; CHECK-LABEL: ptrue_b32: +; CHECK: ptrue p0.s, mul3 +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.ptrue.nxv4i1(i32 30) + ret %out +} + +define @ptrue_b64() { +; CHECK-LABEL: ptrue_b64: +; CHECK: ptrue p0.d +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.ptrue.nxv2i1(i32 31) + ret %out +} + +declare @llvm.aarch64.sve.ptrue.nxv16i1(i32 %pattern) +declare @llvm.aarch64.sve.ptrue.nxv8i1(i32 %pattern) +declare @llvm.aarch64.sve.ptrue.nxv4i1(i32 %pattern) +declare @llvm.aarch64.sve.ptrue.nxv2i1(i32 %pattern)