return BinaryOperator::CreateAdd(X, ConstantExpr::getSub(C, C2));
}
+ // If there's no chance any bit will need to borrow from an adjacent bit:
+ // sub C, X --> xor X, C
const APInt *Op0C;
- if (match(Op0, m_APInt(Op0C)) && Op0C->isMask()) {
- // Turn this into a xor if LHS is 2^n-1 and the remaining bits are known
- // zero.
- KnownBits RHSKnown = computeKnownBits(Op1, 0, &I);
- if ((*Op0C | RHSKnown.Zero).isAllOnes())
- return BinaryOperator::CreateXor(Op1, Op0);
- }
+ if (match(Op0, m_APInt(Op0C)) &&
+ (~computeKnownBits(Op1, 0, &I).Zero).isSubsetOf(*Op0C))
+ return BinaryOperator::CreateXor(Op1, Op0);
{
Value *Y;
define i8 @masked_sub_i8(i8 %x) {
; CHECK-LABEL: @masked_sub_i8(
; CHECK-NEXT: [[A:%.*]] = and i8 [[X:%.*]], 10
-; CHECK-NEXT: [[M:%.*]] = sub nuw nsw i8 11, [[A]]
+; CHECK-NEXT: [[M:%.*]] = xor i8 [[A]], 11
; CHECK-NEXT: ret i8 [[M]]
;
%a = and i8 %x, 10 ; 0b00001010
define <2 x i5> @masked_sub_v2i5(<2 x i5> %x) {
; CHECK-LABEL: @masked_sub_v2i5(
; CHECK-NEXT: [[A:%.*]] = and <2 x i5> [[X:%.*]], <i5 -8, i5 -8>
-; CHECK-NEXT: [[M:%.*]] = sub nuw nsw <2 x i5> <i5 -6, i5 -6>, [[A]]
+; CHECK-NEXT: [[M:%.*]] = xor <2 x i5> [[A]], <i5 -6, i5 -6>
; CHECK-NEXT: ret <2 x i5> [[M]]
;
%a = and <2 x i5> %x, <i5 24, i5 24> ; 0b11000
ret <2 x i5> %m
}
+; negative test - sub constant isn't superset of masked bits
+
define i8 @not_masked_sub_i8(i8 %x) {
; CHECK-LABEL: @not_masked_sub_i8(
; CHECK-NEXT: [[A:%.*]] = and i8 [[X:%.*]], 7