Skip to content

Commit 554b1bc

Browse files
committed
[InstCombine] ~(C + X) --> ~C - X (PR50308)
We can not rely on (C+X)-->(X+C) already happening, because we might not have visited that `add` yet. The added testcase would get stuck in an endless combine loop.
1 parent a383d32 commit 554b1bc

File tree

2 files changed

+37
-8
lines changed

2 files changed

+37
-8
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3352,11 +3352,6 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
33523352
}
33533353
}
33543354

3355-
// ~(X - Y) --> ~X + Y
3356-
if (match(NotVal, m_Sub(m_Value(X), m_Value(Y))))
3357-
if (isa<Constant>(X) || NotVal->hasOneUse())
3358-
return BinaryOperator::CreateAdd(Builder.CreateNot(X), Y);
3359-
33603355
// ~((-X) | Y) --> (X - 1) & (~Y)
33613356
if (match(NotVal,
33623357
m_OneUse(m_c_Or(m_OneUse(m_Neg(m_Value(X))), m_Value(Y))))) {
@@ -3395,9 +3390,15 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
33953390
return BinaryOperator::CreateAShr(ConstantExpr::getNot(C), Y);
33963391
}
33973392

3398-
// ~(X + C) --> -(C + 1) - X
3399-
if (match(Op0, m_Add(m_Value(X), m_Constant(C))))
3400-
return BinaryOperator::CreateSub(ConstantExpr::getNeg(AddOne(C)), X);
3393+
// ~(X + C) --> ~C - X
3394+
if (match(NotVal, m_c_Add(m_Value(X), m_ImmConstant(C))))
3395+
return BinaryOperator::CreateSub(ConstantExpr::getNot(C), X);
3396+
3397+
// ~(X - Y) --> ~X + Y
3398+
// FIXME: is it really beneficial to sink the `not` here?
3399+
if (match(NotVal, m_Sub(m_Value(X), m_Value(Y))))
3400+
if (isa<Constant>(X) || NotVal->hasOneUse())
3401+
return BinaryOperator::CreateAdd(Builder.CreateNot(X), Y);
34013402

34023403
// ~(~X + Y) --> X - Y
34033404
if (match(NotVal, m_c_Add(m_Not(m_Value(X)), m_Value(Y))))

llvm/test/Transforms/InstCombine/not-add.ll

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,31 @@ define <4 x i32> @vector_test_undef_nsw_nuw(<4 x i32> %x, <4 x i32> %y) {
137137
%nota = xor <4 x i32> %a, <i32 -1, i32 -1, i32 undef, i32 undef>
138138
ret <4 x i32> %nota
139139
}
140+
141+
define i32 @pr50308(i1 %c1, i32 %v1, i32 %v2, i32 %v3) {
142+
; CHECK-LABEL: @pr50308(
143+
; CHECK-NEXT: entry:
144+
; CHECK-NEXT: br i1 [[C1:%.*]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
145+
; CHECK: cond.true:
146+
; CHECK-NEXT: [[ADD_NOT:%.*]] = sub i32 -2, [[V1:%.*]]
147+
; CHECK-NEXT: [[ADD1_NEG:%.*]] = xor i32 [[ADD_NOT]], [[V2:%.*]]
148+
; CHECK-NEXT: br label [[COND_END]]
149+
; CHECK: cond.end:
150+
; CHECK-NEXT: [[COND_NEG:%.*]] = phi i32 [ [[ADD1_NEG]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
151+
; CHECK-NEXT: [[SUB:%.*]] = add i32 [[COND_NEG]], [[V3:%.*]]
152+
; CHECK-NEXT: ret i32 [[SUB]]
153+
;
154+
entry:
155+
br i1 %c1, label %cond.true, label %cond.end
156+
157+
cond.true:
158+
%add = add nsw i32 1, %v1
159+
%xor = xor i32 %add, %v2
160+
%add1 = add nsw i32 1, %xor
161+
br label %cond.end
162+
163+
cond.end:
164+
%cond = phi i32 [ %add1, %cond.true ], [ 0, %entry ]
165+
%sub = sub nsw i32 %v3, %cond
166+
ret i32 %sub
167+
}

0 commit comments

Comments
 (0)