[llvm] 3a3c951 - [InstCombine] Negator: 0 - (X + Y) --> (-X) - Y iff a single operand negated
Roman Lebedev via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 5 10:01:59 PDT 2020
Author: Roman Lebedev
Date: 2020-08-05T20:01:13+03:00
New Revision: 3a3c9519e272e664172a0a90e8abf84b6d400106
URL: https://github.com/llvm/llvm-project/commit/3a3c9519e272e664172a0a90e8abf84b6d400106
DIFF: https://github.com/llvm/llvm-project/commit/3a3c9519e272e664172a0a90e8abf84b6d400106.diff
LOG: [InstCombine] Negator: 0 - (X + Y) --> (-X) - Y iff a single operand negated
This was the most obvious regression in
f5df5cd5586ae9cfb2d9e53704dfc76f47aff149.f5df5cd5586ae9cfb2d9e53704dfc76f47aff149
We really don't want to do this if the original/outermost subtraction
isn't a negation, and therefore doesn't go away - just sinking negation
isn't a win. We are actually appear to be missing folds so hoist it.
https://rise4fun.com/Alive/tiVe
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
llvm/test/Transforms/InstCombine/sub-of-negatible.ll
llvm/test/Transforms/InstCombine/sub.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp b/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
index b684016b6a29..be69061b3947 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
@@ -347,13 +347,32 @@ LLVM_NODISCARD Value *Negator::visitImpl(Value *V, unsigned Depth) {
LLVM_FALLTHROUGH;
case Instruction::Add: {
// `add` is negatible if both of its operands are negatible.
- Value *NegOp0 = negate(I->getOperand(0), Depth + 1);
- if (!NegOp0) // Early return.
- return nullptr;
- Value *NegOp1 = negate(I->getOperand(1), Depth + 1);
- if (!NegOp1)
+ SmallVector<Value *, 2> NegatedOps, NonNegatedOps;
+ for (Value *Op : I->operands()) {
+ // Can we sink the negation into this operand?
+ if (Value *NegOp = negate(Op, Depth + 1)) {
+ NegatedOps.emplace_back(NegOp); // Successfully negated operand!
+ continue;
+ }
+ // Failed to sink negation into this operand. IFF we started from negation
+ // and we manage to sink negation into one operand, we can still do this.
+ if (!IsTrulyNegation)
+ return nullptr;
+ NonNegatedOps.emplace_back(Op); // Just record which operand that was.
+ }
+ assert((NegatedOps.size() + NonNegatedOps.size()) == 2 &&
+ "Internal consistency sanity check.");
+ // Did we manage to sink negation into both of the operands?
+ if (NegatedOps.size() == 2) // Then we get to keep the `add`!
+ return Builder.CreateAdd(NegatedOps[0], NegatedOps[1],
+ I->getName() + ".neg");
+ assert(IsTrulyNegation && "We should have early-exited then.");
+ // Completely failed to sink negation?
+ if (NonNegatedOps.size() == 2)
return nullptr;
- return Builder.CreateAdd(NegOp0, NegOp1, I->getName() + ".neg");
+ // 0-(a+b) --> (-a)-b
+ return Builder.CreateSub(NegatedOps[0], NonNegatedOps[0],
+ I->getName() + ".neg");
}
case Instruction::Xor:
// `xor` is negatible if one of its operands is invertible.
diff --git a/llvm/test/Transforms/InstCombine/sub-of-negatible.ll b/llvm/test/Transforms/InstCombine/sub-of-negatible.ll
index 478724dc5207..f1f0609c924a 100644
--- a/llvm/test/Transforms/InstCombine/sub-of-negatible.ll
+++ b/llvm/test/Transforms/InstCombine/sub-of-negatible.ll
@@ -1106,9 +1106,8 @@ define i8 @negate_left_shift_by_constant_extrause(i8 %x, i8 %y, i8 %z, i8 %k) {
; `add` with single negatible operand is still negatible
define i8 @negate_add_with_single_negatible_operand(i8 %x, i8 %y) {
; CHECK-LABEL: @negate_add_with_single_negatible_operand(
-; CHECK-NEXT: [[T0:%.*]] = add i8 [[X:%.*]], 42
-; CHECK-NEXT: [[T1:%.*]] = sub i8 0, [[T0]]
-; CHECK-NEXT: ret i8 [[T1]]
+; CHECK-NEXT: [[T0_NEG:%.*]] = sub i8 -42, [[X:%.*]]
+; CHECK-NEXT: ret i8 [[T0_NEG]]
;
%t0 = add i8 %x, 42
%t1 = sub i8 0, %t0
@@ -1126,6 +1125,7 @@ define i8 @negate_add_with_single_negatible_operand_extrause(i8 %x, i8 %y) {
%t1 = sub i8 0, %t0
ret i8 %t1
}
+; But don't do this if that means just sinking the negation.
define i8 @negate_add_with_single_negatible_operand_non_negation(i8 %x, i8 %y) {
; CHECK-LABEL: @negate_add_with_single_negatible_operand_non_negation(
; CHECK-NEXT: [[T0:%.*]] = add i8 [[X:%.*]], 42
diff --git a/llvm/test/Transforms/InstCombine/sub.ll b/llvm/test/Transforms/InstCombine/sub.ll
index 4116a79d66d9..d2e566be3411 100644
--- a/llvm/test/Transforms/InstCombine/sub.ll
+++ b/llvm/test/Transforms/InstCombine/sub.ll
@@ -839,10 +839,9 @@ define i64 @test29(i8* %foo, i64 %i, i64 %j) {
define i64 @test30(i8* %foo, i64 %i, i64 %j) {
; CHECK-LABEL: @test30(
-; CHECK-NEXT: [[GEP1_IDX_NEG:%.*]] = mul i64 [[I:%.*]], -4
-; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[GEP1_IDX_NEG]], [[J:%.*]]
-; CHECK-NEXT: [[DIFF_NEG:%.*]] = sub i64 0, [[TMP1]]
-; CHECK-NEXT: ret i64 [[DIFF_NEG]]
+; CHECK-NEXT: [[GEP1_IDX_NEG_NEG:%.*]] = shl i64 [[I:%.*]], 2
+; CHECK-NEXT: [[DOTNEG:%.*]] = sub i64 [[GEP1_IDX_NEG_NEG]], [[J:%.*]]
+; CHECK-NEXT: ret i64 [[DOTNEG]]
;
%bit = bitcast i8* %foo to i32*
%gep1 = getelementptr inbounds i32, i32* %bit, i64 %i
@@ -855,10 +854,9 @@ define i64 @test30(i8* %foo, i64 %i, i64 %j) {
define i16 @test30_as1(i8 addrspace(1)* %foo, i16 %i, i16 %j) {
; CHECK-LABEL: @test30_as1(
-; CHECK-NEXT: [[GEP1_IDX_NEG:%.*]] = mul i16 [[I:%.*]], -4
-; CHECK-NEXT: [[TMP1:%.*]] = add i16 [[GEP1_IDX_NEG]], [[J:%.*]]
-; CHECK-NEXT: [[DIFF_NEG:%.*]] = sub i16 0, [[TMP1]]
-; CHECK-NEXT: ret i16 [[DIFF_NEG]]
+; CHECK-NEXT: [[GEP1_IDX_NEG_NEG:%.*]] = shl i16 [[I:%.*]], 2
+; CHECK-NEXT: [[DOTNEG:%.*]] = sub i16 [[GEP1_IDX_NEG_NEG]], [[J:%.*]]
+; CHECK-NEXT: ret i16 [[DOTNEG]]
;
%bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)*
%gep1 = getelementptr inbounds i32, i32 addrspace(1)* %bit, i16 %i
More information about the llvm-commits
mailing list