[PATCH] D25135: [InstCombine] sub X, sext(bool Y) -> add X, zext(bool Y)
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 7 12:15:34 PDT 2016
spatel updated this revision to Diff 73964.
spatel added a comment.
Ping.
Minor update:
Not sure if the use of 'auto' was welcome here, so I changed it to 'BinaryOperator *Add'.
https://reviews.llvm.org/D25135
Files:
lib/Transforms/InstCombine/InstCombineAddSub.cpp
test/Transforms/InstCombine/sub.ll
test/Transforms/InstCombine/urem.ll
Index: test/Transforms/InstCombine/urem.ll
===================================================================
--- test/Transforms/InstCombine/urem.ll
+++ test/Transforms/InstCombine/urem.ll
@@ -25,12 +25,11 @@
ret i8 %rem
}
-; TODO: Should this be zext+add instead of sext+sub?
define i5 @biggest_divisor(i5 %x) {
; CHECK-LABEL: @biggest_divisor(
; CHECK-NEXT: [[NOT_:%.*]] = icmp eq i5 %x, -1
-; CHECK-NEXT: [[TMP1:%.*]] = sext i1 [[NOT_]] to i5
-; CHECK-NEXT: [[REM:%.*]] = sub i5 %x, [[TMP1]]
+; CHECK-NEXT: [[TMP1:%.*]] = zext i1 [[NOT_]] to i5
+; CHECK-NEXT: [[REM:%.*]] = add i5 [[TMP1]], %x
; CHECK-NEXT: ret i5 [[REM]]
;
%rem = urem i5 %x, -1
Index: test/Transforms/InstCombine/sub.ll
===================================================================
--- test/Transforms/InstCombine/sub.ll
+++ test/Transforms/InstCombine/sub.ll
@@ -639,3 +639,54 @@
%sub = sub i32 %sel0, %sel1
ret i32 %sub
}
+
+define i8 @bool_sext_sub(i8 %x, i1 %y) {
+; CHECK-LABEL: @bool_sext_sub(
+; CHECK-NEXT: [[TMP1:%.*]] = zext i1 %y to i8
+; CHECK-NEXT: [[SUB:%.*]] = add i8 [[TMP1]], %x
+; CHECK-NEXT: ret i8 [[SUB]]
+;
+ %sext = sext i1 %y to i8
+ %sub = sub i8 %x, %sext
+ ret i8 %sub
+}
+
+; Vectors get the same transform.
+
+define <2 x i8> @bool_sext_sub_vec(<2 x i8> %x, <2 x i1> %y) {
+; CHECK-LABEL: @bool_sext_sub_vec(
+; CHECK-NEXT: [[TMP1:%.*]] = zext <2 x i1> %y to <2 x i8>
+; CHECK-NEXT: [[SUB:%.*]] = add <2 x i8> [[TMP1]], %x
+; CHECK-NEXT: ret <2 x i8> [[SUB]]
+;
+ %sext = sext <2 x i1> %y to <2 x i8>
+ %sub = sub <2 x i8> %x, %sext
+ ret <2 x i8> %sub
+}
+
+; NSW is preserved.
+
+define <2 x i8> @bool_sext_sub_vec_nsw(<2 x i8> %x, <2 x i1> %y) {
+; CHECK-LABEL: @bool_sext_sub_vec_nsw(
+; CHECK-NEXT: [[TMP1:%.*]] = zext <2 x i1> %y to <2 x i8>
+; CHECK-NEXT: [[SUB:%.*]] = add nsw <2 x i8> [[TMP1]], %x
+; CHECK-NEXT: ret <2 x i8> [[SUB]]
+;
+ %sext = sext <2 x i1> %y to <2 x i8>
+ %sub = sub nsw <2 x i8> %x, %sext
+ ret <2 x i8> %sub
+}
+
+; Don't lose the information provided by NUW. If y is true, then x can only be 0xff.
+
+define i8 @bool_sext_sub_vec_nuw(i8 %x, i1 %y) {
+; CHECK-LABEL: @bool_sext_sub_vec_nuw(
+; CHECK-NEXT: [[SEXT:%.*]] = sext i1 %y to i8
+; CHECK-NEXT: [[SUB:%.*]] = sub nuw i8 %x, [[SEXT]]
+; CHECK-NEXT: ret i8 [[SUB]]
+;
+ %sext = sext i1 %y to i8
+ %sub = sub nuw i8 %x, %sext
+ ret i8 %sub
+}
+
Index: lib/Transforms/InstCombine/InstCombineAddSub.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1642,6 +1642,17 @@
if (Value *XNeg = dyn_castNegVal(X))
return BinaryOperator::CreateShl(XNeg, Y);
+ // Subtracting -1/0 is the same as adding 1/0:
+ // sub [nsw] Op0, sext(bool Y) -> add [nsw] Op0, zext(bool Y)
+ // But ignore a 'sub nuw' because we can't transfer nuw to the add.
+ if (!I.hasNoUnsignedWrap() && match(Op1, m_SExt(m_Value(Y))) &&
+ Y->getType()->getScalarSizeInBits() == 1) {
+ Value *Zext = Builder->CreateZExt(Y, I.getType());
+ BinaryOperator *Add = BinaryOperator::CreateAdd(Op0, Zext);
+ Add->setHasNoSignedWrap(I.hasNoSignedWrap());
+ return Add;
+ }
+
// X - A*-B -> X + A*B
// X - -A*B -> X + A*B
Value *A, *B;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D25135.73964.patch
Type: text/x-patch
Size: 3376 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20161007/d7fcd73a/attachment.bin>
More information about the llvm-commits
mailing list