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

Roman Lebedev via llvm-commits llvm-commits at lists.llvm.org
Wed May 30 23:06:50 PDT 2018


Thanks everyone, reverted in rL333631!

Roman.

On Thu, May 31, 2018 at 8:34 AM, Chandler Carruth <chandlerc at gmail.com> wrote:
> 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


More information about the llvm-commits mailing list