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

Chandler Carruth via llvm-commits llvm-commits at lists.llvm.org
Wed May 30 22:34:20 PDT 2018


On Wed, May 30, 2018 at 9:06 PM Sanjoy Das <sanjoy at playingwithpointers.com>
wrote:

> Yes, this transform looks incorrect for undef.  We can't increase the
> number of uses of a value (this is one of the known problem with
> undef).
>

Thanks, I'll probably revert it for now. We can keep discussion going in
the interim about the best way to do it, but I don't want to keep
(potentially) miscompiling code like encryption...


>
> I'm curious about what msan warnings you're seeing -- usually I'd
> expect this sort of problem (which, just to be clear, does look like a
> legit bug) to show up in C/C++ programs that had UB to begin with.
>

I strongly suspect that this code is trying to do something like:

unsigned f(unsigned mask, unsigned x, unsigned y) {
  return (mask & x) | (~mask & y);
}

void g(unsigned x) {
  unsigned y;
  unsigned z = f(-1, x, y);
  // use z
}

This is technically UB according to C++, but it isn't clear at all this is
UB in C. More practically speaking, real code really does assume that
"failing to observe" uninitialized memory is sufficient. That's why for
MSan to be useful in practice it has to propagate uninitialized memory
exactly the way we would propagate undef (and why an undef breaking
transform directly breaks MSan).

Fundamentally, MSan is a undef/poison sanitizer, not just an uninitialized
memory sanitizer.



> -- Sanjoy
>
> On Wed, May 30, 2018 at 8:48 PM, Eric Christopher <echristo at gmail.com>
> wrote:
> > 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/801a1277/attachment.html>


More information about the llvm-commits mailing list