summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2018-07-28 16:48:44 +0000
committerSanjay Patel <spatel@rotateright.com>2018-07-28 16:48:44 +0000
commit818b253d3a33e4881b5378beee1fa72a0bece912 (patch)
tree4e2a50682ef795d3c2989882d7a8ce112a2e9764
parent376051820d17cdc2feccb1878896d571db07f068 (diff)
downloadbcm5719-llvm-818b253d3a33e4881b5378beee1fa72a0bece912.tar.gz
bcm5719-llvm-818b253d3a33e4881b5378beee1fa72a0bece912.zip
[InstCombine] try to fold 'sub' to 'not'
https://rise4fun.com/Alive/jDd Patterns with add/sub combos can be improved using 'not' ops. This is better for analysis and may lead to follow-on transforms because 'xor' and 'add' are commutative/associative. It can also help codegen. llvm-svn: 338200
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp8
-rw-r--r--llvm/test/Transforms/InstCombine/sub-not.ll8
2 files changed, 11 insertions, 5 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index aa31e0d850d..e79bdf75d40 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -926,7 +926,13 @@ Instruction *InstCombiner::foldAddWithConstant(BinaryOperator &Add) {
if (Instruction *NV = foldBinOpIntoSelectOrPhi(Add))
return NV;
- Value *X;
+ Value *X, *Y;
+
+ // add (sub X, Y), -1 --> add (not Y), X
+ if (match(Op0, m_OneUse(m_Sub(m_Value(X), m_Value(Y)))) &&
+ match(Op1, m_AllOnes()))
+ return BinaryOperator::CreateAdd(Builder.CreateNot(Y), X);
+
// zext(bool) + C -> bool ? C + 1 : C
if (match(Op0, m_ZExt(m_Value(X))) &&
X->getType()->getScalarSizeInBits() == 1)
diff --git a/llvm/test/Transforms/InstCombine/sub-not.ll b/llvm/test/Transforms/InstCombine/sub-not.ll
index 5fc42367dad..c4fbbe22f4e 100644
--- a/llvm/test/Transforms/InstCombine/sub-not.ll
+++ b/llvm/test/Transforms/InstCombine/sub-not.ll
@@ -40,8 +40,8 @@ define <2 x i8> @sub_not_vec(<2 x i8> %x, <2 x i8> %y) {
define i8 @dec_sub(i8 %x, i8 %y) {
; CHECK-LABEL: @dec_sub(
-; CHECK-NEXT: [[S:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT: [[R:%.*]] = add i8 [[S]], -1
+; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -1
+; CHECK-NEXT: [[R:%.*]] = add i8 [[TMP1]], [[X:%.*]]
; CHECK-NEXT: ret i8 [[R]]
;
%s = sub i8 %x, %y
@@ -64,8 +64,8 @@ define i8 @dec_sub_extra_use(i8 %x, i8 %y) {
define <2 x i8> @dec_sub_vec(<2 x i8> %x, <2 x i8> %y) {
; CHECK-LABEL: @dec_sub_vec(
-; CHECK-NEXT: [[S:%.*]] = sub <2 x i8> [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[S]], <i8 -1, i8 undef>
+; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i8> [[Y:%.*]], <i8 -1, i8 -1>
+; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[TMP1]], [[X:%.*]]
; CHECK-NEXT: ret <2 x i8> [[R]]
;
%s = sub <2 x i8> %x, %y
OpenPOWER on IntegriCloud