[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