Index: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp =================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -2411,6 +2411,36 @@ return nullptr; } +/// If we have a masked merge, in the canonical form of: +/// | A | |B| +/// ((x ^ y) & M) ^ y +/// | D | +/// * If M is inverted: +/// | D | +/// ((x ^ y) & ~M) ^ y +/// If A has one use, and, we want to canonicalize it to non-inverted mask: +/// ((x ^ y) & M) ^ x +static Instruction *visitMaskedMerge(BinaryOperator &I, + InstCombiner::BuilderTy &Builder) { + Value *B, *X, *D; + Value *M; + if (!match(&I, m_c_Xor(m_Value(B), + m_OneUse(m_c_And( + m_CombineAnd(m_c_Xor(m_Deferred(B), m_Value(X)), + m_Value(D)), + m_Value(M)))))) + return nullptr; + + Value *NotM; + if (match(M, m_Not(m_Value(NotM)))) { + // De-invert the mask and swap the value in B part. + Value *NewA = Builder.CreateAnd(D, NotM); + return BinaryOperator::CreateXor(NewA, X); + } + + return nullptr; +} + // FIXME: We use commutative matchers (m_c_*) for some, but not all, matches // here. We should standardize that construct where it is needed or choose some // other way to ensure that commutated variants of patterns are not missed. @@ -2461,6 +2491,9 @@ return BinaryOperator::CreateAnd(X, NotY); } + if (Instruction *Xor = visitMaskedMerge(I, Builder)) + return Xor; + // Is this a 'not' (~) fed by a binary operator? BinaryOperator *NotVal; if (match(&I, m_Not(m_BinOp(NotVal)))) { Index: llvm/trunk/test/Transforms/InstCombine/invert-variable-mask-in-masked-merge-scalar.ll =================================================================== --- llvm/trunk/test/Transforms/InstCombine/invert-variable-mask-in-masked-merge-scalar.ll +++ llvm/trunk/test/Transforms/InstCombine/invert-variable-mask-in-masked-merge-scalar.ll @@ -8,10 +8,9 @@ define i4 @scalar (i4 %x, i4 %y, i4 %m) { ; CHECK-LABEL: @scalar( -; CHECK-NEXT: [[IM:%.*]] = xor i4 [[M:%.*]], -1 ; CHECK-NEXT: [[N0:%.*]] = xor i4 [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: [[N1:%.*]] = and i4 [[N0]], [[IM]] -; CHECK-NEXT: [[R:%.*]] = xor i4 [[N1]], [[Y]] +; CHECK-NEXT: [[TMP1:%.*]] = and i4 [[N0]], [[M:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor i4 [[TMP1]], [[X]] ; CHECK-NEXT: ret i4 [[R]] ; %im = xor i4 %m, -1 @@ -39,10 +38,9 @@ define i4 @in_constant_varx_6_invmask(i4 %x, i4 %mask) { ; CHECK-LABEL: @in_constant_varx_6_invmask( -; CHECK-NEXT: [[NOTMASK:%.*]] = xor i4 [[MASK:%.*]], -1 ; CHECK-NEXT: [[N0:%.*]] = xor i4 [[X:%.*]], 6 -; CHECK-NEXT: [[N1:%.*]] = and i4 [[N0]], [[NOTMASK]] -; CHECK-NEXT: [[R:%.*]] = xor i4 [[N1]], 6 +; CHECK-NEXT: [[TMP1:%.*]] = and i4 [[N0]], [[MASK:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor i4 [[TMP1]], [[X]] ; CHECK-NEXT: ret i4 [[R]] ; %notmask = xor i4 %mask, -1 @@ -68,10 +66,9 @@ define i4 @in_constant_6_vary_invmask(i4 %y, i4 %mask) { ; CHECK-LABEL: @in_constant_6_vary_invmask( -; CHECK-NEXT: [[NOTMASK:%.*]] = xor i4 [[MASK:%.*]], -1 ; CHECK-NEXT: [[N0:%.*]] = xor i4 [[Y:%.*]], 6 -; CHECK-NEXT: [[N1:%.*]] = and i4 [[N0]], [[NOTMASK]] -; CHECK-NEXT: [[R:%.*]] = xor i4 [[N1]], [[Y]] +; CHECK-NEXT: [[TMP1:%.*]] = and i4 [[N0]], [[MASK:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor i4 [[TMP1]], 6 ; CHECK-NEXT: ret i4 [[R]] ; %notmask = xor i4 %mask, -1 @@ -92,10 +89,9 @@ define i4 @c_1_0_0 (i4 %x, i4 %y, i4 %m) { ; CHECK-LABEL: @c_1_0_0( -; CHECK-NEXT: [[IM:%.*]] = xor i4 [[M:%.*]], -1 ; CHECK-NEXT: [[N0:%.*]] = xor i4 [[Y:%.*]], [[X:%.*]] -; CHECK-NEXT: [[N1:%.*]] = and i4 [[N0]], [[IM]] -; CHECK-NEXT: [[R:%.*]] = xor i4 [[N1]], [[Y]] +; CHECK-NEXT: [[TMP1:%.*]] = and i4 [[N0]], [[M:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor i4 [[TMP1]], [[X]] ; CHECK-NEXT: ret i4 [[R]] ; %im = xor i4 %m, -1 @@ -107,10 +103,9 @@ define i4 @c_0_1_0 (i4 %x, i4 %y, i4 %m) { ; CHECK-LABEL: @c_0_1_0( -; CHECK-NEXT: [[IM:%.*]] = xor i4 [[M:%.*]], -1 ; CHECK-NEXT: [[N0:%.*]] = xor i4 [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: [[N1:%.*]] = and i4 [[N0]], [[IM]] -; CHECK-NEXT: [[R:%.*]] = xor i4 [[N1]], [[X]] +; CHECK-NEXT: [[TMP1:%.*]] = and i4 [[N0]], [[M:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor i4 [[TMP1]], [[Y]] ; CHECK-NEXT: ret i4 [[R]] ; %im = xor i4 %m, -1 @@ -122,12 +117,11 @@ define i4 @c_0_0_1 (i4 %m) { ; CHECK-LABEL: @c_0_0_1( -; CHECK-NEXT: [[IM:%.*]] = xor i4 [[M:%.*]], -1 ; CHECK-NEXT: [[X:%.*]] = call i4 @gen4() ; CHECK-NEXT: [[Y:%.*]] = call i4 @gen4() ; CHECK-NEXT: [[N0:%.*]] = xor i4 [[X]], [[Y]] -; CHECK-NEXT: [[N1:%.*]] = and i4 [[N0]], [[IM]] -; CHECK-NEXT: [[R:%.*]] = xor i4 [[Y]], [[N1]] +; CHECK-NEXT: [[TMP1:%.*]] = and i4 [[N0]], [[M:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor i4 [[TMP1]], [[X]] ; CHECK-NEXT: ret i4 [[R]] ; %im = xor i4 %m, -1 @@ -141,10 +135,9 @@ define i4 @c_1_1_0 (i4 %x, i4 %y, i4 %m) { ; CHECK-LABEL: @c_1_1_0( -; CHECK-NEXT: [[IM:%.*]] = xor i4 [[M:%.*]], -1 ; CHECK-NEXT: [[N0:%.*]] = xor i4 [[Y:%.*]], [[X:%.*]] -; CHECK-NEXT: [[N1:%.*]] = and i4 [[N0]], [[IM]] -; CHECK-NEXT: [[R:%.*]] = xor i4 [[N1]], [[X]] +; CHECK-NEXT: [[TMP1:%.*]] = and i4 [[N0]], [[M:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor i4 [[TMP1]], [[Y]] ; CHECK-NEXT: ret i4 [[R]] ; %im = xor i4 %m, -1 @@ -156,11 +149,10 @@ define i4 @c_1_0_1 (i4 %x, i4 %m) { ; CHECK-LABEL: @c_1_0_1( -; CHECK-NEXT: [[IM:%.*]] = xor i4 [[M:%.*]], -1 ; CHECK-NEXT: [[Y:%.*]] = call i4 @gen4() ; CHECK-NEXT: [[N0:%.*]] = xor i4 [[Y]], [[X:%.*]] -; CHECK-NEXT: [[N1:%.*]] = and i4 [[N0]], [[IM]] -; CHECK-NEXT: [[R:%.*]] = xor i4 [[Y]], [[N1]] +; CHECK-NEXT: [[TMP1:%.*]] = and i4 [[N0]], [[M:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor i4 [[TMP1]], [[X]] ; CHECK-NEXT: ret i4 [[R]] ; %im = xor i4 %m, -1 @@ -173,11 +165,10 @@ define i4 @c_0_1_1 (i4 %y, i4 %m) { ; CHECK-LABEL: @c_0_1_1( -; CHECK-NEXT: [[IM:%.*]] = xor i4 [[M:%.*]], -1 ; CHECK-NEXT: [[X:%.*]] = call i4 @gen4() ; CHECK-NEXT: [[N0:%.*]] = xor i4 [[X]], [[Y:%.*]] -; CHECK-NEXT: [[N1:%.*]] = and i4 [[N0]], [[IM]] -; CHECK-NEXT: [[R:%.*]] = xor i4 [[X]], [[N1]] +; CHECK-NEXT: [[TMP1:%.*]] = and i4 [[N0]], [[M:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor i4 [[TMP1]], [[Y]] ; CHECK-NEXT: ret i4 [[R]] ; %im = xor i4 %m, -1 @@ -190,12 +181,11 @@ define i4 @c_1_1_1 (i4 %m) { ; CHECK-LABEL: @c_1_1_1( -; CHECK-NEXT: [[IM:%.*]] = xor i4 [[M:%.*]], -1 ; CHECK-NEXT: [[X:%.*]] = call i4 @gen4() ; CHECK-NEXT: [[Y:%.*]] = call i4 @gen4() ; CHECK-NEXT: [[N0:%.*]] = xor i4 [[Y]], [[X]] -; CHECK-NEXT: [[N1:%.*]] = and i4 [[N0]], [[IM]] -; CHECK-NEXT: [[R:%.*]] = xor i4 [[X]], [[N1]] +; CHECK-NEXT: [[TMP1:%.*]] = and i4 [[N0]], [[M:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor i4 [[TMP1]], [[Y]] ; CHECK-NEXT: ret i4 [[R]] ; %im = xor i4 %m, -1 @@ -209,10 +199,9 @@ define i4 @commutativity_constant_varx_6_invmask(i4 %x, i4 %mask) { ; CHECK-LABEL: @commutativity_constant_varx_6_invmask( -; CHECK-NEXT: [[NOTMASK:%.*]] = xor i4 [[MASK:%.*]], -1 ; CHECK-NEXT: [[N0:%.*]] = xor i4 [[X:%.*]], 6 -; CHECK-NEXT: [[N1:%.*]] = and i4 [[N0]], [[NOTMASK]] -; CHECK-NEXT: [[R:%.*]] = xor i4 [[N1]], 6 +; CHECK-NEXT: [[TMP1:%.*]] = and i4 [[N0]], [[MASK:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor i4 [[TMP1]], [[X]] ; CHECK-NEXT: ret i4 [[R]] ; %notmask = xor i4 %mask, -1 @@ -224,10 +213,9 @@ define i4 @commutativity_constant_6_vary_invmask(i4 %y, i4 %mask) { ; CHECK-LABEL: @commutativity_constant_6_vary_invmask( -; CHECK-NEXT: [[NOTMASK:%.*]] = xor i4 [[MASK:%.*]], -1 ; CHECK-NEXT: [[N0:%.*]] = xor i4 [[Y:%.*]], 6 -; CHECK-NEXT: [[N1:%.*]] = and i4 [[N0]], [[NOTMASK]] -; CHECK-NEXT: [[R:%.*]] = xor i4 [[N1]], [[Y]] +; CHECK-NEXT: [[TMP1:%.*]] = and i4 [[N0]], [[MASK:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor i4 [[TMP1]], 6 ; CHECK-NEXT: ret i4 [[R]] ; %notmask = xor i4 %mask, -1 @@ -247,10 +235,9 @@ define i4 @n_oneuse_D_is_ok (i4 %x, i4 %y, i4 %m) { ; CHECK-LABEL: @n_oneuse_D_is_ok( -; CHECK-NEXT: [[IM:%.*]] = xor i4 [[M:%.*]], -1 ; CHECK-NEXT: [[N0:%.*]] = xor i4 [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: [[N1:%.*]] = and i4 [[N0]], [[IM]] -; CHECK-NEXT: [[R:%.*]] = xor i4 [[N1]], [[Y]] +; CHECK-NEXT: [[TMP1:%.*]] = and i4 [[N0]], [[M:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor i4 [[TMP1]], [[X]] ; CHECK-NEXT: call void @use4(i4 [[N0]]) ; CHECK-NEXT: ret i4 [[R]] ; Index: llvm/trunk/test/Transforms/InstCombine/invert-variable-mask-in-masked-merge-vector.ll =================================================================== --- llvm/trunk/test/Transforms/InstCombine/invert-variable-mask-in-masked-merge-vector.ll +++ llvm/trunk/test/Transforms/InstCombine/invert-variable-mask-in-masked-merge-vector.ll @@ -8,10 +8,9 @@ define <2 x i4> @vector (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) { ; CHECK-LABEL: @vector( -; CHECK-NEXT: [[IM:%.*]] = xor <2 x i4> [[M:%.*]], ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[IM]] -; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], [[Y]] +; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]] ; CHECK-NEXT: ret <2 x i4> [[R]] ; %im = xor <2 x i4> %m, @@ -23,10 +22,9 @@ define <3 x i4> @vector_undef (<3 x i4> %x, <3 x i4> %y, <3 x i4> %m) { ; CHECK-LABEL: @vector_undef( -; CHECK-NEXT: [[IM:%.*]] = xor <3 x i4> [[M:%.*]], ; CHECK-NEXT: [[N0:%.*]] = xor <3 x i4> [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: [[N1:%.*]] = and <3 x i4> [[N0]], [[IM]] -; CHECK-NEXT: [[R:%.*]] = xor <3 x i4> [[N1]], [[Y]] +; CHECK-NEXT: [[TMP1:%.*]] = and <3 x i4> [[N0]], [[M:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor <3 x i4> [[TMP1]], [[X]] ; CHECK-NEXT: ret <3 x i4> [[R]] ; %im = xor <3 x i4> %m, @@ -54,10 +52,9 @@ define <2 x i4> @in_constant_varx_6_invmask(<2 x i4> %x, <2 x i4> %mask) { ; CHECK-LABEL: @in_constant_varx_6_invmask( -; CHECK-NEXT: [[NOTMASK:%.*]] = xor <2 x i4> [[MASK:%.*]], ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], -; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[NOTMASK]] -; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], +; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[MASK:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]] ; CHECK-NEXT: ret <2 x i4> [[R]] ; %notmask = xor <2 x i4> %mask, @@ -69,10 +66,9 @@ define <2 x i4> @in_constant_varx_6_invmask_nonsplat(<2 x i4> %x, <2 x i4> %mask) { ; CHECK-LABEL: @in_constant_varx_6_invmask_nonsplat( -; CHECK-NEXT: [[NOTMASK:%.*]] = xor <2 x i4> [[MASK:%.*]], ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], -; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[NOTMASK]] -; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], +; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[MASK:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]] ; CHECK-NEXT: ret <2 x i4> [[R]] ; %notmask = xor <2 x i4> %mask, @@ -84,10 +80,9 @@ define <3 x i4> @in_constant_varx_6_invmask_undef(<3 x i4> %x, <3 x i4> %mask) { ; CHECK-LABEL: @in_constant_varx_6_invmask_undef( -; CHECK-NEXT: [[NOTMASK:%.*]] = xor <3 x i4> [[MASK:%.*]], ; CHECK-NEXT: [[N0:%.*]] = xor <3 x i4> [[X:%.*]], -; CHECK-NEXT: [[N1:%.*]] = and <3 x i4> [[N0]], [[NOTMASK]] -; CHECK-NEXT: [[R:%.*]] = xor <3 x i4> [[N1]], +; CHECK-NEXT: [[TMP1:%.*]] = and <3 x i4> [[N0]], [[MASK:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor <3 x i4> [[TMP1]], [[X]] ; CHECK-NEXT: ret <3 x i4> [[R]] ; %notmask = xor <3 x i4> %mask, @@ -113,10 +108,9 @@ define <2 x i4> @in_constant_6_vary_invmask(<2 x i4> %y, <2 x i4> %mask) { ; CHECK-LABEL: @in_constant_6_vary_invmask( -; CHECK-NEXT: [[NOTMASK:%.*]] = xor <2 x i4> [[MASK:%.*]], ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[Y:%.*]], -; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[NOTMASK]] -; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], [[Y]] +; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[MASK:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], ; CHECK-NEXT: ret <2 x i4> [[R]] ; %notmask = xor <2 x i4> %mask, @@ -128,10 +122,9 @@ define <2 x i4> @in_constant_6_vary_invmask_nonsplat(<2 x i4> %y, <2 x i4> %mask) { ; CHECK-LABEL: @in_constant_6_vary_invmask_nonsplat( -; CHECK-NEXT: [[NOTMASK:%.*]] = xor <2 x i4> [[MASK:%.*]], ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[Y:%.*]], -; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[NOTMASK]] -; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], [[Y]] +; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[MASK:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], ; CHECK-NEXT: ret <2 x i4> [[R]] ; %notmask = xor <2 x i4> %mask, @@ -143,10 +136,9 @@ define <3 x i4> @in_constant_6_vary_invmask_undef(<3 x i4> %y, <3 x i4> %mask) { ; CHECK-LABEL: @in_constant_6_vary_invmask_undef( -; CHECK-NEXT: [[NOTMASK:%.*]] = xor <3 x i4> [[MASK:%.*]], ; CHECK-NEXT: [[N0:%.*]] = xor <3 x i4> [[Y:%.*]], -; CHECK-NEXT: [[N1:%.*]] = and <3 x i4> [[N0]], [[NOTMASK]] -; CHECK-NEXT: [[R:%.*]] = xor <3 x i4> [[N1]], [[Y]] +; CHECK-NEXT: [[TMP1:%.*]] = and <3 x i4> [[N0]], [[MASK:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor <3 x i4> [[TMP1]], ; CHECK-NEXT: ret <3 x i4> [[R]] ; %notmask = xor <3 x i4> %mask, @@ -167,10 +159,9 @@ define <2 x i4> @c_1_0_0 (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) { ; CHECK-LABEL: @c_1_0_0( -; CHECK-NEXT: [[IM:%.*]] = xor <2 x i4> [[M:%.*]], ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[Y:%.*]], [[X:%.*]] -; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[IM]] -; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], [[Y]] +; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]] ; CHECK-NEXT: ret <2 x i4> [[R]] ; %im = xor <2 x i4> %m, @@ -182,10 +173,9 @@ define <2 x i4> @c_0_1_0 (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) { ; CHECK-LABEL: @c_0_1_0( -; CHECK-NEXT: [[IM:%.*]] = xor <2 x i4> [[M:%.*]], ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[IM]] -; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], [[X]] +; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[Y]] ; CHECK-NEXT: ret <2 x i4> [[R]] ; %im = xor <2 x i4> %m, @@ -197,12 +187,11 @@ define <2 x i4> @c_0_0_1 (<2 x i4> %m) { ; CHECK-LABEL: @c_0_0_1( -; CHECK-NEXT: [[IM:%.*]] = xor <2 x i4> [[M:%.*]], ; CHECK-NEXT: [[X:%.*]] = call <2 x i4> @gen4() ; CHECK-NEXT: [[Y:%.*]] = call <2 x i4> @gen4() ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X]], [[Y]] -; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[IM]] -; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[Y]], [[N1]] +; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]] ; CHECK-NEXT: ret <2 x i4> [[R]] ; %im = xor <2 x i4> %m, @@ -216,10 +205,9 @@ define <2 x i4> @c_1_1_0 (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) { ; CHECK-LABEL: @c_1_1_0( -; CHECK-NEXT: [[IM:%.*]] = xor <2 x i4> [[M:%.*]], ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[Y:%.*]], [[X:%.*]] -; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[IM]] -; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], [[X]] +; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[Y]] ; CHECK-NEXT: ret <2 x i4> [[R]] ; %im = xor <2 x i4> %m, @@ -231,11 +219,10 @@ define <2 x i4> @c_1_0_1 (<2 x i4> %x, <2 x i4> %m) { ; CHECK-LABEL: @c_1_0_1( -; CHECK-NEXT: [[IM:%.*]] = xor <2 x i4> [[M:%.*]], ; CHECK-NEXT: [[Y:%.*]] = call <2 x i4> @gen4() ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[Y]], [[X:%.*]] -; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[IM]] -; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[Y]], [[N1]] +; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]] ; CHECK-NEXT: ret <2 x i4> [[R]] ; %im = xor <2 x i4> %m, @@ -248,11 +235,10 @@ define <2 x i4> @c_0_1_1 (<2 x i4> %y, <2 x i4> %m) { ; CHECK-LABEL: @c_0_1_1( -; CHECK-NEXT: [[IM:%.*]] = xor <2 x i4> [[M:%.*]], ; CHECK-NEXT: [[X:%.*]] = call <2 x i4> @gen4() ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X]], [[Y:%.*]] -; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[IM]] -; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[X]], [[N1]] +; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[Y]] ; CHECK-NEXT: ret <2 x i4> [[R]] ; %im = xor <2 x i4> %m, @@ -265,12 +251,11 @@ define <2 x i4> @c_1_1_1 (<2 x i4> %m) { ; CHECK-LABEL: @c_1_1_1( -; CHECK-NEXT: [[IM:%.*]] = xor <2 x i4> [[M:%.*]], ; CHECK-NEXT: [[X:%.*]] = call <2 x i4> @gen4() ; CHECK-NEXT: [[Y:%.*]] = call <2 x i4> @gen4() ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[Y]], [[X]] -; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[IM]] -; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[X]], [[N1]] +; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[Y]] ; CHECK-NEXT: ret <2 x i4> [[R]] ; %im = xor <2 x i4> %m, @@ -284,10 +269,9 @@ define <2 x i4> @commutativity_constant_varx_6_invmask(<2 x i4> %x, <2 x i4> %mask) { ; CHECK-LABEL: @commutativity_constant_varx_6_invmask( -; CHECK-NEXT: [[NOTMASK:%.*]] = xor <2 x i4> [[MASK:%.*]], ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], -; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[NOTMASK]] -; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], +; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[MASK:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]] ; CHECK-NEXT: ret <2 x i4> [[R]] ; %notmask = xor <2 x i4> %mask, @@ -299,10 +283,9 @@ define <2 x i4> @commutativity_constant_6_vary_invmask(<2 x i4> %y, <2 x i4> %mask) { ; CHECK-LABEL: @commutativity_constant_6_vary_invmask( -; CHECK-NEXT: [[NOTMASK:%.*]] = xor <2 x i4> [[MASK:%.*]], ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[Y:%.*]], -; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[NOTMASK]] -; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], [[Y]] +; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[MASK:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], ; CHECK-NEXT: ret <2 x i4> [[R]] ; %notmask = xor <2 x i4> %mask, @@ -322,10 +305,9 @@ define <2 x i4> @n_oneuse_D_is_ok (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) { ; CHECK-LABEL: @n_oneuse_D_is_ok( -; CHECK-NEXT: [[IM:%.*]] = xor <2 x i4> [[M:%.*]], ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[IM]] -; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], [[Y]] +; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]] ; CHECK-NEXT: call void @use4(<2 x i4> [[N0]]) ; CHECK-NEXT: ret <2 x i4> [[R]] ;