summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp16
-rw-r--r--llvm/test/Transforms/InstCombine/abs-1.ll27
2 files changed, 43 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 0df56bd0c07..1e4c38c4c84 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1628,6 +1628,22 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
Value *ShAmtOp = cast<Instruction>(Op1)->getOperand(1);
return BinaryOperator::CreateLShr(X, ShAmtOp);
}
+
+ if (Op1->hasOneUse()) {
+ Value *LHS, *RHS;
+ SelectPatternFlavor SPF = matchSelectPattern(Op1, LHS, RHS).Flavor;
+ if (SPF == SPF_ABS || SPF == SPF_NABS) {
+ // This is a negate of an ABS/NABS pattern. Just swap the operands
+ // of the select.
+ SelectInst *SI = cast<SelectInst>(Op1);
+ Value *TrueVal = SI->getTrueValue();
+ Value *FalseVal = SI->getFalseValue();
+ SI->setTrueValue(FalseVal);
+ SI->setFalseValue(TrueVal);
+ // Don't swap prof metadata, we didn't change the branch behavior.
+ return replaceInstUsesWith(I, SI);
+ }
+ }
}
// Turn this into a xor if LHS is 2^n-1 and the remaining bits are known
diff --git a/llvm/test/Transforms/InstCombine/abs-1.ll b/llvm/test/Transforms/InstCombine/abs-1.ll
index ab1813c9043..2a94001b69d 100644
--- a/llvm/test/Transforms/InstCombine/abs-1.ll
+++ b/llvm/test/Transforms/InstCombine/abs-1.ll
@@ -266,3 +266,30 @@ define i8 @shifty_abs_too_many_uses(i8 %x) {
ret i8 %abs
}
+define i8 @negate_abs(i8 %x) {
+; CHECK-LABEL: @negate_abs(
+; CHECK-NEXT: [[N:%.*]] = sub i8 0, [[X:%.*]]
+; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[X]], 0
+; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 [[X]], i8 [[N]]
+; CHECK-NEXT: ret i8 [[S]]
+;
+ %n = sub i8 0, %x
+ %c = icmp slt i8 %x, 0
+ %s = select i1 %c, i8 %n, i8 %x
+ %r = sub i8 0, %s
+ ret i8 %r
+}
+
+define <2 x i8> @negate_nabs(<2 x i8> %x) {
+; CHECK-LABEL: @negate_nabs(
+; CHECK-NEXT: [[N:%.*]] = sub <2 x i8> zeroinitializer, [[X:%.*]]
+; CHECK-NEXT: [[C:%.*]] = icmp slt <2 x i8> [[X]], zeroinitializer
+; CHECK-NEXT: [[S:%.*]] = select <2 x i1> [[C]], <2 x i8> [[N]], <2 x i8> [[X]]
+; CHECK-NEXT: ret <2 x i8> [[S]]
+;
+ %n = sub <2 x i8> zeroinitializer, %x
+ %c = icmp slt <2 x i8> %x, zeroinitializer
+ %s = select <2 x i1> %c, <2 x i8> %x, <2 x i8> %n
+ %r = sub <2 x i8> zeroinitializer, %s
+ ret <2 x i8> %r
+}
OpenPOWER on IntegriCloud