[llvm] 6c39a3a - [InstCombine] fold not-shift of signbit to icmp+zext

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 29 07:09:19 PDT 2022


Author: Sanjay Patel
Date: 2022-08-29T10:06:31-04:00
New Revision: 6c39a3aae1dcce6ba1373289480c49c2d41e0a88

URL: https://github.com/llvm/llvm-project/commit/6c39a3aae1dcce6ba1373289480c49c2d41e0a88
DIFF: https://github.com/llvm/llvm-project/commit/6c39a3aae1dcce6ba1373289480c49c2d41e0a88.diff

LOG: [InstCombine] fold not-shift of signbit to icmp+zext

https://alive2.llvm.org/ce/z/j_8Wz9

The arithmetic shift was converted to logical shift with:
246078604c871d43

That does not seem to uncover any other missing/conflicting folds,
so convert directly to signbit test + cast.

We still need to fold the pattern with logical shift to test + cast.

This allows reducing patterns where the output type is not
the same as the input value:
https://alive2.llvm.org/ce/z/nydwFV

Fixes #57394

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
    llvm/test/Transforms/InstCombine/add.ll
    llvm/test/Transforms/InstCombine/high-bit-signmask.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 8a49943f52bf..c8b3fd05a8db 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -884,13 +884,13 @@ Instruction *InstCombinerImpl::foldAddWithConstant(BinaryOperator &Add) {
   if (match(Op0, m_Not(m_Value(X))))
     return BinaryOperator::CreateSub(InstCombiner::SubOne(Op1C), X);
 
-  // (iN X s>> (N - 1)) + 1 --> (~X) u>> (N - 1)
+  // (iN X s>> (N - 1)) + 1 --> zext (X > -1)
   const APInt *C;
-  if (match(Op0, m_OneUse(m_AShr(m_Value(X), m_APIntAllowUndef(C)))) &&
-      *C == (Ty->getScalarSizeInBits() - 1) && match(Op1, m_One())) {
-    Value *NotX = Builder.CreateNot(X, X->getName() + ".not");
-    return BinaryOperator::CreateLShr(NotX, ConstantInt::get(Ty, *C));
-  }
+  unsigned BitWidth = Ty->getScalarSizeInBits();
+  if (match(Op0, m_OneUse(m_AShr(m_Value(X),
+                                 m_SpecificIntAllowUndef(BitWidth - 1)))) &&
+      match(Op1, m_One()))
+    return new ZExtInst(Builder.CreateIsNotNeg(X, "isnotneg"), Ty);
 
   if (!match(Op1, m_APInt(C)))
     return nullptr;

diff  --git a/llvm/test/Transforms/InstCombine/add.ll b/llvm/test/Transforms/InstCombine/add.ll
index 58d97c971db7..486078cb9b05 100644
--- a/llvm/test/Transforms/InstCombine/add.ll
+++ b/llvm/test/Transforms/InstCombine/add.ll
@@ -1900,8 +1900,8 @@ define i8 @not_mul_use2(i8 %x) {
 
 define i8 @full_ashr_inc(i8 %x) {
 ; CHECK-LABEL: @full_ashr_inc(
-; CHECK-NEXT:    [[X_NOT:%.*]] = xor i8 [[X:%.*]], -1
-; CHECK-NEXT:    [[R:%.*]] = lshr i8 [[X_NOT]], 7
+; CHECK-NEXT:    [[ISNOTNEG:%.*]] = icmp sgt i8 [[X:%.*]], -1
+; CHECK-NEXT:    [[R:%.*]] = zext i1 [[ISNOTNEG]] to i8
 ; CHECK-NEXT:    ret i8 [[R]]
 ;
   %a = ashr i8 %x, 7
@@ -1911,8 +1911,8 @@ define i8 @full_ashr_inc(i8 %x) {
 
 define <2 x i6> @full_ashr_inc_vec(<2 x i6> %x) {
 ; CHECK-LABEL: @full_ashr_inc_vec(
-; CHECK-NEXT:    [[X_NOT:%.*]] = xor <2 x i6> [[X:%.*]], <i6 -1, i6 -1>
-; CHECK-NEXT:    [[R:%.*]] = lshr <2 x i6> [[X_NOT]], <i6 5, i6 5>
+; CHECK-NEXT:    [[ISNOTNEG:%.*]] = icmp sgt <2 x i6> [[X:%.*]], <i6 -1, i6 -1>
+; CHECK-NEXT:    [[R:%.*]] = zext <2 x i1> [[ISNOTNEG]] to <2 x i6>
 ; CHECK-NEXT:    ret <2 x i6> [[R]]
 ;
   %a = ashr <2 x i6> %x, <i6 5, i6 poison>

diff  --git a/llvm/test/Transforms/InstCombine/high-bit-signmask.ll b/llvm/test/Transforms/InstCombine/high-bit-signmask.ll
index a202c43fbb5c..86865556b6a5 100644
--- a/llvm/test/Transforms/InstCombine/high-bit-signmask.ll
+++ b/llvm/test/Transforms/InstCombine/high-bit-signmask.ll
@@ -116,8 +116,8 @@ define i64 @n9(i64 %x) {
 
 define i64 @n10(i64 %x) {
 ; CHECK-LABEL: @n10(
-; CHECK-NEXT:    [[X_NOT:%.*]] = xor i64 [[X:%.*]], -1
-; CHECK-NEXT:    [[R:%.*]] = lshr i64 [[X_NOT]], 63
+; CHECK-NEXT:    [[ISNOTNEG:%.*]] = icmp sgt i64 [[X:%.*]], -1
+; CHECK-NEXT:    [[R:%.*]] = zext i1 [[ISNOTNEG]] to i64
 ; CHECK-NEXT:    ret i64 [[R]]
 ;
   %t0 = lshr i64 %x, 63


        


More information about the llvm-commits mailing list