Skip to content

Commit 3aa009c

Browse files
committed
[InstCombine] generalize subtract with 'not' operands
The motivation was to get min/max intrinsics to parity with cmp+select idioms, but this unlocks a few more folds because isFreeToInvert recognizes add/sub with constants too. In the min/max example, we have too many extra uses for smaller folds to improve things, but this fold is able to eliminate uses even though we can't reduce the number of instructions.
1 parent 7f48bd3 commit 3aa009c

File tree

4 files changed

+13
-15
lines changed

4 files changed

+13
-15
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1829,11 +1829,15 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
18291829
return BinaryOperator::CreateNot(Op1);
18301830

18311831
// (~X) - (~Y) --> Y - X
1832-
Value *X, *Y;
1833-
if (match(Op0, m_Not(m_Value(X))) && match(Op1, m_Not(m_Value(Y))))
1834-
return BinaryOperator::CreateSub(Y, X);
1832+
if (isFreeToInvert(Op0, Op0->hasOneUse()) &&
1833+
isFreeToInvert(Op1, Op1->hasOneUse())) {
1834+
Value *NotOp0 = Builder.CreateNot(Op0);
1835+
Value *NotOp1 = Builder.CreateNot(Op1);
1836+
return BinaryOperator::CreateSub(NotOp1, NotOp0);
1837+
}
18351838

18361839
// (X + -1) - Y --> ~Y + X
1840+
Value *X, *Y;
18371841
if (match(Op0, m_OneUse(m_Add(m_Value(X), m_AllOnes()))))
18381842
return BinaryOperator::CreateAdd(Builder.CreateNot(Op1), X);
18391843

llvm/test/Transforms/InstCombine/minmax-intrinsics.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,8 +1157,8 @@ define i8 @freeToInvertSub(i8 %x, i8 %y, i8 %z) {
11571157
; CHECK-NEXT: call void @use(i8 [[NX]])
11581158
; CHECK-NEXT: call void @use(i8 [[NY]])
11591159
; CHECK-NEXT: call void @use(i8 [[NZ]])
1160-
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umax.i8(i8 [[NX]], i8 [[NY]])
1161-
; CHECK-NEXT: [[SUB:%.*]] = sub i8 [[NZ]], [[M]]
1160+
; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[X]], i8 [[Y]])
1161+
; CHECK-NEXT: [[SUB:%.*]] = sub i8 [[TMP1]], [[Z]]
11621162
; CHECK-NEXT: ret i8 [[SUB]]
11631163
;
11641164
%nx = xor i8 %x, -1

llvm/test/Transforms/InstCombine/reassociate-nuw.ll

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,8 @@ define i32 @reassoc_x2_mul_nuw(i32 %x, i32 %y) {
7979

8080
define i32 @reassoc_x2_sub_nuw(i32 %x, i32 %y) {
8181
; CHECK-LABEL: @reassoc_x2_sub_nuw(
82-
; CHECK-NEXT: [[SUB0:%.*]] = add i32 [[X:%.*]], -4
83-
; CHECK-NEXT: [[SUB1:%.*]] = add i32 [[Y:%.*]], -8
84-
; CHECK-NEXT: [[SUB2:%.*]] = sub nuw i32 [[SUB0]], [[SUB1]]
82+
; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]
83+
; CHECK-NEXT: [[SUB2:%.*]] = add i32 [[TMP1]], 4
8584
; CHECK-NEXT: ret i32 [[SUB2]]
8685
;
8786
%sub0 = sub nuw i32 %x, 4

llvm/test/Transforms/InstCombine/sub.ll

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,14 +1109,9 @@ define i32 @test57(i32 %A, i32 %B) {
11091109
@dummy_global2 = external global i8*
11101110

11111111
define i64 @test58([100 x [100 x i8]]* %foo, i64 %i, i64 %j) {
1112-
; Note the reassociate pass and another instcombine pass will further optimize this to
1113-
; "%sub = i64 %i, %j, ret i64 %sub"
1114-
; gep1 and gep2 have only one use
11151112
; CHECK-LABEL: @test58(
1116-
; CHECK-NEXT: [[GEP1_OFFS:%.*]] = add nsw i64 [[I:%.*]], 4200
1117-
; CHECK-NEXT: [[GEP2_OFFS:%.*]] = add nsw i64 [[J:%.*]], 4200
1118-
; CHECK-NEXT: [[GEPDIFF:%.*]] = sub nsw i64 [[GEP1_OFFS]], [[GEP2_OFFS]]
1119-
; CHECK-NEXT: ret i64 [[GEPDIFF]]
1113+
; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[I:%.*]], [[J:%.*]]
1114+
; CHECK-NEXT: ret i64 [[TMP1]]
11201115
;
11211116
%gep1 = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 42, i64 %i
11221117
%gep2 = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 42, i64 %j

0 commit comments

Comments
 (0)