Skip to content

Commit 4973ce5

Browse files
LebedevRItstellar
authored andcommitted
~(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. (cherry-picked from 554b1bc)
1 parent de579ba commit 4973ce5

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
@@ -3221,11 +3221,6 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
32213221
}
32223222
}
32233223

3224-
// ~(X - Y) --> ~X + Y
3225-
if (match(NotVal, m_Sub(m_Value(X), m_Value(Y))))
3226-
if (isa<Constant>(X) || NotVal->hasOneUse())
3227-
return BinaryOperator::CreateAdd(Builder.CreateNot(X), Y);
3228-
32293224
// ~(~X >>s Y) --> (X >>s Y)
32303225
if (match(NotVal, m_AShr(m_Not(m_Value(X)), m_Value(Y))))
32313226
return BinaryOperator::CreateAShr(X, Y);
@@ -3256,9 +3251,15 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
32563251
return BinaryOperator::CreateAShr(ConstantExpr::getNot(C), Y);
32573252
}
32583253

3259-
// ~(X + C) --> -(C + 1) - X
3260-
if (match(Op0, m_Add(m_Value(X), m_Constant(C))))
3261-
return BinaryOperator::CreateSub(ConstantExpr::getNeg(AddOne(C)), X);
3254+
// ~(X + C) --> ~C - X
3255+
if (match(NotVal, m_c_Add(m_Value(X), m_ImmConstant(C))))
3256+
return BinaryOperator::CreateSub(ConstantExpr::getNot(C), X);
3257+
3258+
// ~(X - Y) --> ~X + Y
3259+
// FIXME: is it really beneficial to sink the `not` here?
3260+
if (match(NotVal, m_Sub(m_Value(X), m_Value(Y))))
3261+
if (isa<Constant>(X) || NotVal->hasOneUse())
3262+
return BinaryOperator::CreateAdd(Builder.CreateNot(X), Y);
32623263

32633264
// ~(~X + Y) --> X - Y
32643265
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)