diff options
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 8 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/masked-merge-add.ll | 22 |
2 files changed, 19 insertions, 11 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 1a41d0cb657..ac29cde01fa 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -190,6 +190,14 @@ bool llvm::haveNoCommonBitsSet(const Value *LHS, const Value *RHS, "LHS and RHS should have the same type"); assert(LHS->getType()->isIntOrIntVectorTy() && "LHS and RHS should be integers"); + // Look for an inverted mask: (X & ~M) op (Y & M). + Value *M; + if (match(LHS, m_c_And(m_Not(m_Value(M)), m_Value())) && + match(RHS, m_c_And(m_Specific(M), m_Value()))) + return true; + if (match(RHS, m_c_And(m_Not(m_Value(M)), m_Value())) && + match(LHS, m_c_And(m_Specific(M), m_Value()))) + return true; IntegerType *IT = cast<IntegerType>(LHS->getType()->getScalarType()); KnownBits LHSKnown(IT->getBitWidth()); KnownBits RHSKnown(IT->getBitWidth()); diff --git a/llvm/test/Transforms/InstCombine/masked-merge-add.ll b/llvm/test/Transforms/InstCombine/masked-merge-add.ll index aa99a9c9783..391a2c50571 100644 --- a/llvm/test/Transforms/InstCombine/masked-merge-add.ll +++ b/llvm/test/Transforms/InstCombine/masked-merge-add.ll @@ -21,7 +21,7 @@ define i32 @p(i32 %x, i32 %y, i32 %m) { ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]] ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], -1 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[NEG]], [[Y:%.*]] -; CHECK-NEXT: [[RET:%.*]] = add i32 [[AND]], [[AND1]] +; CHECK-NEXT: [[RET:%.*]] = or i32 [[AND]], [[AND1]] ; CHECK-NEXT: ret i32 [[RET]] ; %and = and i32 %x, %m @@ -36,7 +36,7 @@ define <2 x i32> @p_splatvec(<2 x i32> %x, <2 x i32> %y, <2 x i32> %m) { ; 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:%.*]] = add <2 x i32> [[AND]], [[AND1]] +; CHECK-NEXT: [[RET:%.*]] = or <2 x i32> [[AND]], [[AND1]] ; CHECK-NEXT: ret <2 x i32> [[RET]] ; %and = and <2 x i32> %x, %m @@ -51,7 +51,7 @@ define <3 x i32> @p_vec_undef(<3 x i32> %x, <3 x i32> %y, <3 x i32> %m) { ; 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:%.*]] = add <3 x i32> [[AND]], [[AND1]] +; CHECK-NEXT: [[RET:%.*]] = or <3 x i32> [[AND]], [[AND1]] ; CHECK-NEXT: ret <3 x i32> [[RET]] ; %and = and <3 x i32> %x, %m @@ -129,7 +129,7 @@ define i32 @p_commutative0(i32 %x, i32 %y, i32 %m) { ; CHECK-NEXT: [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]] ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], -1 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[NEG]], [[Y:%.*]] -; CHECK-NEXT: [[RET:%.*]] = add i32 [[AND]], [[AND1]] +; CHECK-NEXT: [[RET:%.*]] = or i32 [[AND]], [[AND1]] ; CHECK-NEXT: ret i32 [[RET]] ; %and = and i32 %m, %x ; swapped order @@ -145,7 +145,7 @@ define i32 @p_commutative1(i32 %x, i32 %m) { ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]] ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], -1 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y]], [[NEG]] -; CHECK-NEXT: [[RET:%.*]] = add i32 [[AND]], [[AND1]] +; CHECK-NEXT: [[RET:%.*]] = or i32 [[AND]], [[AND1]] ; CHECK-NEXT: ret i32 [[RET]] ; %y = call i32 @gen32() @@ -161,7 +161,7 @@ define i32 @p_commutative2(i32 %x, i32 %y, i32 %m) { ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]] ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], -1 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[NEG]], [[Y:%.*]] -; CHECK-NEXT: [[RET:%.*]] = add i32 [[AND1]], [[AND]] +; CHECK-NEXT: [[RET:%.*]] = or i32 [[AND1]], [[AND]] ; CHECK-NEXT: ret i32 [[RET]] ; %and = and i32 %x, %m @@ -177,7 +177,7 @@ define i32 @p_commutative3(i32 %x, i32 %m) { ; CHECK-NEXT: [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]] ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], -1 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y]], [[NEG]] -; CHECK-NEXT: [[RET:%.*]] = add i32 [[AND]], [[AND1]] +; CHECK-NEXT: [[RET:%.*]] = or i32 [[AND]], [[AND1]] ; CHECK-NEXT: ret i32 [[RET]] ; %y = call i32 @gen32() @@ -193,7 +193,7 @@ define i32 @p_commutative4(i32 %x, i32 %y, i32 %m) { ; CHECK-NEXT: [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]] ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], -1 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[NEG]], [[Y:%.*]] -; CHECK-NEXT: [[RET:%.*]] = add i32 [[AND1]], [[AND]] +; CHECK-NEXT: [[RET:%.*]] = or i32 [[AND1]], [[AND]] ; CHECK-NEXT: ret i32 [[RET]] ; %and = and i32 %m, %x ; swapped order @@ -209,7 +209,7 @@ define i32 @p_commutative5(i32 %x, i32 %m) { ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]] ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], -1 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y]], [[NEG]] -; CHECK-NEXT: [[RET:%.*]] = add i32 [[AND1]], [[AND]] +; CHECK-NEXT: [[RET:%.*]] = or i32 [[AND1]], [[AND]] ; CHECK-NEXT: ret i32 [[RET]] ; %y = call i32 @gen32() @@ -226,7 +226,7 @@ define i32 @p_commutative6(i32 %x, i32 %m) { ; CHECK-NEXT: [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]] ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], -1 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y]], [[NEG]] -; CHECK-NEXT: [[RET:%.*]] = add i32 [[AND1]], [[AND]] +; CHECK-NEXT: [[RET:%.*]] = or i32 [[AND1]], [[AND]] ; CHECK-NEXT: ret i32 [[RET]] ; %y = call i32 @gen32() @@ -263,7 +263,7 @@ define i32 @n0_oneuse(i32 %x, i32 %y, i32 %m) { ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]] ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], -1 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[NEG]], [[Y:%.*]] -; CHECK-NEXT: [[RET:%.*]] = add i32 [[AND]], [[AND1]] +; CHECK-NEXT: [[RET:%.*]] = or i32 [[AND]], [[AND1]] ; CHECK-NEXT: call void @use32(i32 [[AND]]) ; CHECK-NEXT: call void @use32(i32 [[NEG]]) ; CHECK-NEXT: call void @use32(i32 [[AND1]]) |