Skip to content

Commit e465f9c

Browse files
committed
[InstCombine] Negator: - (C - %x) --> %x - C (PR47997)
This relaxes one-use restriction on that `sub` fold, since apparently the addition of Negator broke preexisting `C-(C2-X) --> X+(C-C2)` (with C=0) fold.
1 parent f8cf6d0 commit e465f9c

File tree

3 files changed

+14
-13
lines changed

3 files changed

+14
-13
lines changed

llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -219,19 +219,22 @@ LLVM_NODISCARD Value *Negator::visitImpl(Value *V, unsigned Depth) {
219219
break; // Other instructions require recursive reasoning.
220220
}
221221

222+
if (I->getOpcode() == Instruction::Sub &&
223+
(I->hasOneUse() || (isa<Constant>(I->getOperand(0)) &&
224+
!isa<ConstantExpr>(I->getOperand(0))))) {
225+
// `sub` is always negatible.
226+
// However, only do this either if the old `sub` doesn't stick around, or
227+
// it was subtracting from a constant. Otherwise, this isn't profitable.
228+
return Builder.CreateSub(I->getOperand(1), I->getOperand(0),
229+
I->getName() + ".neg");
230+
}
231+
222232
// Some other cases, while still don't require recursion,
223233
// are restricted to the one-use case.
224234
if (!V->hasOneUse())
225235
return nullptr;
226236

227237
switch (I->getOpcode()) {
228-
case Instruction::Sub:
229-
// `sub` is always negatible.
230-
// But if the old `sub` sticks around, even thought we don't increase
231-
// instruction count, this is a likely regression since we increased
232-
// live-range of *both* of the operands, which might lead to more spilling.
233-
return Builder.CreateSub(I->getOperand(1), I->getOperand(0),
234-
I->getName() + ".neg");
235238
case Instruction::SDiv:
236239
// `sdiv` is negatible if divisor is not undef/INT_MIN/1.
237240
// While this is normally not behind a use-check,

llvm/test/Transforms/InstCombine/icmp.ll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3831,9 +3831,7 @@ define i1 @pr47997(i32 %arg) {
38313831
; CHECK-NEXT: store i32 [[I]], i32* @x, align 4
38323832
; CHECK-NEXT: [[I1:%.*]] = sub nsw i32 1, [[ARG]]
38333833
; CHECK-NEXT: store i32 [[I1]], i32* @y, align 4
3834-
; CHECK-NEXT: [[I2:%.*]] = sub nsw i32 0, [[I1]]
3835-
; CHECK-NEXT: [[I3:%.*]] = icmp eq i32 [[I]], [[I2]]
3836-
; CHECK-NEXT: ret i1 [[I3]]
3834+
; CHECK-NEXT: ret i1 true
38373835
;
38383836
bb:
38393837
%i = add nsw i32 %arg, -1

llvm/test/Transforms/InstCombine/sub-of-negatible.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,10 +195,10 @@ define i8 @neg_of_sub_from_constant(i8 %x) {
195195

196196
define i8 @neg_of_sub_from_constant_multi_use(i8 %x) {
197197
; CHECK-LABEL: @neg_of_sub_from_constant_multi_use(
198-
; CHECK-NEXT: [[S:%.*]] = sub i8 42, [[X:%.*]]
198+
; CHECK-NEXT: [[S_NEG:%.*]] = add i8 [[X:%.*]], -42
199+
; CHECK-NEXT: [[S:%.*]] = sub i8 42, [[X]]
199200
; CHECK-NEXT: call void @use8(i8 [[S]])
200-
; CHECK-NEXT: [[R:%.*]] = sub i8 0, [[S]]
201-
; CHECK-NEXT: ret i8 [[R]]
201+
; CHECK-NEXT: ret i8 [[S_NEG]]
202202
;
203203
%s = sub i8 42, %x
204204
call void @use8(i8 %s)

0 commit comments

Comments
 (0)