[PATCH] D59071: [Transform] Improve saddo with mixed signs
Dan Robertson via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 6 19:09:32 PST 2019
dlrobertson created this revision.
dlrobertson added reviewers: nikic, spatel.
Herald added subscribers: llvm-commits, hiraditya.
Herald added a project: LLVM.
Improve folding of the `sadd.with.overflow` intrinsic with `add nsw`
when given constants of mixed signs.
https://reviews.llvm.org/D59071
Files:
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
llvm/test/Transforms/InstCombine/sadd-with-overflow.ll
Index: llvm/test/Transforms/InstCombine/sadd-with-overflow.ll
===================================================================
--- llvm/test/Transforms/InstCombine/sadd-with-overflow.ll
+++ llvm/test/Transforms/InstCombine/sadd-with-overflow.ll
@@ -17,16 +17,27 @@
ret { i32, i1 } %3
}
-define { i32, i1 } @fold_mixed_signs(i32) {
-; CHECK-LABEL: @fold_mixed_signs(
-; CHECK-NEXT: [[TMP2:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP0:%.*]], i32 6)
-; CHECK-NEXT: ret { i32, i1 } [[TMP2]]
+define { i32, i1 } @fold_mixed_signs_first_high(i32) {
+; CHECK-LABEL: @fold_mixed_signs_first_high(
+; CHECK-NEXT: [[TMP2:%.*]] = add nsw i32 [[TMP0:%.*]], 6
+; CHECK-NEXT: [[TMP3:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[TMP2]], 0
+; CHECK-NEXT: ret { i32, i1 } [[TMP3]]
;
%2 = add nsw i32 %0, 13
%3 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %2, i32 -7)
ret { i32, i1 } %3
}
+define { i32, i1 } @fold_mixed_signs_second_high(i32) {
+; CHECK-LABEL: @fold_mixed_signs_second_high(
+; CHECK-NEXT: [[TMP2:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP0:%.*]], i32 -6)
+; CHECK-NEXT: ret { i32, i1 } [[TMP2]]
+;
+ %2 = add nsw i32 %0, 7
+ %3 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %2, i32 -13)
+ ret { i32, i1 } %3
+}
+
define { i8, i1 } @fold_on_constant_add_no_overflow(i8) {
; CHECK-LABEL: @fold_on_constant_add_no_overflow(
; CHECK-NEXT: [[TMP2:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[TMP0:%.*]], i8 127)
Index: llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2035,8 +2035,19 @@
if (Instruction *I = foldIntrinsicWithOverflowCommon(II))
return I;
- // Given 2 constant operands whose sum does not overflow:
- // saddo (X +nsw C0), C1 -> saddo X, C0 + C1
+ // Given 2 constant operands whose sum does not overflow the intrinsic
+ // may be folded.
+ //
+ // Cases for `saddo (X +nsw C0), C1 -> saddo X, C0 + C1`:
+ //
+ // - Same sign can be folded to a single `saddo` call.
+ // - Opposite signs with `|C1| > |C0|` can be folded to a single `saddo`
+ // call.
+ //
+ // Cases for `saddo (X +nsw C0), C1 -> X +nsw (C0 + C1), false`:
+ //
+ // - Opposite signs with `|C1| <= |C0|` can be folded to a single `+nsw`
+ // call with the overflow flag set to false.
Value *X;
const APInt *C0, *C1;
Value *Arg0 = II->getArgOperand(0);
@@ -2045,11 +2056,19 @@
match(Arg1, m_APInt(C1))) {
bool Overflow;
APInt NewC = C1->sadd_ov(*C0, Overflow);
- if (!Overflow)
- return replaceInstUsesWith(
- *II, Builder.CreateBinaryIntrinsic(
- Intrinsic::sadd_with_overflow, X,
- ConstantInt::get(Arg1->getType(), NewC)));
+ if (!Overflow) {
+ if (C0->isNegative() == C1->isNegative() || C0->abs().slt(C1->abs())) {
+ return replaceInstUsesWith(
+ *II, Builder.CreateBinaryIntrinsic(
+ Intrinsic::sadd_with_overflow, X,
+ ConstantInt::get(Arg1->getType(), NewC)));
+ } else {
+ return CreateOverflowTuple(
+ II,
+ Builder.CreateNSWAdd(X, ConstantInt::get(Arg1->getType(), NewC)),
+ Builder.getFalse());
+ }
+ }
}
break;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D59071.189641.patch
Type: text/x-patch
Size: 3559 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190307/57a90ec2/attachment.bin>
More information about the llvm-commits
mailing list