If both sides of AND operations are i1 splat_vectors or PTRUE node then we can produce just i1 splat_vector as the result.
Details
Diff Detail
Event Timeline
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | ||
---|---|---|
16380 | I think you can use the existing function isAllActivePredicate to check if either of the operands is an all active-predicate. This function already looks through reinterpret nodes and already checks both the splat/ptrue case. | |
llvm/test/CodeGen/AArch64/sve-splat-one-and-ptrue.ll | ||
16 | It would also be good to have a test that uses a shufflevector to create the splat. | |
20 | Is this function call relevant? |
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | ||
---|---|---|
16275 | Rather than use a recursive function call you could just do: static SDValue findRootNonReinterpretNode(SDValue Op) { while (Op.getOpcode() == AArch64ISD::REINTERPRET_CAST) Op = Op->getOperand(0); return Op; } Perhaps that's a bit friendlier to the compiler too? |
Addressed comments.
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | ||
---|---|---|
16380 | but I need to check and return ptrue/splat node and isAllActivePredicate() just checks. |
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | ||
---|---|---|
16380 | Hi @dtemirbulatov, I'm re-reading this code and isAllActivePredicate. I actually think @sdesmalen is right and we should use isAllActivePredicate here, because your current code doesn't take into account various cases such as:
For any cases where we bail out I think it's worth adding a negative test as well. |
Hi @dtemirbulatov, this is looking better now thanks! I just have a couple more comments ...
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | ||
---|---|---|
16378 | I think this comment suggests we only support the case where both operands are i1 splat_vectors, but your code below supports only one operand being an all-active predicate. Can you update the comment to reflect that? For example, something like // If either side of the AND operation is a i1 splat_vector then return the other // operand. For example, and %splat_i1, %b -> %b and and %a, %splat_i1 -> %a. Can you add twmo test cases to cover both of these cases too? | |
llvm/test/CodeGen/AArch64/sve-splat-one-and-ptrue.ll | ||
36 | This looks like a negative test. Can you add a comment explaining why the DAG combine doesn't happen? |
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | ||
---|---|---|
16275–16281 | isAllInactivePredicate is unused now? | |
16283 | Can you commit the moving of this function as a non-functional change (as a precursory patch)? | |
16380–16383 | nit: can you replace Src with N->getOperand(0) here? It's equivalent, but it makes it a bit more intuitive to understand. | |
llvm/test/CodeGen/AArch64/sve-splat-one-and-ptrue.ll | ||
41 | I would have expected all ptrues to have folded away and to only have: ptrue p0.s Why are these AND instructions not removed? | |
46 | nit: you can remove tail for these function calls. |
llvm/test/CodeGen/AArch64/sve-splat-one-and-ptrue.ll | ||
---|---|---|
41 | In second consideration, I see that only one of these AND's can be removed. The semantics of llvm.aarch64.sve.convert.to.svbool.nxv2i1 are such that it explicitly zeroes the inactive lanes, i.e. they don't map 1-1 to REINTERPRET_CAST. |
Added combine for AArch64ISD::REINTERPRET_CAST nodes, addressed remarks.
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | ||
---|---|---|
16275–16281 | No, still in use in performVSelectCombine. |
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | ||
---|---|---|
16324–16326 | This code would simplify: t0: nxv2i1 ... t1: nxv16i1 REINTERPRET_CAST t0 t2: nxv4i1 REINTERPRET_CAST t1 t3: nxv8i1 REINTERPRET_CAST t2 t4: nxv2i1 REINTERPRET_CAST t3 into: t0 But not something like this t0: nxv2i1 ... t1: nxv16i1 REINTERPRET_CAST t0 t2: nxv4i1 REINTERPRET_CAST t1 t3: nxv8i1 REINTERPRET_CAST t2 t4: nxv16i1 REINTERPRET_CAST t3 into: t0: nxv2i1 ... t1: nxv16i1 REINTERPRET_CAST t0 I'm not sure if this is common, but it's probably more robust to do something like this: while(Op.getOpcode() == AArch64ISD::REINTERPRET_CAST && LeafOp.getValueType() != Op.getValueType()) Op = Op->getOperand(0); | |
llvm/test/CodeGen/AArch64/sve-intrinsics-reinterpret.ll | ||
128 | Nice :) | |
llvm/test/CodeGen/AArch64/sve-splat-one-and-ptrue.ll | ||
8 | Can you give these tests more meaningful names, e.g. @fold_away_ptrue_and_ptrue for @foo and @fold_away_ptrue_and_splat_predicate for bar. |
llvm/test/CodeGen/AArch64/sve-splat-one-and-ptrue.ll | ||
---|---|---|
1 | I think this is still missing tests for the more general case where only one AND operand is an all-active predicate. Your logic on line 16380 permits this more general behaviour so we ought to test it. |
LGTM with comment on the test addressed!
llvm/test/CodeGen/AArch64/sve-splat-one-and-ptrue.ll | ||
---|---|---|
37 | Can you give @foo and @bar some more meaningful names as well? |
Rather than use a recursive function call you could just do:
Perhaps that's a bit friendlier to the compiler too?