[PATCH] D46988: [InstCombine] Propagate the nsw/nuw flags from the add in the 'shifty' abs pattern to the sub in the select version.

Phabricator via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu May 17 09:33:48 PDT 2018


This revision was automatically updated to reflect the committed changes.
Closed by commit rL332623: [InstCombine] Propagate the nsw/nuw flags from the add in the 'shifty' abs… (authored by ctopper, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D46988?vs=147210&id=147334#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D46988

Files:
  llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
  llvm/trunk/test/Transforms/InstCombine/abs-1.ll


Index: llvm/trunk/test/Transforms/InstCombine/abs-1.ll
===================================================================
--- llvm/trunk/test/Transforms/InstCombine/abs-1.ll
+++ llvm/trunk/test/Transforms/InstCombine/abs-1.ll
@@ -59,6 +59,34 @@
   ret i8 %abs
 }
 
+define i8 @shifty_abs_commute0_nsw(i8 %x) {
+; CHECK-LABEL: @shifty_abs_commute0_nsw(
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8 %x, 0
+; CHECK-NEXT:    [[TMP2:%.*]] = sub nsw i8 0, %x
+; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[TMP1]], i8 [[TMP2]], i8 %x
+; CHECK-NEXT:    ret i8 [[ABS]]
+;
+  %signbit = ashr i8 %x, 7
+  %add = add nsw i8 %signbit, %x
+  %abs = xor i8 %add, %signbit
+  ret i8 %abs
+}
+
+; The nuw flag creates a contradiction. If the shift produces all 1s, the only
+; way for the add to not wrap is for %x to be 0, but then the shift couldn't
+; have produced all 1s. We partially optimize this.
+define i8 @shifty_abs_commute0_nuw(i8 %x) {
+; CHECK-LABEL: @shifty_abs_commute0_nuw(
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i8 %x, 0
+; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[TMP1]], i8 %x, i8 0
+; CHECK-NEXT:    ret i8 [[ABS]]
+;
+  %signbit = ashr i8 %x, 7
+  %add = add nuw i8 %signbit, %x
+  %abs = xor i8 %add, %signbit
+  ret i8 %abs
+}
+
 define <2 x i8> @shifty_abs_commute1(<2 x i8> %x) {
 ; CHECK-LABEL: @shifty_abs_commute1(
 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <2 x i8> %x, zeroinitializer
Index: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
===================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2748,7 +2748,11 @@
     // xor (add A, B), B  ; add -1 and flip bits if negative
     // --> (A < 0) ? -A : A
     Value *Cmp = Builder.CreateICmpSLT(A, ConstantInt::getNullValue(Ty));
-    return SelectInst::Create(Cmp, Builder.CreateNeg(A), A);
+    // Copy the nuw/nsw flags from the add to the negate.
+    auto *Add = cast<BinaryOperator>(Op0);
+    Value *Neg = Builder.CreateNeg(A, "", Add->hasNoUnsignedWrap(),
+                                   Add->hasNoSignedWrap());
+    return SelectInst::Create(Cmp, Neg, A);
   }
 
   // Eliminate a bitwise 'not' op of 'not' min/max by inverting the min/max:


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D46988.147334.patch
Type: text/x-patch
Size: 2283 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180517/be8fb0b8/attachment.bin>


More information about the llvm-commits mailing list