[llvm] r333106 - [InstCombine] Fold unfolded masked merge pattern with variable mask!

Eric Christopher via llvm-commits llvm-commits at lists.llvm.org
Wed May 30 20:48:49 PDT 2018


Hi Roman, Sanjoy,

With this patch we're seeing some msan warnings - one thought that came up
is whether or not this transformation is taking undef properly into
account. If 'y' is undef here and we could evaluate it twice and get
different results is it still valid?

One example:

// constant_time_select_w returns (mask & a) | (~mask & b). When |mask| is
all
// 1s or all 0s (as returned by the methods above), the select methods
return
// either |a| (if |mask| is nonzero) or |b| (if |mask| is zero).
static inline crypto_word_t constant_time_select_w(crypto_word_t mask,
                                                   crypto_word_t a,
                                                   crypto_word_t b) {
  return (mask & a) | (~mask & b);
}

which is used all over the place to initialize variables and perform a
constant time select.

Thoughts? Are we off base? Something else wrong?

Thanks!

-eric

On Wed, May 23, 2018 at 10:51 AM Roman Lebedev via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> Author: lebedevri
> Date: Wed May 23 10:47:52 2018
> New Revision: 333106
>
> URL: http://llvm.org/viewvc/llvm-project?rev=333106&view=rev
> Log:
> [InstCombine] Fold unfolded masked merge pattern with variable mask!
>
> Summary:
> Finally fixes [[ https://bugs.llvm.org/show_bug.cgi?id=6773 | PR6773 ]].
>
> Now that the backend is all done, we can finally fold it!
>
> The canonical unfolded masked merge pattern is
> ```(x &  m) | (y & ~m)```
> There is a second, equivalent variant:
> ```(x | ~m) & (y |  m)```
> Only one of them (the or-of-and's i think) is canonical.
> And if the mask is not a constant, we should fold it to:
> ```((x ^ y) & M) ^ y```
>
> https://rise4fun.com/Alive/ndQw
>
> Reviewers: spatel, craig.topper
>
> Reviewed By: spatel
>
> Subscribers: nicholas, RKSimon, llvm-commits
>
> Differential Revision: https://reviews.llvm.org/D46814
>
> Modified:
>     llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
>     llvm/trunk/test/Transforms/InstCombine/and-or-not.ll
>     llvm/trunk/test/Transforms/InstCombine/masked-merge-add.ll
>     llvm/trunk/test/Transforms/InstCombine/masked-merge-and-of-ors.ll
>     llvm/trunk/test/Transforms/InstCombine/masked-merge-or.ll
>     llvm/trunk/test/Transforms/InstCombine/masked-merge-xor.ll
>     llvm/trunk/test/Transforms/InstCombine/vec_sext.ll
>
> Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp?rev=333106&r1=333105&r2=333106&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
> (original)
> +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Wed May
> 23 10:47:52 2018
> @@ -748,6 +748,9 @@ static Value *foldLogOpOfMaskedICmps(ICm
>    return nullptr;
>  }
>
> +static Instruction *foldMaskedMerge(BinaryOperator &I,
> +                                    InstCombiner::BuilderTy &Builder);
> +
>  /// Try to fold a signed range checked with lower bound 0 to an unsigned
> icmp.
>  /// Example: (icmp sge x, 0) & (icmp slt x, n) --> icmp ult x, n
>  /// If \p Inverted is true then the check is for the inverted range, e.g.
> @@ -1648,6 +1651,9 @@ Instruction *InstCombiner::visitAnd(Bina
>        A->getType()->isIntOrIntVectorTy(1))
>      return SelectInst::Create(A, Op0,
> Constant::getNullValue(I.getType()));
>
> +  if (Instruction *MM = foldMaskedMerge(I, Builder))
> +    return MM;
> +
>    return Changed ? &I : nullptr;
>  }
>
> @@ -2287,6 +2293,9 @@ Instruction *InstCombiner::visitOr(Binar
>      }
>    }
>
> +  if (Instruction *MM = foldMaskedMerge(I, Builder))
> +    return MM;
> +
>    return Changed ? &I : nullptr;
>  }
>
> @@ -2421,6 +2430,33 @@ Value *InstCombiner::foldXorOfICmps(ICmp
>
>    return nullptr;
>  }
> +
> +/// Bitwise masked merge (bitwise select) is typically coded as:
> +/// (x & m) | (y & ~m)
> +/// Another variant is:
> +/// (x | ~m) & (y | m)
> +/// Canonicalize those to a form with one less IR instruction:
> +/// ((x ^ y) & m) ^ y
> +static Instruction *foldMaskedMerge(BinaryOperator &I,
> +                                    InstCombiner::BuilderTy &Builder) {
> +  Value *X, *Y;
> +
> +  Value *M;
> +  if (match(&I, m_c_Or(m_OneUse(m_c_And(m_Value(Y), m_Not(m_Value(M)))),
> +                       m_OneUse(m_c_And(m_Value(X), m_Deferred(M))))) ||
> +      match(&I, m_c_And(m_OneUse(m_c_Or(m_Value(X), m_Not(m_Value(M)))),
> +                        m_OneUse(m_c_Or(m_Value(Y), m_Deferred(M)))))) {
> +    assert(!isa<Constant>(M) && "Shouldn't have matched a constant.");
> +
> +    Value *D = Builder.CreateXor(X, Y);
> +    Value *A = Builder.CreateAnd(D, M);
> +    return BinaryOperator::CreateXor(A, Y);
> +  }
> +
> +  // FIXME: we still want to canonicalize the patterns with constants
> somewhat.
> +
> +  return nullptr;
> +}
>
>  /// If we have a masked merge, in the canonical form of:
>  /// (assuming that A only has one use.)
>
> Modified: llvm/trunk/test/Transforms/InstCombine/and-or-not.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/and-or-not.ll?rev=333106&r1=333105&r2=333106&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/Transforms/InstCombine/and-or-not.ll (original)
> +++ llvm/trunk/test/Transforms/InstCombine/and-or-not.ll Wed May 23
> 10:47:52 2018
> @@ -502,11 +502,10 @@ define i32 @xor_to_xor12(float %fa, floa
>
>  define i64 @PR32830(i64 %a, i64 %b, i64 %c) {
>  ; CHECK-LABEL: @PR32830(
> -; CHECK-NEXT:    [[NOTA:%.*]] = xor i64 [[A:%.*]], -1
>  ; CHECK-NEXT:    [[NOTB:%.*]] = xor i64 [[B:%.*]], -1
> -; CHECK-NEXT:    [[OR1:%.*]] = or i64 [[NOTB]], [[A]]
> -; CHECK-NEXT:    [[OR2:%.*]] = or i64 [[NOTA]], [[C:%.*]]
> -; CHECK-NEXT:    [[AND:%.*]] = and i64 [[OR1]], [[OR2]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i64 [[NOTB]], [[C:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i64 [[TMP1]], [[A:%.*]]
> +; CHECK-NEXT:    [[AND:%.*]] = xor i64 [[TMP2]], [[NOTB]]
>  ; CHECK-NEXT:    ret i64 [[AND]]
>  ;
>    %nota = xor i64 %a, -1
>
> Modified: llvm/trunk/test/Transforms/InstCombine/masked-merge-add.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/masked-merge-add.ll?rev=333106&r1=333105&r2=333106&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/Transforms/InstCombine/masked-merge-add.ll (original)
> +++ llvm/trunk/test/Transforms/InstCombine/masked-merge-add.ll Wed May 23
> 10:47:52 2018
> @@ -18,10 +18,9 @@
>
>  define i32 @p(i32 %x, i32 %y, i32 %m) {
>  ; CHECK-LABEL: @p(
> -; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1
> -; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[NEG]], [[Y:%.*]]
> -; CHECK-NEXT:    [[RET:%.*]] = or i32 [[AND]], [[AND1]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %and = and i32 %x, %m
> @@ -33,10 +32,9 @@ define i32 @p(i32 %x, i32 %y, i32 %m) {
>
>  define <2 x i32> @p_splatvec(<2 x i32> %x, <2 x i32> %y, <2 x i32> %m) {
>  ; CHECK-LABEL: @p_splatvec(
> -; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X:%.*]], [[M:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor <2 x i32> [[M]], <i32 -1, i32 -1>
> -; CHECK-NEXT:    [[AND1:%.*]] = and <2 x i32> [[NEG]], [[Y:%.*]]
> -; CHECK-NEXT:    [[RET:%.*]] = or <2 x i32> [[AND]], [[AND1]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i32> [[X:%.*]], [[Y:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor <2 x i32> [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret <2 x i32> [[RET]]
>  ;
>    %and = and <2 x i32> %x, %m
> @@ -48,10 +46,9 @@ define <2 x i32> @p_splatvec(<2 x i32> %
>
>  define <3 x i32> @p_vec_undef(<3 x i32> %x, <3 x i32> %y, <3 x i32> %m) {
>  ; CHECK-LABEL: @p_vec_undef(
> -; CHECK-NEXT:    [[AND:%.*]] = and <3 x i32> [[X:%.*]], [[M:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor <3 x i32> [[M]], <i32 -1, i32 undef,
> i32 -1>
> -; CHECK-NEXT:    [[AND1:%.*]] = and <3 x i32> [[NEG]], [[Y:%.*]]
> -; CHECK-NEXT:    [[RET:%.*]] = or <3 x i32> [[AND]], [[AND1]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor <3 x i32> [[X:%.*]], [[Y:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor <3 x i32> [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret <3 x i32> [[RET]]
>  ;
>    %and = and <3 x i32> %x, %m
> @@ -182,10 +179,9 @@ declare i32 @gen32()
>
>  define i32 @p_commutative0(i32 %x, i32 %y, i32 %m) {
>  ; CHECK-LABEL: @p_commutative0(
> -; CHECK-NEXT:    [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1
> -; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[NEG]], [[Y:%.*]]
> -; CHECK-NEXT:    [[RET:%.*]] = or i32 [[AND]], [[AND1]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %and = and i32 %m, %x ; swapped order
> @@ -198,10 +194,9 @@ define i32 @p_commutative0(i32 %x, i32 %
>  define i32 @p_commutative1(i32 %x, i32 %m) {
>  ; CHECK-LABEL: @p_commutative1(
>  ; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()
> -; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1
> -; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y]], [[NEG]]
> -; CHECK-NEXT:    [[RET:%.*]] = or i32 [[AND]], [[AND1]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y]], [[X:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %y = call i32 @gen32()
> @@ -214,10 +209,9 @@ define i32 @p_commutative1(i32 %x, i32 %
>
>  define i32 @p_commutative2(i32 %x, i32 %y, i32 %m) {
>  ; CHECK-LABEL: @p_commutative2(
> -; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1
> -; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[NEG]], [[Y:%.*]]
> -; CHECK-NEXT:    [[RET:%.*]] = or i32 [[AND1]], [[AND]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %and = and i32 %x, %m
> @@ -230,10 +224,9 @@ define i32 @p_commutative2(i32 %x, i32 %
>  define i32 @p_commutative3(i32 %x, i32 %m) {
>  ; CHECK-LABEL: @p_commutative3(
>  ; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()
> -; CHECK-NEXT:    [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1
> -; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y]], [[NEG]]
> -; CHECK-NEXT:    [[RET:%.*]] = or i32 [[AND]], [[AND1]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y]], [[X:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %y = call i32 @gen32()
> @@ -246,10 +239,9 @@ define i32 @p_commutative3(i32 %x, i32 %
>
>  define i32 @p_commutative4(i32 %x, i32 %y, i32 %m) {
>  ; CHECK-LABEL: @p_commutative4(
> -; CHECK-NEXT:    [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1
> -; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[NEG]], [[Y:%.*]]
> -; CHECK-NEXT:    [[RET:%.*]] = or i32 [[AND1]], [[AND]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %and = and i32 %m, %x ; swapped order
> @@ -262,10 +254,9 @@ define i32 @p_commutative4(i32 %x, i32 %
>  define i32 @p_commutative5(i32 %x, i32 %m) {
>  ; CHECK-LABEL: @p_commutative5(
>  ; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()
> -; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1
> -; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y]], [[NEG]]
> -; CHECK-NEXT:    [[RET:%.*]] = or i32 [[AND1]], [[AND]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y]], [[X:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %y = call i32 @gen32()
> @@ -279,10 +270,9 @@ define i32 @p_commutative5(i32 %x, i32 %
>  define i32 @p_commutative6(i32 %x, i32 %m) {
>  ; CHECK-LABEL: @p_commutative6(
>  ; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()
> -; CHECK-NEXT:    [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1
> -; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y]], [[NEG]]
> -; CHECK-NEXT:    [[RET:%.*]] = or i32 [[AND1]], [[AND]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y]], [[X:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %y = call i32 @gen32()
>
> Modified: llvm/trunk/test/Transforms/InstCombine/masked-merge-and-of-ors.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/masked-merge-and-of-ors.ll?rev=333106&r1=333105&r2=333106&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/Transforms/InstCombine/masked-merge-and-of-ors.ll
> (original)
> +++ llvm/trunk/test/Transforms/InstCombine/masked-merge-and-of-ors.ll Wed
> May 23 10:47:52 2018
> @@ -16,10 +16,9 @@
>
>  define i32 @p(i32 %x, i32 %y, i32 %m) {
>  ; CHECK-LABEL: @p(
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M:%.*]], -1
> -; CHECK-NEXT:    [[OR:%.*]] = or i32 [[NEG]], [[X:%.*]]
> -; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], [[M]]
> -; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR]], [[OR1]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %neg = xor i32 %m, -1
> @@ -31,10 +30,9 @@ define i32 @p(i32 %x, i32 %y, i32 %m) {
>
>  define <2 x i32> @p_splatvec(<2 x i32> %x, <2 x i32> %y, <2 x i32> %m) {
>  ; CHECK-LABEL: @p_splatvec(
> -; CHECK-NEXT:    [[NEG:%.*]] = xor <2 x i32> [[M:%.*]], <i32 -1, i32 -1>
> -; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[NEG]], [[X:%.*]]
> -; CHECK-NEXT:    [[OR1:%.*]] = or <2 x i32> [[Y:%.*]], [[M]]
> -; CHECK-NEXT:    [[RET:%.*]] = and <2 x i32> [[OR]], [[OR1]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i32> [[X:%.*]], [[Y:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor <2 x i32> [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret <2 x i32> [[RET]]
>  ;
>    %neg = xor <2 x i32> %m, <i32 -1, i32 -1>
> @@ -46,10 +44,9 @@ define <2 x i32> @p_splatvec(<2 x i32> %
>
>  define <3 x i32> @p_vec_undef(<3 x i32> %x, <3 x i32> %y, <3 x i32> %m) {
>  ; CHECK-LABEL: @p_vec_undef(
> -; CHECK-NEXT:    [[NEG:%.*]] = xor <3 x i32> [[M:%.*]], <i32 -1, i32
> undef, i32 -1>
> -; CHECK-NEXT:    [[OR:%.*]] = or <3 x i32> [[NEG]], [[X:%.*]]
> -; CHECK-NEXT:    [[OR1:%.*]] = or <3 x i32> [[Y:%.*]], [[M]]
> -; CHECK-NEXT:    [[RET:%.*]] = and <3 x i32> [[OR]], [[OR1]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor <3 x i32> [[X:%.*]], [[Y:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor <3 x i32> [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret <3 x i32> [[RET]]
>  ;
>    %neg = xor <3 x i32> %m, <i32 -1, i32 undef, i32 -1>
> @@ -124,10 +121,9 @@ declare i32 @gen32()
>
>  define i32 @p_commutative0(i32 %x, i32 %y, i32 %m) {
>  ; CHECK-LABEL: @p_commutative0(
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M:%.*]], -1
> -; CHECK-NEXT:    [[OR:%.*]] = or i32 [[NEG]], [[X:%.*]]
> -; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], [[M]]
> -; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR]], [[OR1]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %neg = xor i32 %m, -1
> @@ -140,10 +136,9 @@ define i32 @p_commutative0(i32 %x, i32 %
>  define i32 @p_commutative1(i32 %x, i32 %m) {
>  ; CHECK-LABEL: @p_commutative1(
>  ; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M:%.*]], -1
> -; CHECK-NEXT:    [[OR:%.*]] = or i32 [[NEG]], [[X:%.*]]
> -; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y]], [[M]]
> -; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR]], [[OR1]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y]], [[X:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %y = call i32 @gen32()
> @@ -156,10 +151,9 @@ define i32 @p_commutative1(i32 %x, i32 %
>
>  define i32 @p_commutative2(i32 %x, i32 %y, i32 %m) {
>  ; CHECK-LABEL: @p_commutative2(
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M:%.*]], -1
> -; CHECK-NEXT:    [[OR:%.*]] = or i32 [[NEG]], [[X:%.*]]
> -; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], [[M]]
> -; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR1]], [[OR]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %neg = xor i32 %m, -1
> @@ -172,10 +166,9 @@ define i32 @p_commutative2(i32 %x, i32 %
>  define i32 @p_commutative3(i32 %x, i32 %m) {
>  ; CHECK-LABEL: @p_commutative3(
>  ; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M:%.*]], -1
> -; CHECK-NEXT:    [[OR:%.*]] = or i32 [[NEG]], [[X:%.*]]
> -; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y]], [[M]]
> -; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR]], [[OR1]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y]], [[X:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %y = call i32 @gen32()
> @@ -188,10 +181,9 @@ define i32 @p_commutative3(i32 %x, i32 %
>
>  define i32 @p_commutative4(i32 %x, i32 %y, i32 %m) {
>  ; CHECK-LABEL: @p_commutative4(
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M:%.*]], -1
> -; CHECK-NEXT:    [[OR:%.*]] = or i32 [[NEG]], [[X:%.*]]
> -; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], [[M]]
> -; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR1]], [[OR]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %neg = xor i32 %m, -1
> @@ -204,10 +196,9 @@ define i32 @p_commutative4(i32 %x, i32 %
>  define i32 @p_commutative5(i32 %x, i32 %m) {
>  ; CHECK-LABEL: @p_commutative5(
>  ; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M:%.*]], -1
> -; CHECK-NEXT:    [[OR:%.*]] = or i32 [[NEG]], [[X:%.*]]
> -; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y]], [[M]]
> -; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR1]], [[OR]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y]], [[X:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %y = call i32 @gen32()
> @@ -221,10 +212,9 @@ define i32 @p_commutative5(i32 %x, i32 %
>  define i32 @p_commutative6(i32 %x, i32 %m) {
>  ; CHECK-LABEL: @p_commutative6(
>  ; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M:%.*]], -1
> -; CHECK-NEXT:    [[OR:%.*]] = or i32 [[NEG]], [[X:%.*]]
> -; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y]], [[M]]
> -; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR1]], [[OR]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y]], [[X:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %y = call i32 @gen32()
> @@ -259,9 +249,9 @@ declare void @use32(i32)
>  define i32 @n0_oneuse_of_neg_is_ok_0(i32 %x, i32 %y, i32 %m) {
>  ; CHECK-LABEL: @n0_oneuse_of_neg_is_ok_0(
>  ; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M:%.*]], -1
> -; CHECK-NEXT:    [[OR:%.*]] = or i32 [[NEG]], [[X:%.*]]
> -; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], [[M]]
> -; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR]], [[OR1]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    call void @use32(i32 [[NEG]])
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>
> Modified: llvm/trunk/test/Transforms/InstCombine/masked-merge-or.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/masked-merge-or.ll?rev=333106&r1=333105&r2=333106&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/Transforms/InstCombine/masked-merge-or.ll (original)
> +++ llvm/trunk/test/Transforms/InstCombine/masked-merge-or.ll Wed May 23
> 10:47:52 2018
> @@ -18,10 +18,9 @@
>
>  define i32 @p(i32 %x, i32 %y, i32 %m) {
>  ; CHECK-LABEL: @p(
> -; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1
> -; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[NEG]], [[Y:%.*]]
> -; CHECK-NEXT:    [[RET:%.*]] = or i32 [[AND]], [[AND1]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %and = and i32 %x, %m
> @@ -33,10 +32,9 @@ define i32 @p(i32 %x, i32 %y, i32 %m) {
>
>  define <2 x i32> @p_splatvec(<2 x i32> %x, <2 x i32> %y, <2 x i32> %m) {
>  ; CHECK-LABEL: @p_splatvec(
> -; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X:%.*]], [[M:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor <2 x i32> [[M]], <i32 -1, i32 -1>
> -; CHECK-NEXT:    [[AND1:%.*]] = and <2 x i32> [[NEG]], [[Y:%.*]]
> -; CHECK-NEXT:    [[RET:%.*]] = or <2 x i32> [[AND]], [[AND1]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i32> [[X:%.*]], [[Y:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor <2 x i32> [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret <2 x i32> [[RET]]
>  ;
>    %and = and <2 x i32> %x, %m
> @@ -48,10 +46,9 @@ define <2 x i32> @p_splatvec(<2 x i32> %
>
>  define <3 x i32> @p_vec_undef(<3 x i32> %x, <3 x i32> %y, <3 x i32> %m) {
>  ; CHECK-LABEL: @p_vec_undef(
> -; CHECK-NEXT:    [[AND:%.*]] = and <3 x i32> [[X:%.*]], [[M:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor <3 x i32> [[M]], <i32 -1, i32 undef,
> i32 -1>
> -; CHECK-NEXT:    [[AND1:%.*]] = and <3 x i32> [[NEG]], [[Y:%.*]]
> -; CHECK-NEXT:    [[RET:%.*]] = or <3 x i32> [[AND]], [[AND1]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor <3 x i32> [[X:%.*]], [[Y:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor <3 x i32> [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret <3 x i32> [[RET]]
>  ;
>    %and = and <3 x i32> %x, %m
> @@ -182,10 +179,9 @@ declare i32 @gen32()
>
>  define i32 @p_commutative0(i32 %x, i32 %y, i32 %m) {
>  ; CHECK-LABEL: @p_commutative0(
> -; CHECK-NEXT:    [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1
> -; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[NEG]], [[Y:%.*]]
> -; CHECK-NEXT:    [[RET:%.*]] = or i32 [[AND]], [[AND1]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %and = and i32 %m, %x ; swapped order
> @@ -198,10 +194,9 @@ define i32 @p_commutative0(i32 %x, i32 %
>  define i32 @p_commutative1(i32 %x, i32 %m) {
>  ; CHECK-LABEL: @p_commutative1(
>  ; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()
> -; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1
> -; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y]], [[NEG]]
> -; CHECK-NEXT:    [[RET:%.*]] = or i32 [[AND]], [[AND1]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y]], [[X:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %y = call i32 @gen32()
> @@ -214,10 +209,9 @@ define i32 @p_commutative1(i32 %x, i32 %
>
>  define i32 @p_commutative2(i32 %x, i32 %y, i32 %m) {
>  ; CHECK-LABEL: @p_commutative2(
> -; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1
> -; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[NEG]], [[Y:%.*]]
> -; CHECK-NEXT:    [[RET:%.*]] = or i32 [[AND1]], [[AND]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %and = and i32 %x, %m
> @@ -230,10 +224,9 @@ define i32 @p_commutative2(i32 %x, i32 %
>  define i32 @p_commutative3(i32 %x, i32 %m) {
>  ; CHECK-LABEL: @p_commutative3(
>  ; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()
> -; CHECK-NEXT:    [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1
> -; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y]], [[NEG]]
> -; CHECK-NEXT:    [[RET:%.*]] = or i32 [[AND]], [[AND1]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y]], [[X:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %y = call i32 @gen32()
> @@ -246,10 +239,9 @@ define i32 @p_commutative3(i32 %x, i32 %
>
>  define i32 @p_commutative4(i32 %x, i32 %y, i32 %m) {
>  ; CHECK-LABEL: @p_commutative4(
> -; CHECK-NEXT:    [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1
> -; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[NEG]], [[Y:%.*]]
> -; CHECK-NEXT:    [[RET:%.*]] = or i32 [[AND1]], [[AND]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %and = and i32 %m, %x ; swapped order
> @@ -262,10 +254,9 @@ define i32 @p_commutative4(i32 %x, i32 %
>  define i32 @p_commutative5(i32 %x, i32 %m) {
>  ; CHECK-LABEL: @p_commutative5(
>  ; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()
> -; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1
> -; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y]], [[NEG]]
> -; CHECK-NEXT:    [[RET:%.*]] = or i32 [[AND1]], [[AND]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y]], [[X:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %y = call i32 @gen32()
> @@ -279,10 +270,9 @@ define i32 @p_commutative5(i32 %x, i32 %
>  define i32 @p_commutative6(i32 %x, i32 %m) {
>  ; CHECK-LABEL: @p_commutative6(
>  ; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()
> -; CHECK-NEXT:    [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1
> -; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y]], [[NEG]]
> -; CHECK-NEXT:    [[RET:%.*]] = or i32 [[AND1]], [[AND]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y]], [[X:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %y = call i32 @gen32()
>
> Modified: llvm/trunk/test/Transforms/InstCombine/masked-merge-xor.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/masked-merge-xor.ll?rev=333106&r1=333105&r2=333106&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/Transforms/InstCombine/masked-merge-xor.ll (original)
> +++ llvm/trunk/test/Transforms/InstCombine/masked-merge-xor.ll Wed May 23
> 10:47:52 2018
> @@ -18,10 +18,9 @@
>
>  define i32 @p(i32 %x, i32 %y, i32 %m) {
>  ; CHECK-LABEL: @p(
> -; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1
> -; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[NEG]], [[Y:%.*]]
> -; CHECK-NEXT:    [[RET:%.*]] = or i32 [[AND]], [[AND1]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %and = and i32 %x, %m
> @@ -33,10 +32,9 @@ define i32 @p(i32 %x, i32 %y, i32 %m) {
>
>  define <2 x i32> @p_splatvec(<2 x i32> %x, <2 x i32> %y, <2 x i32> %m) {
>  ; CHECK-LABEL: @p_splatvec(
> -; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X:%.*]], [[M:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor <2 x i32> [[M]], <i32 -1, i32 -1>
> -; CHECK-NEXT:    [[AND1:%.*]] = and <2 x i32> [[NEG]], [[Y:%.*]]
> -; CHECK-NEXT:    [[RET:%.*]] = or <2 x i32> [[AND]], [[AND1]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i32> [[X:%.*]], [[Y:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor <2 x i32> [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret <2 x i32> [[RET]]
>  ;
>    %and = and <2 x i32> %x, %m
> @@ -48,10 +46,9 @@ define <2 x i32> @p_splatvec(<2 x i32> %
>
>  define <3 x i32> @p_vec_undef(<3 x i32> %x, <3 x i32> %y, <3 x i32> %m) {
>  ; CHECK-LABEL: @p_vec_undef(
> -; CHECK-NEXT:    [[AND:%.*]] = and <3 x i32> [[X:%.*]], [[M:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor <3 x i32> [[M]], <i32 -1, i32 undef,
> i32 -1>
> -; CHECK-NEXT:    [[AND1:%.*]] = and <3 x i32> [[NEG]], [[Y:%.*]]
> -; CHECK-NEXT:    [[RET:%.*]] = or <3 x i32> [[AND]], [[AND1]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor <3 x i32> [[X:%.*]], [[Y:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor <3 x i32> [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret <3 x i32> [[RET]]
>  ;
>    %and = and <3 x i32> %x, %m
> @@ -182,10 +179,9 @@ declare i32 @gen32()
>
>  define i32 @p_commutative0(i32 %x, i32 %y, i32 %m) {
>  ; CHECK-LABEL: @p_commutative0(
> -; CHECK-NEXT:    [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1
> -; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[NEG]], [[Y:%.*]]
> -; CHECK-NEXT:    [[RET:%.*]] = or i32 [[AND]], [[AND1]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %and = and i32 %m, %x ; swapped order
> @@ -198,10 +194,9 @@ define i32 @p_commutative0(i32 %x, i32 %
>  define i32 @p_commutative1(i32 %x, i32 %m) {
>  ; CHECK-LABEL: @p_commutative1(
>  ; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()
> -; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1
> -; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y]], [[NEG]]
> -; CHECK-NEXT:    [[RET:%.*]] = or i32 [[AND]], [[AND1]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y]], [[X:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %y = call i32 @gen32()
> @@ -214,10 +209,9 @@ define i32 @p_commutative1(i32 %x, i32 %
>
>  define i32 @p_commutative2(i32 %x, i32 %y, i32 %m) {
>  ; CHECK-LABEL: @p_commutative2(
> -; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1
> -; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[NEG]], [[Y:%.*]]
> -; CHECK-NEXT:    [[RET:%.*]] = or i32 [[AND1]], [[AND]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %and = and i32 %x, %m
> @@ -230,10 +224,9 @@ define i32 @p_commutative2(i32 %x, i32 %
>  define i32 @p_commutative3(i32 %x, i32 %m) {
>  ; CHECK-LABEL: @p_commutative3(
>  ; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()
> -; CHECK-NEXT:    [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1
> -; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y]], [[NEG]]
> -; CHECK-NEXT:    [[RET:%.*]] = or i32 [[AND]], [[AND1]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y]], [[X:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %y = call i32 @gen32()
> @@ -246,10 +239,9 @@ define i32 @p_commutative3(i32 %x, i32 %
>
>  define i32 @p_commutative4(i32 %x, i32 %y, i32 %m) {
>  ; CHECK-LABEL: @p_commutative4(
> -; CHECK-NEXT:    [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1
> -; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[NEG]], [[Y:%.*]]
> -; CHECK-NEXT:    [[RET:%.*]] = or i32 [[AND1]], [[AND]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %and = and i32 %m, %x ; swapped order
> @@ -262,10 +254,9 @@ define i32 @p_commutative4(i32 %x, i32 %
>  define i32 @p_commutative5(i32 %x, i32 %m) {
>  ; CHECK-LABEL: @p_commutative5(
>  ; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()
> -; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1
> -; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y]], [[NEG]]
> -; CHECK-NEXT:    [[RET:%.*]] = or i32 [[AND1]], [[AND]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y]], [[X:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %y = call i32 @gen32()
> @@ -279,10 +270,9 @@ define i32 @p_commutative5(i32 %x, i32 %
>  define i32 @p_commutative6(i32 %x, i32 %m) {
>  ; CHECK-LABEL: @p_commutative6(
>  ; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()
> -; CHECK-NEXT:    [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]]
> -; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1
> -; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y]], [[NEG]]
> -; CHECK-NEXT:    [[RET:%.*]] = or i32 [[AND1]], [[AND]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y]], [[X:%.*]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[M:%.*]]
> +; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[TMP2]], [[Y]]
>  ; CHECK-NEXT:    ret i32 [[RET]]
>  ;
>    %y = call i32 @gen32()
>
> Modified: llvm/trunk/test/Transforms/InstCombine/vec_sext.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/vec_sext.ll?rev=333106&r1=333105&r2=333106&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/Transforms/InstCombine/vec_sext.ll (original)
> +++ llvm/trunk/test/Transforms/InstCombine/vec_sext.ll Wed May 23 10:47:52
> 2018
> @@ -5,10 +5,9 @@ define <4 x i32> @psignd_3(<4 x i32> %a,
>  ; CHECK-LABEL: @psignd_3(
>  ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw <4 x i32> zeroinitializer,
> [[A:%.*]]
>  ; CHECK-NEXT:    [[B_LOBIT1:%.*]] = ashr <4 x i32> [[B:%.*]], <i32 31,
> i32 31, i32 31, i32 31>
> -; CHECK-NEXT:    [[T1:%.*]] = xor <4 x i32> [[B_LOBIT1]], <i32 -1, i32
> -1, i32 -1, i32 -1>
> -; CHECK-NEXT:    [[T2:%.*]] = and <4 x i32> [[T1]], [[A]]
> -; CHECK-NEXT:    [[T3:%.*]] = and <4 x i32> [[B_LOBIT1]], [[SUB]]
> -; CHECK-NEXT:    [[COND:%.*]] = or <4 x i32> [[T2]], [[T3]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor <4 x i32> [[SUB]], [[A]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and <4 x i32> [[TMP1]], [[B_LOBIT1]]
> +; CHECK-NEXT:    [[COND:%.*]] = xor <4 x i32> [[TMP2]], [[A]]
>  ; CHECK-NEXT:    ret <4 x i32> [[COND]]
>  ;
>    %cmp = icmp slt <4 x i32> %b, zeroinitializer
> @@ -27,10 +26,9 @@ define <4 x i32> @test1(<4 x i32> %a, <4
>  ; CHECK-LABEL: @test1(
>  ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw <4 x i32> zeroinitializer,
> [[A:%.*]]
>  ; CHECK-NEXT:    [[B_LOBIT1:%.*]] = ashr <4 x i32> [[B:%.*]], <i32 31,
> i32 31, i32 31, i32 31>
> -; CHECK-NEXT:    [[B_LOBIT1_NOT:%.*]] = xor <4 x i32> [[B_LOBIT1]], <i32
> -1, i32 -1, i32 -1, i32 -1>
> -; CHECK-NEXT:    [[T2:%.*]] = and <4 x i32> [[B_LOBIT1]], [[A]]
> -; CHECK-NEXT:    [[T3:%.*]] = and <4 x i32> [[B_LOBIT1_NOT]], [[SUB]]
> -; CHECK-NEXT:    [[COND:%.*]] = or <4 x i32> [[T2]], [[T3]]
> +; CHECK-NEXT:    [[TMP1:%.*]] = xor <4 x i32> [[SUB]], [[A]]
> +; CHECK-NEXT:    [[TMP2:%.*]] = and <4 x i32> [[TMP1]], [[B_LOBIT1]]
> +; CHECK-NEXT:    [[COND:%.*]] = xor <4 x i32> [[TMP2]], [[SUB]]
>  ; CHECK-NEXT:    ret <4 x i32> [[COND]]
>  ;
>    %cmp = icmp sgt <4 x i32> %b, <i32 -1, i32 -1, i32 -1, i32 -1>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180530/b6a2b402/attachment-0001.html>


More information about the llvm-commits mailing list