[PATCH] D72978: [InstCombine] Combine neg of shl of sub (PR44529)
Nikita Popov via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sat Jan 18 08:07:32 PST 2020
nikic created this revision.
nikic added reviewers: lebedev.ri, spatel.
Herald added subscribers: llvm-commits, hiraditya.
Herald added a project: LLVM.
Fixes https://bugs.llvm.org/show_bug.cgi?id=44529. We already have a combine to sink a negation through a left-shift, but it currently only works if the shift operand is negatable without creating any instructions. This patch introduces `freelyNegateValue()` as a more powerful extension of `dyn_castNegVal()`, which allows negating a value as long as this doesn't end up increasing instruction count. Specifically, this patch adds support for negating `A-B` to `B-A`.
This mechanism could in the future be extended to handle general negation chains that a) start at a proper `0-X` negation and b) only require one operand to be freely negatable. This would end up as a weaker form of D68408 <https://reviews.llvm.org/D68408> aimed at the most obviously profitable subset (that eliminates a negation).
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D72978
Files:
llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
llvm/lib/Transforms/InstCombine/InstCombineInternal.h
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
llvm/test/Transforms/InstCombine/sub.ll
Index: llvm/test/Transforms/InstCombine/sub.ll
===================================================================
--- llvm/test/Transforms/InstCombine/sub.ll
+++ llvm/test/Transforms/InstCombine/sub.ll
@@ -543,9 +543,8 @@
define i64 @test_neg_shl_sub(i64 %a, i64 %b) {
; CHECK-LABEL: @test_neg_shl_sub(
-; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: [[MUL:%.*]] = shl i64 [[SUB]], 2
-; CHECK-NEXT: [[NEG:%.*]] = sub i64 0, [[MUL]]
+; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[B:%.*]], [[A:%.*]]
+; CHECK-NEXT: [[NEG:%.*]] = shl i64 [[TMP1]], 2
; CHECK-NEXT: ret i64 [[NEG]]
;
%sub = sub i64 %a, %b
Index: llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -856,6 +856,23 @@
return nullptr;
}
+/// Get negated V (that is 0-V) without increasing instruction count,
+/// assuming that the original V will become unused.
+Value *InstCombiner::freelyNegateValue(Value *V) {
+ if (Value *NegV = dyn_castNegVal(V))
+ return NegV;
+
+ if (!V->hasOneUse())
+ return nullptr;
+
+ Value *A, *B;
+ // 0-(A-B) => B-A
+ if (match(V, m_Sub(m_Value(A), m_Value(B))))
+ return Builder.CreateSub(B, A);
+
+ return nullptr;
+}
+
static Value *foldOperationIntoSelectOperand(Instruction &I, Value *SO,
InstCombiner::BuilderTy &Builder) {
if (auto *Cast = dyn_cast<CastInst>(&I))
Index: llvm/lib/Transforms/InstCombine/InstCombineInternal.h
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineInternal.h
+++ llvm/lib/Transforms/InstCombine/InstCombineInternal.h
@@ -474,6 +474,7 @@
bool shouldChangeType(unsigned FromBitWidth, unsigned ToBitWidth) const;
bool shouldChangeType(Type *From, Type *To) const;
Value *dyn_castNegVal(Value *V) const;
+ Value *freelyNegateValue(Value *V);
Type *FindElementAtOffset(PointerType *PtrTy, int64_t Offset,
SmallVectorImpl<Value *> &NewIndices);
Index: llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1985,7 +1985,7 @@
// 0 - (X << Y) -> (-X << Y) when X is freely negatable.
if (match(Op1, m_Shl(m_Value(X), m_Value(Y))) && match(Op0, m_Zero()))
- if (Value *XNeg = dyn_castNegVal(X))
+ if (Value *XNeg = freelyNegateValue(X))
return BinaryOperator::CreateShl(XNeg, Y);
// Subtracting -1/0 is the same as adding 1/0:
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D72978.238951.patch
Type: text/x-patch
Size: 2798 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200118/7337a887/attachment.bin>
More information about the llvm-commits
mailing list