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