Skip to content

Commit 78e4b4d

Browse files
committed
[InstCombine] not(sub X, Y) --> add (not X), Y
The tests with constants show a missing optimization. Analysis for adds is better than subs, so this can also help with other transforms. And codegen is better with adds for targets like x86 (destructive ops, no sub-from). https://rise4fun.com/Alive/llK llvm-svn: 338118
1 parent eee52b5 commit 78e4b4d

File tree

3 files changed

+12
-10
lines changed

3 files changed

+12
-10
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -2545,6 +2545,10 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
25452545
}
25462546
}
25472547

2548+
// ~(X - Y) --> ~X + Y
2549+
if (match(NotVal, m_OneUse(m_Sub(m_Value(X), m_Value(Y)))))
2550+
return BinaryOperator::CreateAdd(Builder.CreateNot(X), Y);
2551+
25482552
// ~(~X >>s Y) --> (X >>s Y)
25492553
if (match(NotVal, m_AShr(m_Not(m_Value(X)), m_Value(Y))))
25502554
return BinaryOperator::CreateAShr(X, Y);

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ declare void @use(i8)
55

66
define i8 @sub_not(i8 %x, i8 %y) {
77
; CHECK-LABEL: @sub_not(
8-
; CHECK-NEXT: [[S:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]
9-
; CHECK-NEXT: [[R:%.*]] = xor i8 [[S]], -1
8+
; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X:%.*]], -1
9+
; CHECK-NEXT: [[R:%.*]] = add i8 [[TMP1]], [[Y:%.*]]
1010
; CHECK-NEXT: ret i8 [[R]]
1111
;
1212
%s = sub i8 %x, %y
@@ -29,8 +29,8 @@ define i8 @sub_not_extra_use(i8 %x, i8 %y) {
2929

3030
define <2 x i8> @sub_not_vec(<2 x i8> %x, <2 x i8> %y) {
3131
; CHECK-LABEL: @sub_not_vec(
32-
; CHECK-NEXT: [[S:%.*]] = sub <2 x i8> [[X:%.*]], [[Y:%.*]]
33-
; CHECK-NEXT: [[R:%.*]] = xor <2 x i8> [[S]], <i8 -1, i8 undef>
32+
; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i8> [[X:%.*]], <i8 -1, i8 -1>
33+
; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[TMP1]], [[Y:%.*]]
3434
; CHECK-NEXT: ret <2 x i8> [[R]]
3535
;
3636
%s = sub <2 x i8> %x, %y

llvm/test/Transforms/InstCombine/vector-xor.ll

+4-6
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,8 @@ define <4 x i32> @test_v4i32_not_sub_splatconst(<4 x i32> %a0) {
194194

195195
define <4 x i32> @test_v4i32_not_sub_const(<4 x i32> %a0) {
196196
; CHECK-LABEL: @test_v4i32_not_sub_const(
197-
; CHECK-NEXT: [[TMP1:%.*]] = sub <4 x i32> <i32 3, i32 5, i32 -1, i32 15>, [[A0:%.*]]
198-
; CHECK-NEXT: [[TMP2:%.*]] = xor <4 x i32> [[TMP1]], <i32 -1, i32 -1, i32 -1, i32 -1>
199-
; CHECK-NEXT: ret <4 x i32> [[TMP2]]
197+
; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i32> [[A0:%.*]], <i32 -4, i32 -6, i32 0, i32 -16>
198+
; CHECK-NEXT: ret <4 x i32> [[TMP1]]
200199
;
201200
%1 = sub <4 x i32> <i32 3, i32 5, i32 -1, i32 15>, %a0
202201
%2 = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, %1
@@ -205,9 +204,8 @@ define <4 x i32> @test_v4i32_not_sub_const(<4 x i32> %a0) {
205204

206205
define <4 x i32> @test_v4i32_not_sub_const_undef(<4 x i32> %a0) {
207206
; CHECK-LABEL: @test_v4i32_not_sub_const_undef(
208-
; CHECK-NEXT: [[TMP1:%.*]] = sub <4 x i32> <i32 3, i32 undef, i32 -1, i32 15>, [[A0:%.*]]
209-
; CHECK-NEXT: [[TMP2:%.*]] = xor <4 x i32> [[TMP1]], <i32 -1, i32 -1, i32 -1, i32 undef>
210-
; CHECK-NEXT: ret <4 x i32> [[TMP2]]
207+
; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i32> [[A0:%.*]], <i32 -4, i32 undef, i32 0, i32 -16>
208+
; CHECK-NEXT: ret <4 x i32> [[TMP1]]
211209
;
212210
%1 = sub <4 x i32> <i32 3, i32 undef, i32 -1, i32 15>, %a0
213211
%2 = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 undef>, %1

0 commit comments

Comments
 (0)