Skip to content

Commit 5271d33

Browse files
committed
[InstCombine] Add transform for ~X + ~Y) -> -2 - Y - X
Proof: https://alive2.llvm.org/ce/z/36FySK Closes #66787.
1 parent b7c0f79 commit 5271d33

File tree

2 files changed

+21
-5
lines changed

2 files changed

+21
-5
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1662,6 +1662,23 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
16621662
m_c_UMin(m_Deferred(A), m_Deferred(B))))))
16631663
return BinaryOperator::CreateWithCopiedFlags(Instruction::Add, A, B, &I);
16641664

1665+
// (~X) + (~Y) --> -2 - (X + Y)
1666+
{
1667+
// To ensure we can save instructions we need to ensure that we consume both
1668+
// LHS/RHS (i.e they have a `not`).
1669+
bool ConsumesLHS, ConsumesRHS;
1670+
if (isFreeToInvert(LHS, LHS->hasOneUse(), ConsumesLHS) && ConsumesLHS &&
1671+
isFreeToInvert(RHS, RHS->hasOneUse(), ConsumesRHS) && ConsumesRHS) {
1672+
Value *NotLHS = getFreelyInverted(LHS, LHS->hasOneUse(), &Builder);
1673+
Value *NotRHS = getFreelyInverted(RHS, RHS->hasOneUse(), &Builder);
1674+
assert(NotLHS != nullptr && NotRHS != nullptr &&
1675+
"isFreeToInvert desynced with getFreelyInverted");
1676+
Value *LHSPlusRHS = Builder.CreateAdd(NotLHS, NotRHS);
1677+
return BinaryOperator::CreateSub(ConstantInt::get(RHS->getType(), -2),
1678+
LHSPlusRHS);
1679+
}
1680+
}
1681+
16651682
// TODO(jingyue): Consider willNotOverflowSignedAdd and
16661683
// willNotOverflowUnsignedAdd to reduce the number of invocations of
16671684
// computeKnownBits.

llvm/test/Transforms/InstCombine/free-inversion.ll

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,10 @@ define i8 @sub_1(i8 %a, i1 %c, i8 %x, i8 %y) {
117117

118118
define i8 @sub_2(i8 %a, i1 %c, i8 %x, i8 %y) {
119119
; CHECK-LABEL: @sub_2(
120-
; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1
121-
; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 123
122-
; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]]
123-
; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[A:%.*]], -1
124-
; CHECK-NEXT: [[NOT_AB:%.*]] = add i8 [[B]], [[TMP1]]
120+
; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -124
121+
; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP1]]
122+
; CHECK-NEXT: [[TMP3:%.*]] = add i8 [[TMP2]], [[A:%.*]]
123+
; CHECK-NEXT: [[NOT_AB:%.*]] = sub i8 -2, [[TMP3]]
125124
; CHECK-NEXT: ret i8 [[NOT_AB]]
126125
;
127126
%nx = xor i8 %x, -1

0 commit comments

Comments
 (0)