[PATCH] D29729: [InstCombine] don't lose nsw/nuw from add by converting to xor
Sanjay Patel via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 8 14:45:39 PST 2017
spatel created this revision.
Herald added a subscriber: mcrosier.
I was looking at an improvement to InstSimplify when I noticed that this add fold in InstCombine was preventing icmp simplifies.
There's a later fold that special-cases (add (xor with signbit), C), so I don't think we're losing anything by limiting this.
'test20' and 'xor_sign_bit' in add.ll verify that the later fold still works, so there are no regressions in existing tests.
https://reviews.llvm.org/D29729
Files:
lib/Transforms/InstCombine/InstCombineAddSub.cpp
test/Transforms/InstCombine/add.ll
test/Transforms/InstCombine/icmp-add.ll
Index: test/Transforms/InstCombine/icmp-add.ll
===================================================================
--- test/Transforms/InstCombine/icmp-add.ll
+++ test/Transforms/InstCombine/icmp-add.ll
@@ -106,24 +106,22 @@
ret <2 x i1> %cmp
}
-; FIXME: InstCombine should not lose wrapping information by changing the add to xor.
+; InstCombine should not lose wrapping information by changing the add to xor.
define i1 @slt_zero_add_nsw_signbit(i8 %x) {
; CHECK-LABEL: @slt_zero_add_nsw_signbit(
-; CHECK-NEXT: [[Z:%.*]] = icmp sgt i8 %x, -1
-; CHECK-NEXT: ret i1 [[Z]]
+; CHECK-NEXT: ret i1 true
;
%y = add nsw i8 %x, -128
%z = icmp slt i8 %y, 0
ret i1 %z
}
-; FIXME: InstCombine should not lose wrapping information by changing the add to xor.
+; InstCombine should not lose wrapping information by changing the add to xor.
define i1 @slt_zero_add_nuw_signbit(i8 %x) {
; CHECK-LABEL: @slt_zero_add_nuw_signbit(
-; CHECK-NEXT: [[Z:%.*]] = icmp sgt i8 %x, -1
-; CHECK-NEXT: ret i1 [[Z]]
+; CHECK-NEXT: ret i1 true
;
%y = add nuw i8 %x, 128
%z = icmp slt i8 %y, 0
Index: test/Transforms/InstCombine/add.ll
===================================================================
--- test/Transforms/InstCombine/add.ll
+++ test/Transforms/InstCombine/add.ll
@@ -265,24 +265,24 @@
ret i32 %add
}
-; Lose no-wrap info by converting to xor? %x is known non-negative
+; Don't lose no-wrap info by converting to xor. %x is known non-negative
; here, but not after converting to xor.
define i8 @add_nsw_signbit(i8 %x) {
; CHECK-LABEL: @add_nsw_signbit(
-; CHECK-NEXT: [[Y:%.*]] = xor i8 %x, -128
+; CHECK-NEXT: [[Y:%.*]] = add nsw i8 %x, -128
; CHECK-NEXT: ret i8 [[Y]]
;
%y = add nsw i8 %x, -128
ret i8 %y
}
-; Lose no-wrap info by converting to xor? %x is known non-negative
+; Don't lose no-wrap info by converting to xor. %x is known non-negative
; (x < 128 unsigned), but not after converting to xor.
define i8 @add_nuw_signbit(i8 %x) {
; CHECK-LABEL: @add_nuw_signbit(
-; CHECK-NEXT: [[Y:%.*]] = xor i8 %x, -128
+; CHECK-NEXT: [[Y:%.*]] = add nuw i8 %x, -128
; CHECK-NEXT: ret i8 [[Y]]
;
%y = add nuw i8 %x, 128
Index: lib/Transforms/InstCombine/InstCombineAddSub.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1044,8 +1044,8 @@
const APInt *Val;
if (match(RHS, m_APInt(Val))) {
- // X + (signbit) --> X ^ signbit
- if (Val->isSignBit())
+ // X + (signbit) --> X ^ signbit, but only if we're not giving up NSW/NUW.
+ if (Val->isSignBit() && !I.hasNoSignedWrap() && !I.hasNoUnsignedWrap())
return BinaryOperator::CreateXor(LHS, RHS);
// Is this add the last step in a convoluted sext?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D29729.87714.patch
Type: text/x-patch
Size: 2851 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170208/875cab46/attachment.bin>
More information about the llvm-commits
mailing list