[llvm] faebb1b - Reapply [InstCombine] Support inverting lshr with non-negative operand

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 1 07:10:14 PST 2023


Author: Nikita Popov
Date: 2023-12-01T16:09:54+01:00
New Revision: faebb1b2e6891687e4f608b74205985ec78ade40

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

LOG: Reapply [InstCombine] Support inverting lshr with non-negative operand

My initial patch contained a typo, resulting in the wrong value
being checked for non-negativeness.

-----

If the lshr operand is non-negative, we can treat it the same
way as an ashr. Ideally we would represent this as "lshr nneg",
but for now just perform the necessary ValueTracking query.

Proof: https://alive2.llvm.org/ce/z/Ahg4ri

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
    llvm/test/Transforms/InstCombine/free-inversion.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 26fdef672506a68..0f033a9adad7027 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -2181,6 +2181,16 @@ Value *InstCombiner::getFreelyInvertedImpl(Value *V, bool WillInvertAllUses,
     return nullptr;
   }
 
+  // Treat lshr with non-negative operand as ashr.
+  if (match(V, m_LShr(m_Value(A), m_Value(B))) &&
+      isKnownNonNegative(A, SQ.getWithInstruction(cast<Instruction>(V)),
+                         Depth)) {
+    if (auto *AV = getFreelyInvertedImpl(A, A->hasOneUse(), Builder,
+                                         DoesConsume, Depth))
+      return Builder ? Builder->CreateAShr(AV, B) : NonNull;
+    return nullptr;
+  }
+
   Value *Cond;
   // LogicOps are special in that we canonicalize them at the cost of an
   // instruction.

diff  --git a/llvm/test/Transforms/InstCombine/free-inversion.ll b/llvm/test/Transforms/InstCombine/free-inversion.ll
index 93d293df6048e32..851f9823cc692b0 100644
--- a/llvm/test/Transforms/InstCombine/free-inversion.ll
+++ b/llvm/test/Transforms/InstCombine/free-inversion.ll
@@ -499,9 +499,7 @@ define i8 @lshr_nneg(i8 %x, i8 %y) {
 ; CHECK-LABEL: @lshr_nneg(
 ; CHECK-NEXT:    [[NEG:%.*]] = icmp slt i8 [[X:%.*]], 0
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[NEG]])
-; CHECK-NEXT:    [[X_NOT:%.*]] = xor i8 [[X]], -1
-; CHECK-NEXT:    [[SHR:%.*]] = lshr i8 [[X_NOT]], [[Y:%.*]]
-; CHECK-NEXT:    [[SHR_NOT:%.*]] = xor i8 [[SHR]], -1
+; CHECK-NEXT:    [[SHR_NOT:%.*]] = ashr i8 [[X]], [[Y:%.*]]
 ; CHECK-NEXT:    ret i8 [[SHR_NOT]]
 ;
   %neg = icmp slt i8 %x, 0


        


More information about the llvm-commits mailing list