[PATCH] D38536: Improve lookThroughCast function.
Sanjay Patel via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 16 13:09:42 PDT 2017
spatel added a comment.
In https://reviews.llvm.org/D38536#898338, @ArturGainullin wrote:
> I have read more carefully your comment. As far as I understood in https://reviews.llvm.org/D26556 you want to change the process of decision making for function that folds cast operation into select.
> According to suggestion from Eli you should try to match the size of a select to a cmp of its condition operand as a final result.
That's right. The patch I was imagining would be something like this:
Index: lib/Transforms/InstCombine/InstCombineSelect.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineSelect.cpp (revision 315902)
+++ lib/Transforms/InstCombine/InstCombineSelect.cpp (working copy)
@@ -748,6 +748,22 @@
}
}
+ // If the select uses a truncated operand of the compare, try to select using the
+ // same value as the compare. This may then be matched as a canonical min/max
+ // op, and it usually produces better codegen for vector types because the
+ // compare result is often used as a mask value for the select.
+ Constant *CmpC, *SelC;
+ if (match(CmpRHS, m_Constant(CmpC)) && match(FalseVal, m_Constant(SelC)) &&
+ match(TrueVal, m_Trunc(m_Specific(CmpLHS)))) {
+ Type *NarrowType = SelC->getType();
+ if (ConstantExpr::getTrunc(CmpC, NarrowType) == SelC) {
+ select (icmp Pred X, CmpC), (trunc X), SelC -->
+ trunc (select (icmp Pred X, CmpC), X, CmpC
+ Value *WideSel = Builder.CreateSelect(ICI, CmpLHS, CmpC);
+ return new TruncInst(WideSel, NarrowType);
+ }
+ }
+
...but I suppose treating this as another special-case min/max is fine too. However, the tests you have are both not minimized (we don't need a clamp pattern) and not complete. Please try this case too:
define <2 x i8> @min_through_cast_vec(<2 x i32> %x) {
%cmp = icmp slt <2 x i32> %x, <i32 510, i32 511>
%max_trunc = trunc <2 x i32> %x to <2 x i8>
%res = select <2 x i1> %cmp, <2 x i8> %max_trunc, <2 x i8> <i8 254, i8 255>
ret <2 x i8> %res
}
Once you determine that the compare is against a constant, I don't think you need to recreate that constant - just use that constant:
if (match(CmpI->getOperand(1), m_Constant(CmpConst)))
CastedTo = CmpConst;
https://reviews.llvm.org/D38536
More information about the llvm-commits
mailing list