Adds aarch64-sve-vector-bits-{min,max} to allow the size of SVE
data registers (in bits) to be specified. This allows the code
generator to make assumptions it normally couldn't. As a starting
point this information is used to mark fixed length vector types
that can fit within the specified size as legal.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Unit Tests
Event Timeline
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | ||
---|---|---|
3500 | Restricting i1 types like this seems a little weird to me. We don't need to pretend to be NEON. We want these types to be legal for similar reasons we want the other fixed vector types to be legal. I guess we could leave the check for now if it makes it easier to get simple testcases working, but I don't think this is what we want long-term. For non-i1 types, should we check the element type is legal? integer_fixedlen_vector_valuetypes() and fp_fixedlen_vector_valuetypes() can return some exotic types. | |
3512 | Non-power-of-two types are an extra complication, yes; better to leave it out for now. | |
llvm/lib/Target/AArch64/AArch64Subtarget.cpp | ||
345 | We probably want function attributes? It looks like this patch doesn't use the max size; what do you anticipate using it for? |
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | ||
---|---|---|
3500 | Part of this is me not looking for trouble at this stage and wanting to wait to see if there's a performance reason to make them legal. I think the majority of the cases can be handled after the conversion to scalable vector types, which just leaves the cross-block scenarios. However, from a functional point of view I'm trying not to make any ABI related changes. Currently the handling of i1 based vectors (well all fixed length vectors) has already been decided for NEON and so I cannot just change it in isolation without breaking compatibility with existing libraries (which don't know about SVE). In the future we'll need a function attribute that corresponds to an as yet undefined ABI. When that is in place we can relax the i1 restriction. For now though my focus is purely on block level code generation. | |
llvm/lib/Target/AArch64/AArch64Subtarget.cpp | ||
345 | When creating the patch I did spot "min-legal-vector-width" exists as a function attribute but as mentioned above I'm trying to avoid establishing anything ABI related at this stage. As part of D80385 where I've added the createPredicateForFixedVector function there's a comment that mentions the use case for the max size. Essentially when min==max we can avoid the need to create explicitly sized predicates and instead use "PTRUE ALL" as a route to select unpredicated instructions when available. |
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | ||
---|---|---|
3500 | We can mess with the ABI separately if we need to say the values are sign-extended or whatever. I'm concerned that if we don't make this legal now, we're going to end up writing a bunch of code to work around the fact that we can't produce i1 vectors after legalization. | |
3503 | isTypeLegal(VT.getVectorElementType()) probably doesn't do what you want; i8 is not a legal type. | |
llvm/lib/Target/AArch64/AArch64Subtarget.cpp | ||
345 | I guess we can leave out function attributes for now, but it's a temporary solution at best; LLVM flags are not properly usable from clang. |
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | ||
---|---|---|
3500 | Do you have any specific examples. I ask because my experience is the opposite. By keeping fixed length i1 vectors as illegal I am able to remove a lot of work that just isn't necessary to achieve my objective of supporting larger fixed length vectors. I'll admit that here I'm potentially trading a bit on performance but there's nothing binding here, it's just the order of implementation I prefer. None of this affects scalable vectors so it doesn't affect the post operation legalisation side of things. | |
3503 | That'll teach me for taking things too literally without thinking about what I'm writing :) I've changed this to an explicit list and deliberately kept it minimal as bf and 128bit element types are things I don't really care about at this stage. | |
llvm/lib/Target/AArch64/AArch64Subtarget.cpp | ||
345 | Yep, I understand. The flags allow me to write more concise tests so even when we nail down the way front-ends enables this feature I suspect the flags will still have value. |
Rebased so now all dependent filecheck work is available.
Corrected the test for legal vector element types.
Updated test to include some vector element type variation.
Okay, it sounds like we're on the same page. LGTM
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | ||
---|---|---|
3500 | Say we have something like (a==b|c==d)? e : f. In NEON, we do something with blending in vector registers. In SVE, we do not want the condition to ever be moved from predicate registers to vector registers. So now you're pattern-matching some combination of logic operators and blends to try to recover the obvious SVE code. If you aren't really doing that sort of optimization in the first iteration, transitioning later might not be a big deal. |
Restricting i1 types like this seems a little weird to me. We don't need to pretend to be NEON. We want these types to be legal for similar reasons we want the other fixed vector types to be legal. I guess we could leave the check for now if it makes it easier to get simple testcases working, but I don't think this is what we want long-term.
For non-i1 types, should we check the element type is legal? integer_fixedlen_vector_valuetypes() and fp_fixedlen_vector_valuetypes() can return some exotic types.