diff --git a/llvm/docs/AArch64SME.rst b/llvm/docs/AArch64SME.rst --- a/llvm/docs/AArch64SME.rst +++ b/llvm/docs/AArch64SME.rst @@ -440,7 +440,38 @@ Exception handling and ZA ------------------------- -4. References +4. Types +======== + +AArch64 Predicate-as-Counter Type +--------------------------------- + +:Overview: + +The predicate-as-counter type represents the type of a predicate-as-counter +value held in a AArch64 SVE predicate register. Such a value contains +information about the number of active lanes, the element width and a bit that +tells whether the generated mask should be inverted. ACLE intrinsics should be +used to move the predicate-as-counter value to/from a predicate vector. + +There are certain limitations on the type: + +* The type can be used for function parameters and return values. + +* The supported LLVM operations on this type are limited to ``load``, ``store``, + ``phi``, ``select`` and ``alloca`` instructions. + +The predicate-as-counter type is a scalable type. + +:Syntax: + +:: + + target("aarch64.svcount") + + + +5. References ============= .. _aarch64_sme_acle: diff --git a/llvm/lib/IR/Type.cpp b/llvm/lib/IR/Type.cpp --- a/llvm/lib/IR/Type.cpp +++ b/llvm/lib/IR/Type.cpp @@ -863,6 +863,11 @@ return TargetTypeInfo(Type::getInt8PtrTy(C, 0), TargetExtType::HasZeroInit, TargetExtType::CanBeGlobal); } + + // Opaque types in the AArch64 name space. + if (Name == "aarch64.svcount") + return TargetTypeInfo(ScalableVectorType::get(Type::getInt1Ty(C), 16)); + return TargetTypeInfo(Type::getVoidTy(C)); } diff --git a/llvm/test/Transforms/InstCombine/AArch64/sme-svcount.ll b/llvm/test/Transforms/InstCombine/AArch64/sme-svcount.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/AArch64/sme-svcount.ll @@ -0,0 +1,25 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -passes='instcombine' -S < %s | FileCheck %s + +define target("aarch64.svcount") @test_alloca_store_reload(target("aarch64.svcount") %val) nounwind { +; CHECK-LABEL: @test_alloca_store_reload( +; CHECK-NEXT: ret target("aarch64.svcount") [[VAL:%.*]] +; + %ptr = alloca target("aarch64.svcount"), align 1 + store target("aarch64.svcount") %val, ptr %ptr + %res = load target("aarch64.svcount"), ptr %ptr + ret target("aarch64.svcount") %res +} + +; Test that instcombine doesn't try to query the (scalable) size of target("aarch64.svcount") +; in foldSelectInstWithICmp. +define target("aarch64.svcount") @test_combine_on_select(target("aarch64.svcount") %x, target("aarch64.svcount") %y, i32 %k) { +; CHECK-LABEL: @test_combine_on_select( +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[K:%.*]], 42 +; CHECK-NEXT: [[X_Y:%.*]] = select i1 [[CMP]], target("aarch64.svcount") [[X:%.*]], target("aarch64.svcount") [[Y:%.*]] +; CHECK-NEXT: ret target("aarch64.svcount") [[X_Y]] +; + %cmp = icmp sgt i32 %k, 42 + %x.y = select i1 %cmp, target("aarch64.svcount") %x, target("aarch64.svcount") %y + ret target("aarch64.svcount") %x.y +} diff --git a/llvm/test/Transforms/SROA/aarch64-sme-svcount.ll b/llvm/test/Transforms/SROA/aarch64-sme-svcount.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/SROA/aarch64-sme-svcount.ll @@ -0,0 +1,12 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -passes='sroa' -S < %s | FileCheck %s + +define target("aarch64.svcount") @test_alloca_store_reload(target("aarch64.svcount") %val) nounwind { +; CHECK-LABEL: @test_alloca_store_reload( +; CHECK-NEXT: ret target("aarch64.svcount") [[VAL:%.*]] +; + %ptr = alloca target("aarch64.svcount"), align 1 + store target("aarch64.svcount") %val, ptr %ptr + %res = load target("aarch64.svcount"), ptr %ptr + ret target("aarch64.svcount") %res +}